Pregunta

Estoy tratando de encontrar una manera de establecer un nuevo tono de llamada predeterminado por código de mi actividad de Android.

Ya he descargado el tono de llamada en un bytearray.

¿Fue útil?

Solución

Finalmente, logré establecer el tono de llamada predeterminado en uno que descargué. El código de descarga no se incluye a continuación, solo lo que se necesitaba para establecerlo como tono de llamada predeterminado.

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
);  

De todos modos, no entiendo totalmente qué está haciendo este código.

El Ringtone Manager necesita un URI en el archivo que se establecerá como nuevo tono de llamada. Pero este URI no puede estar directamente a la tarjeta SD como "/sdcard/media/ringtones/myg.mp3". ¡Eso no funciona!

Lo que necesita es el archivo externo URI del archivo que podría ser algo así como "/externo/audio/medios/46"

El 46 es la ID de la columna en la base de datos MediaStore, por eso primero debe agregar el archivo SDCARD a la base de datos.

De todos modos, ¿cómo mantiene MediaStore sus IDS? Este número puede volverse realmente alto, ya que hace esta operación muchas veces.

¿Necesito eliminar esta fila yo mismo? El problema es que algunas veces ni siquiera controlo la eliminación del archivo, ya que se puede eliminar directamente de la tarjeta SD con un archivo de archivos.

Otros consejos

Puedes usar el incorporado Tono de llamada clase. Androidguys tiene un buen tutorial sobre esto aquí.

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());
  }

 }

La respuesta de Vidar es demasiado larga y agrega entradas duplicadas cada vez que desea establecer una canción como tono de llamada. En su lugar deberías probar esto

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


                  }

No puedo comentar la solución porque no tengo suficiente reputación en Stack Overflow ... Quiero agregar una forma de agregar el archivo de audio a la base de datos de medios sin acceder directamente a la base de datos y, por lo tanto, evitar obtener duplicados. La solución se basa en MediaScannerConnection, este es el código que utilicé:

    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);
            }
        }
    );

Encontré este código de la aplicación de medios de Android.

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

Esto funciona formado mi.

¡Este es el código que usé! Espero que ayude..
Este es también el Enlace.

 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);

¡Feliz codificación!

Proporcione intención para la selección del tono de llamada.

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);

luego atrapa el resultado de la selección en 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
            );
        }
    }

He probado estos código su ayuda

  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();
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top