Saving a sound bite as a ringtone

167 views Asked by At

I am trying to set a .wav file as a ringtone on Android devices. The code below is able to create directories, and the sound file, but seems to have issues actually setting the file as a ringtone, let alone the selected ringtone. After the method ends, I go to ringtones on the device, and the selected ringtone defaults to "None". Any idea what's going on here? I am using the WRITE_EXTERNAL_STORAGE permission in my manifest. Also, the format of the sound bite doesn't matter to me, I don't mind converting anything that needs converted.

Thanks!!

private String saveAs(String fileName) {
    int resSound = getContext().getResources().getIdentifier(fileName, "raw", getContext().getPackageName());

    // Resolve save path and ensure we can read and write to it
    String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/media/audio/ringtones/";
    File dir = new File(path);
    fileName += ".wav";

    if (!dir.exists()) {
        dir.mkdirs();
    }

    if(!dir.canRead() || !dir.canWrite()) {
        return "Unable to save ringtone.";
    }

    // Load the audio into a buffer
    byte[] buffer;
    InputStream fIn = this.context.getBaseContext().getResources().openRawResource(resSound);
    int size;

    try {
        size = fIn.available();
        buffer = new byte[size];
        fIn.read(buffer);
        fIn.close();
    }
    catch (IOException e) {
        return "Error opening sound file";
    }


    File file = new File(dir, fileName);
    FileOutputStream save;
    try {
        save = new FileOutputStream(file);
        save.write(buffer);
        save.flush();
        save.close();
    }
    catch (FileNotFoundException e) {
        return "Error loading sound file.";
    }
    catch (IOException e) {
        return "Unable to save ringtone.";
    }

    // Register the sound byte with the OS and set its properties
    this.context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + path + fileName)));

    ContentValues values = new ContentValues();
    values.put(MediaStore.MediaColumns.DATA, file.getAbsolutePath());
    values.put(MediaStore.MediaColumns.TITLE, getSoundTitle(fileName));
    values.put(MediaStore.MediaColumns.SIZE, size);
    values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/*");
    values.put(MediaStore.Audio.Media.ARTIST, "Sound Clip");
    values.put(MediaStore.Audio.Media.IS_RINGTONE, true);
    values.put(MediaStore.Audio.Media.IS_ALARM, false);
    values.put(MediaStore.Audio.Media.IS_MUSIC, false);

    //Insert it into the database
    Uri uri = this.context.getContentResolver().insert(MediaStore.Audio.Media.getContentUriForPath(file.getAbsolutePath()), values);
    RingtoneManager.setActualDefaultRingtoneUri(this.context, RingtoneManager.TYPE_RINGTONE, uri);

    return "Successfully set ringtone.";
}
1

There are 1 answers

0
Andrew On

For anyone else who runs into this, I figured it out. It's this line.

this.context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + path + fileName)));

If anyone happens to know why this is, I'd be very interested to know. Thanks!