Question

I'm trying to find a way to set a new default ringtone by code from my Android activity.

I have already downloaded the ringtone into a bytearray.

Was it helpful?

Solution

Finally, I managed to set the default ringtone to one that i downloaded. The download code is not included below, only what was needed to set it as default ringtone.

File k = new File(path, "mysong.mp3"); // path is a file to /sdcard/media/ringtone

ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DATA, k.getAbsolutePath());
values.put(MediaStore.MediaColumns.TITLE, "My Song title");
values.put(MediaStore.MediaColumns.SIZE, 215454);
values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/mp3");
values.put(MediaStore.Audio.Media.ARTIST, "Madonna");
values.put(MediaStore.Audio.Media.DURATION, 230);
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());
Uri newUri = this.getContentResolver().insert(uri, values);

RingtoneManager.setActualDefaultRingtoneUri(
  myActivity,
  RingtoneManager.TYPE_RINGTONE,
  newUri
);  

Anyway, I do not totally understand what this code is doing.

The Ringtone manager needs a uri to the file that is to be set as new ringtone. But this uri can not be directly to the sdcard like "/sdcard/media/ringtones/mysong.mp3". That does not work!

What you need is the external file uri of the file which could be something like "/external/audio/media/46"

The 46 is the id of the column in the MediaStore database, so thats why you need to add the sdcard file into the database first.

Anyway, how does mediastore maintain its ids? This number can get really high, as you do this operation many times.

Do i need to delete this row my self? Problem is that some times i dont even controll the deleting of the file since it can be deleted directly from the sdcard with a filebrowser.

OTHER TIPS

You can use the built-in RingtonePreference class. AndroidGuys has a nice tutorial on this here.

public void setRingtone() {
  String ringtoneuri = Environment.getExternalStorageDirectory().getAbsolutePath() + "/media/ringtone";
  File file1 = new File(ringtoneuri);
  file1.mkdirs();
  File newSoundFile = new File(ringtoneuri, "myringtone.mp3");


  Uri mUri = Uri.parse("android.resource://globalapps.funnyringtones/raw/sound_two.mp3");


  ContentResolver mCr = this.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();
  } 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/mp3");
  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());
  Uri newUri = mCr.insert(uri, values);
  try {
   Uri rUri = RingtoneManager.getValidRingtoneUri(this);
   if (rUri != null)
    ringtoneManager.setStopPreviousRingtone(true);
   RingtoneManager.setActualDefaultRingtoneUri(getApplicationContext(), RingtoneManager.TYPE_RINGTONE, newUri);
   Toast.makeText(this, "New Rigntone set", Toast.LENGTH_SHORT).show();
  } catch (Throwable t) {
   Log.e("sanjay in catch", "catch exception"+e.getMessage());
  }

 }

Answer By Vidar is too long and it adds duplicate entries every time you want to set a song as ringtone . Instead you should try this

Uri newUri=Uri.parse("content://media/external/audio/media/"+ID);  
try {
      RingtoneManager.setActualDefaultRingtoneUri(context, RingtoneManager.TYPE_RINGTONE, newUri);
    }
catch (Throwable t) {


                  }

I cannot comment the solution because I don't have enough reputation on stack overflow ... I want just add a way to add the audio file into media database without accessing directly to the database and hence avoiding to get duplicates. The solution is based on MediaScannerConnection, this is the code I used:

    String[] files = { audioFullPath };
    MediaScannerConnection.scanFile(
        getApplicationContext(),
        files,
        null,
        new OnScanCompletedListener() {
            @Override
            public void onScanCompleted(String path, Uri uri) {
                Log.v("myapp", "file " + path + " was scanned seccessfully: " + uri);
            }
        }
    );

I found this code from the Media application from Android.

Settings.System.putString(resolver, 
Settings.System.RINGTONE, ringUri.toString());

this works form my.

This is the code i used! i hope it helps..
This is also the link.

 String exStoragePath =    Environment.getExternalStorageDirectory().getAbsolutePath();
String path=(exStoragePath +"/media/alarms/"); 

saveas(RingtoneManager.TYPE_RINGTONE); 

sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,       Uri.parse("file://"+path+filename+".mp3"
  + Environment.getExternalStorageDirectory()))); 


 File k = new File(path, filename);

ContentValues values = new ContentValues(4);   
long current = System.currentTimeMillis();
values.put(MediaStore.MediaColumns.DATA, path + filename  );
values.put(MediaStore.MediaColumns.TITLE,  filename ); 
values.put(MediaStore.Audio.Media.DATE_ADDED, (int) (current / 1000));
values.put(MediaStore.Audio.Media.MIME_TYPE, "audio/3gpp");

//new
 values.put(MediaStore.Audio.Media.ARTIST, "cssounds ");
values.put(MediaStore.Audio.Media.IS_RINGTONE, true);
values.put(MediaStore.Audio.Media.IS_NOTIFICATION, false);
values.put(MediaStore.Audio.Media.IS_ALARM, true);
values.put(MediaStore.Audio.Media.IS_MUSIC, false);  

   // Insert it into the database
this.getContentResolver()
   .insert(MediaStore.Audio.Media.getContentUriForPath(k
.getAbsolutePath()), values);

HAPPY CODING!

provide intent for ringtone selection.

final Uri currentTone= RingtoneManager.getActualDefaultRingtoneUri(MainActivity.this, RingtoneManager.TYPE_ALARM);
                Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
                intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_RINGTONE);
                intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, "Select Tone");
                intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, currentTone);
                intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, false);
                intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, true);
                startActivityForResult(intent, 999);

then catch the result of selection in onActivityResult.

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(requestCode == 999 && resultCode == RESULT_OK){
            Uri uri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
            txtView.setText("From :" + uri.getPath());
            //Set selected ringtone here.
            RingtoneManager.setActualDefaultRingtoneUri(
                    this,
                    RingtoneManager.TYPE_RINGTONE,
                    uri
            );
        }
    }

I have try these code its help

  private void setRingtone(Context context, String path) {
    if (path == null) {
        return;
    }
    File file = new File(path);
    ContentValues contentValues = new ContentValues();
    contentValues.put(MediaStore.MediaColumns.DATA, file.getAbsolutePath());
    String filterName = path.substring(path.lastIndexOf("/") + 1);
    contentValues.put(MediaStore.MediaColumns.TITLE, filterName);
    contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "audio/mp3");
    contentValues.put(MediaStore.MediaColumns.SIZE, file.length());
    contentValues.put(MediaStore.Audio.Media.IS_RINGTONE, true);
    Uri uri = MediaStore.Audio.Media.getContentUriForPath(path);
    Cursor cursor = context.getContentResolver().query(uri, null, MediaStore.MediaColumns.DATA + "=?", new String[]{path}, null);
    if (cursor != null && cursor.moveToFirst() && cursor.getCount() > 0) {
        String id = cursor.getString(0);
        contentValues.put(MediaStore.Audio.Media.IS_RINGTONE, true);
        context.getContentResolver().update(uri, contentValues, MediaStore.MediaColumns.DATA + "=?", new String[]{path});
        Uri newuri = ContentUris.withAppendedId(uri, Long.valueOf(id));
        try {
            RingtoneManager.setActualDefaultRingtoneUri(context, RingtoneManager.TYPE_RINGTONE, newuri);
            Toast.makeText(context, "Set as Ringtone Successfully.", Toast.LENGTH_SHORT).show();
        } catch (Throwable t) {
            t.printStackTrace();
        }
        cursor.close();
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top