When I run my app on Android Pie then its work fine, I mean my code for set ringtone and alarm,notification work perfectly but when I run this app on Android 7 (nougat), then alarm and notification is set but ringtone is not. When I click set ringtone then toast message display that ringtone set successfully but when I check it on my phone it still using previous ringtone.
Code for set ringtone:
private void setRingtone() {
AssetFileDescriptor openAssetFileDescriptor;
((AudioManager) getSystemService(AUDIO_SERVICE)).setRingerMode(2);
File file = new File(Environment.getExternalStorageDirectory() + "", this.fNmae);
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
Uri parse = Uri.parse(this.fPAth);
ContentResolver contentResolver = getContentResolver();
try {
openAssetFileDescriptor = contentResolver.openAssetFileDescriptor(parse, "r");
} catch (FileNotFoundException e2) {
openAssetFileDescriptor = null;
}
try {
byte[] bArr = new byte[1024];
FileInputStream createInputStream = openAssetFileDescriptor.createInputStream();
FileOutputStream fileOutputStream = new FileOutputStream(file);
for (int read = createInputStream.read(bArr); read != -1; read = createInputStream.read(bArr)) {
fileOutputStream.write(bArr, 0, read);
}
fileOutputStream.close();
} catch (IOException e3) {
e3.printStackTrace();
}
ContentValues contentValues = new ContentValues();
contentValues.put("_data", file.getAbsolutePath());
contentValues.put("title", "nkDroid ringtone");
contentValues.put("mime_type", "audio/mp3");
contentValues.put("_size", Long.valueOf(file.length()));
contentValues.put("artist", Integer.valueOf(R.string.app_name));
contentValues.put("is_ringtone", Boolean.valueOf(true));
contentValues.put("is_notification", Boolean.valueOf(false));
contentValues.put("is_alarm", Boolean.valueOf(false));
contentValues.put("is_music", Boolean.valueOf(false));
try {
RingtoneManager.setActualDefaultRingtoneUri(MainActivity.this, RingtoneManager.TYPE_RINGTONE, parse);
Toast.makeText(this, new StringBuilder().append("Ringtone set successfully"), Toast.LENGTH_LONG).show();
} catch (Throwable th) {
Toast.makeText(this, new StringBuilder().append("Ringtone feature is not working"), Toast.LENGTH_LONG).show();
}
}
Code for alarm:
private void setAlarm() {
AssetFileDescriptor openAssetFileDescriptor;
((AudioManager) getSystemService(AUDIO_SERVICE)).setRingerMode(2);
File file = new File(Environment.getExternalStorageDirectory() + "", this.fNmae);
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
Uri parse = Uri.parse(this.fPAth);
ContentResolver contentResolver = getContentResolver();
try {
openAssetFileDescriptor = contentResolver.openAssetFileDescriptor(parse, "r");
} catch (FileNotFoundException e2) {
openAssetFileDescriptor = null;
}
try {
byte[] bArr = new byte[1024];
FileInputStream createInputStream = openAssetFileDescriptor.createInputStream();
FileOutputStream fileOutputStream = new FileOutputStream(file);
for (int read = createInputStream.read(bArr); read != -1; read = createInputStream.read(bArr)) {
fileOutputStream.write(bArr, 0, read);
}
fileOutputStream.close();
} catch (IOException e3) {
e3.printStackTrace();
}
ContentValues contentValues = new ContentValues();
contentValues.put("_data", file.getAbsolutePath());
contentValues.put("title", "nkDroid ringtone");
contentValues.put("mime_type", "audio/mp3");
contentValues.put("_size", Long.valueOf(file.length()));
contentValues.put("artist", Integer.valueOf(R.string.app_name));
contentValues.put("is_ringtone", Boolean.valueOf(false));
contentValues.put("is_notification", Boolean.valueOf(false));
contentValues.put("is_alarm", Boolean.valueOf(true));
contentValues.put("is_music", Boolean.valueOf(false));
try {
Toast.makeText(this, new StringBuilder().append("Alarm set successfully"), Toast.LENGTH_LONG).show();
// RingtoneManager.setActualDefaultRingtoneUri(getBaseContext(), RingtoneManager.TYPE_RINGTONE, contentResolver.insert(MediaStore.Audio.Media.getContentUriForPath(file.getAbsolutePath()), contentValues));
RingtoneManager.setActualDefaultRingtoneUri(getBaseContext(), RingtoneManager.TYPE_ALARM, parse);
Settings.System.putString(contentResolver, Settings.System.ALARM_ALERT,
parse.toString());
} catch (Throwable th) {
Toast.makeText(this, new StringBuilder().append("Alarm feature is not working"), Toast.LENGTH_LONG).show();
}
}
Related
I am trying to set ringtone / notification tone in Android 11 since last 4-5 days, but doesn't able to complete it, It's not like i haven't tried anything new or something that, I have code which is already working fine in Android 10 and below version but when i set target to Android 30, It doesn't work.
public boolean saveAsRingtone() {
if (mInterstitialAd != null) {
mInterstitialAd.show(this);
}
InputStream fIn = getBaseContext().getResources().openRawResource(R.raw.file);
try {
byte[] buffer = new byte[fIn.available()];
fIn.read(buffer);
fIn.close();
String path = Environment.getExternalStorageDirectory() + "/Sounds/Media/";
String filename = "Ring.mp3";
if (!new File(path).exists()) {
new File(path).mkdirs();
}
try {
FileOutputStream save = new FileOutputStream(path + filename);
save.write(buffer);
save.flush();
save.close();
sendBroadcast(new Intent("android.intent.action.MEDIA_SCANNER_SCAN_FILE", Uri.parse("file://" + path + filename)));
File k = new File(path, filename);
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DATA, k.getAbsolutePath());
values.put(MediaStore.MediaColumns.TITLE, "RingTone");
values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/mp3");
values.put(MediaStore.MediaColumns.SIZE, 215454);
values.put(MediaStore.MediaColumns.ARTIST, "Test");
if (RingtoneManager.TYPE_RINGTONE == RingtoneManager.TYPE_RINGTONE) {
values.put(MediaStore.Audio.Media.IS_RINGTONE, true);
} else if (RingtoneManager.TYPE_NOTIFICATION == RingtoneManager.TYPE_NOTIFICATION) {
values.put(MediaStore.Audio.Media.IS_NOTIFICATION, false);
}
values.put(MediaStore.Audio.Media.IS_ALARM, Boolean.valueOf(false));
values.put(MediaStore.Audio.Media.IS_MUSIC, Boolean.valueOf(false));
Uri uri = MediaStore.Audio.Media.getContentUriForPath(k.getAbsolutePath());
getContentResolver().delete(uri, MediaStore.MediaColumns.DATA + "=\"" + k.getAbsolutePath() + "\"", null);
RingtoneManager.setActualDefaultRingtoneUri(this, RingtoneManager.TYPE_RINGTONE, uri);
Toast.makeText(getApplicationContext(), "Done", Toast.LENGTH_SHORT).show();
return true;
} catch (FileNotFoundException e) {
e.printStackTrace();
return false;
} catch (IOException e2) {
e2.printStackTrace();
return false;
}
} catch (IOException e3) {
e3.printStackTrace();
return false;
}
}
I already know about scoped storage and other permission related things which i have already declared in manifest file and so on.
I am using the following code, but it doesn't seem to change the ringtone. What am I doing wrong, or is there an easier way to set an mp3 to ringtone? I have a uri that parses the location, and I call the following function. I know the uri is correct because it functions correctly with a file share method I have.
private void setRingtone(Uri uri) {
AssetFileDescriptor openAssetFileDescriptor;
((AudioManager) getActivity().getSystemService(AUDIO_SERVICE)).setRingerMode(2);
File file = new File(Environment.getExternalStorageDirectory() + "/appkeeda", mp3s[position]);
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
ContentResolver contentResolver = getActivity().getContentResolver();
try {
openAssetFileDescriptor = contentResolver.openAssetFileDescriptor(uri, "r");
} catch (FileNotFoundException e2) {
openAssetFileDescriptor = null;
}
try {
byte[] bArr = new byte[1024];
FileInputStream createInputStream = openAssetFileDescriptor.createInputStream();
FileOutputStream fileOutputStream = new FileOutputStream(file);
for (int read = createInputStream.read(bArr); read != -1; read = createInputStream.read(bArr)) {
fileOutputStream.write(bArr, 0, read);
}
fileOutputStream.close();
} catch (IOException e3) {
e3.printStackTrace();
}
ContentValues contentValues = new ContentValues();
contentValues.put("_data", file.getAbsolutePath());
contentValues.put("title", "nkDroid ringtone");
contentValues.put("mime_type", "audio/mp3");
contentValues.put("_size", Long.valueOf(file.length()));
contentValues.put("artist", Integer.valueOf(R.string.app_name));
contentValues.put("is_ringtone", Boolean.valueOf(true));
contentValues.put("is_notification", Boolean.valueOf(false));
contentValues.put("is_alarm", Boolean.valueOf(false));
contentValues.put("is_music", Boolean.valueOf(false));
try {
//Toast.makeText(this, new StringBuilder().append("Ringtone set successfully"), Toast.LENGTH_LONG).show();
RingtoneManager.setActualDefaultRingtoneUri(getActivity().getBaseContext(), 1, contentResolver.insert(MediaStore.Audio.Media.getContentUriForPath(file.getAbsolutePath()), contentValues));
} catch (Throwable th) {
//Toast.makeText(this, new StringBuilder().append("Ringtone feature is not working"), Toast.LENGTH_LONG).show();
}
}
Solution: This tutorial worked for me: http://blog.nkdroidsolutions.com/set-default-ringtone-raw-folder-programmatically-android/
Below I have the coding for hiow to set audio as your ringtone. This works fine however I wanna know how could I alter this such that it well save just the audio so that it can be played with my other songs
public boolean save1(int type) {
byte[] buffer = null;
InputStream fIn = getBaseContext().getResources().openRawResource(
R.raw.song);
int size = 0;
try {
size = fIn.available();
buffer = new byte[size];
fIn.read(buffer);
fIn.close();
} catch (IOException e) {
return false;
}
String path = Environment.getExternalStorageDirectory().getPath()
+ "/media/audio/";
String filename = "New song";
FileOutputStream save;
try {
save = new FileOutputStream(path + filename);
save.write(buffer);
save.flush();
save.close();
} catch (FileNotFoundException e) {
return false;
} catch (IOException e) {
return false;
}
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
Uri.parse("file://" + path + filename)));
File k = new File(path, filename);
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DATA, k.getAbsolutePath());
values.put(MediaStore.MediaColumns.TITLE, filename);
values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/ogg");
if (RingtoneManager.TYPE_RINGTONE == type) {
values.put(MediaStore.Audio.Media.IS_RINGTONE, true);
} else if (RingtoneManager.TYPE_NOTIFICATION == type) {
values.put(MediaStore.Audio.Media.IS_NOTIFICATION, true);
} else if (RingtoneManager.TYPE_ALARM == type) {
values.put(MediaStore.Audio.Media.IS_ALARM, true);
}
Uri uri = MediaStore.Audio.Media.getContentUriForPath(k
.getAbsolutePath());
Uri newUri = MainActivity.this.getContentResolver().insert(uri, values);
RingtoneManager.setActualDefaultRingtoneUri(MainActivity.this, type,
newUri);
this.getContentResolver()
.insert(MediaStore.Audio.Media.getContentUriForPath(k
.getAbsolutePath()), values);
return true;
}
To move raw folder file to sdcard or phone storage below code will work:
private void CopyRAWtoPhone(int id, String path) throws IOException {
InputStream in = getResources().openRawResource(id);
FileOutputStream out = new FileOutputStream(path);
byte[] buff = new byte[1024];
int read = 0;
try {
while ((read = in.read(buff)) > 0) {
out.write(buff, 0, read);
}
} finally {
in.close();
out.close();
}
}
where first Variable id will be your raw file id and String path will be your phone storage path.
i need to add an alarm with a preset ringtone and at max volume
but i don't understand how i can pass this info to AlarmClock....
i have the ringtone in my res/raw (inside apk) and i use this code:
Intent i = new Intent(AlarmClock.ACTION_SET_ALARM);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.putExtra(AlarmClock.EXTRA_HOUR, oratimer);
i.putExtra(AlarmClock.EXTRA_MINUTES, minutitimer);
i.putExtra(AlarmClock.EXTRA_RINGTONE, saveSong(context, R.raw.song).toString());
i.putExtra(AlarmClock.EXTRA_SKIP_UI, true);
context.startActivity(i);
this is the saveSong function:
public Uri saveSong(Context context, int song) {
byte[] buffer = null;
InputStream fIn = context.getResources().openRawResource(song);
int size = 0;
try {
size = fIn.available();
buffer = new byte[size];
fIn.read(buffer);
fIn.close();
} catch (IOException e) {
// TODO Auto-generated catch block
return null;
}
String path = Environment.getExternalStorageDirectory()+"/Ringtones/";
String filename = "song" + ".mp3";
boolean exists = (new File(path)).exists();
if (!exists) {
new File(path).mkdirs();
}
exists = (new File(path+filename)).exists();
if (!exists) {
FileOutputStream save;
try {
save = new FileOutputStream(path + filename);
save.write(buffer);
save.flush();
save.close();
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.fromFile(new File(path + filename))));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
return null;
} catch (IOException e) {
// TODO Auto-generated catch block
return null;
}
}
return Uri.fromFile(new File(path+filename));
}
but the alarm is made with the default ringtone at the default volume (like 70%?)
any hint for solve this?
tnx
I Think this would work for you
mp = new MediaPlayer();
mp.setAudioStreamType(AudioManager.STREAM_ALARM);
This has been changed from the original post.
Basically what is happening is I have gotten this to display the ringtone in the ringtone list on the phone. It also selects it. In this code it plays the ringtone after it has been selected (I have taken it out to reduce the size). It seems to be playing the phones default ringtone. Any ideas why? Thanks
private void ringtone(int p){
File newSoundFile = new File("/sdcard/media/ringtone", "raven.wav");
Uri mUri = Uri.parse("android.resource://com.fs.hh/"+R.raw.raven);
ContentResolver mCr = getContentResolver();
AssetFileDescriptor soundFile;
try {
soundFile= mCr.openAssetFileDescriptor(mUri, "r");
} catch (FileNotFoundException e) {
soundFile=null;
}
try {
byte[] readData = new byte[1024];
FileInputStream fis = soundFile.createInputStream();
FileOutputStream fos = new FileOutputStream(newSoundFile);
int i = fis.read(readData);
while (i != -1) {
fos.write(readData, 0, i);
i = fis.read(readData);
}
fos.close();
soundFile.close();
} catch (IOException io) {
}
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DATA, newSoundFile.getAbsolutePath());
values.put(MediaStore.MediaColumns.TITLE, "my ringtone");
values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/wav");
values.put(MediaStore.MediaColumns.SIZE, newSoundFile.length());
values.put(MediaStore.Audio.Media.ARTIST, R.string.app_name);
values.put(MediaStore.Audio.Media.IS_RINGTONE, true);
values.put(MediaStore.Audio.Media.IS_NOTIFICATION, true);
values.put(MediaStore.Audio.Media.IS_ALARM, true);
values.put(MediaStore.Audio.Media.IS_MUSIC, false);
Uri uri = MediaStore.Audio.Media.getContentUriForPath(newSoundFile.getAbsolutePath());
mCr.delete(uri, MediaStore.MediaColumns.DATA + "=\"" + newSoundFile.getAbsolutePath() + "\"", null);
Uri newUri = mCr.insert(uri, values);
RingtoneManager.setActualDefaultRingtoneUri(Soundboard.this, RingtoneManager.TYPE_RINGTONE, newUri);
}
I have also tried adding a / after ringtone and making it get the byte size. Neither have worked.
I have also tried this piece of code instead and it causes the same problem. It shows up selected in the notification section, but the sound being played is not the correct sound. It sounds like a default ringer.
private boolean setRingtone(int p){
int ressound = whichSound(p); //The R.raw.sound
String fileTitle = fileTitle(p); // sound
String soundTitle = soundTitle(p); // Sound
byte[] buffer=null;
InputStream fIn = getBaseContext().getResources().openRawResource(ressound);
int size=0;
try {
size = fIn.available();
buffer = new byte[size];
fIn.read(buffer);
fIn.close();
} catch (IOException e) {
// TODO Auto-generated catch block
return false;
}
String path="/sdcard/media/notification";
String filename=fileTitle+".wav";
boolean exists = (new File(path)).exists();
if (!exists){new File(path).mkdirs();}
FileOutputStream save;
try {
save = new FileOutputStream(path+filename);
save.write(buffer);
save.flush();
save.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
return false;
} catch (IOException e) {
// TODO Auto-generated catch block
return false;
}
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://"+path+filename)));
File k = new File(path, filename);
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DATA, k.getAbsolutePath());
values.put(MediaStore.MediaColumns.TITLE, soundTitle);
values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/wav");
values.put(MediaStore.Audio.Media.ARTIST, "HH");
values.put(MediaStore.Audio.Media.IS_RINGTONE, false);
values.put(MediaStore.Audio.Media.IS_NOTIFICATION, true);
values.put(MediaStore.Audio.Media.IS_ALARM, false);
values.put(MediaStore.Audio.Media.IS_MUSIC, false);
//Insert it into the database
Uri newUri= this.getContentResolver().insert(MediaStore.Audio.Media.getContentUriForPath(k.getAbsolutePath()), values);
RingtoneManager.setActualDefaultRingtoneUri(
this,
RingtoneManager.TYPE_NOTIFICATION,
newUri
);
return false;
}
Here is what finally fixed it.
private boolean setRingtone(int p){
int ressound = whichSound(p);
String fileTitle = fileTitle(p);
String soundTitle = soundTitle(p);
byte[] buffer=null;
InputStream fIn = getBaseContext().getResources().openRawResource(ressound);
int size=0;
try {
size = fIn.available();
buffer = new byte[size];
fIn.read(buffer);
fIn.close();
} catch (IOException e) {
// TODO Auto-generated catch block
return false;
}
String path=Environment.getExternalStorageDirectory().getPath()+"/media/ringtone/";
String filename=fileTitle+".wav";
boolean exists = (new File(path)).exists();
if (!exists){new File(path).mkdirs();}
FileOutputStream save;
try {
save = new FileOutputStream(path+filename);
save.write(buffer);
save.flush();
save.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
return false;
} catch (IOException e) {
// TODO Auto-generated catch block
return false;
}
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://"+path+filename)));
File k = new File(path, filename);
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DATA, k.getAbsolutePath());
values.put(MediaStore.MediaColumns.TITLE, soundTitle);
values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/wav");
values.put(MediaStore.Audio.Media.ARTIST, "");
values.put(MediaStore.Audio.Media.IS_RINGTONE, true);
values.put(MediaStore.Audio.Media.IS_NOTIFICATION, false);
values.put(MediaStore.Audio.Media.IS_ALARM, false);
values.put(MediaStore.Audio.Media.IS_MUSIC, false);
//Insert it into the database
Uri uri = MediaStore.Audio.Media.getContentUriForPath(k.getAbsolutePath());
getContentResolver().delete(uri, MediaStore.MediaColumns.DATA + "=\"" + k.getAbsolutePath() + "\"", null);
Uri newUri = getContentResolver().insert(uri, values);
RingtoneManager.setActualDefaultRingtoneUri(this, RingtoneManager.TYPE_RINGTONE, newUri);
return false;
}
In the path String by adding Environment.getExternatStorageDirectory().getPath() instead of just the sdcard it was actually able to play the sound and work properly.
Uri mUri = Uri.parse("android.resource://com.packange.name/"+R.raw.raven);
"com.packange.name" should be the name of your package, I assume you havenĀ“t called it like that. Hardcode your package name, or call getPackageName() from a proper context.
Update: You can get an uri out of your newSoundFile object, just do Uri.fromFile( newSoundFile ).