通过内容提供者设置铃声/通知音(来自资产)

Set ringtone / notification tone via contentprovider (from assets)

我正在尝试通过我的资产文件夹中的内容提供商设置 android 默认铃声或通知音。 令人惊讶的是,它是这样工作的,但是这是合法的方式吗?

Uri audiouri = Uri.parse("content://"+BuildConfig.APPLICATION_ID+"/"+soundname+".mp3");
RingtoneManager.setActualDefaultRingtoneUri(a, TYPE_NOTIFICATION, audiouri );

遗憾的是,Android 设置中未显示声音名称。

奇怪的是,当我去 'Other sounds' 时,声音名称实际上显示了

我也试过这个:

Uri audiouri = Uri.parse("content://"+BuildConfig.APPLICATION_ID+"/"+soundname+".mp3");
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.MediaColumns.TITLE, soundname);
Uri ringtoneuri = a.getContentResolver().insert(audiouri, contentValues);
RingtoneManager.setActualDefaultRingtoneUri(a, TYPE_NOTIFICATION, ringtoneuri);

导致空音(未设置声音)

我尝试的第三个选项是:

Uri audiouri = MediaStore.Audio.Media.getContentUriForPath("content://"+BuildConfig.APPLICATION_ID+"/"+soundname+".mp3");
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.MediaColumns.DATA, "content://"+BuildConfig.APPLICATION_ID+"/"+soundname+".mp3");
contentValues.put(MediaStore.MediaColumns.TITLE, soundname);
Uri ringtoneuri = a.getContentResolver().insert(audiouri, contentValues);
RingtoneManager.setActualDefaultRingtoneUri(a, TYPE_NOTIFICATION, ringtoneuri);

现在声音名称显示正确,但实际上没有播放声音。 我在 logcat:

上出错

java.io.FileNotFoundException: Can't access /content:/com.mydomain.myapp/test.mp3

所以它似乎从 MediaColumns.DATA 中获取值,它不支持内容提供程序路径,但仅支持真实路径。对吗?

最后一个问题:如何在android设置中设置音调和名字?最好不要将文件复制到外部存储。

所以,不幸的是我没有找到如何直接将资产设置为铃声, 但这是一个很好的解决方法:

将资产复制到内部应用程序存储或缓存目录时(不需要权限!)我能够在没有WRITE_EXTERNAL_STORAGE权限的情况下设置铃声。

static void settone(int type, Sound sound, Activity a)
{
    lastsound = sound; //global remember sound and type (alarm/ringtone/notification) 
    lasttype = type;   // if we have to get permissions first, then call this from onActivityResult
    if (canwritesystem(a))
    {
        RingtoneManager.setActualDefaultRingtoneUri(a, type, getringtoneuri(sound, a));
        Toast.makeText(a, a.getString(R.string.settonesuccess), Toast.LENGTH_LONG).show();
    }
    else a.startActivityForResult(new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS).setData(Uri.parse("package:" + a.getPackageName())),CONTEXT_SET_TONE);
}

static Uri getringtoneuri(Sound sound, Activity a)
{
    File tonefile = new File(sound.getpath); // path could be like: /Android/data/com.company.yourapp
    ContentValues contentValues = new ContentValues();
    contentValues.put(MediaStore.MediaColumns.DATA, tonefile.getAbsolutePath());
    contentValues.put(MediaStore.MediaColumns.TITLE, sound.getDisplayName());
    contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "audio/mp3");
    contentValues.put(MediaStore.MediaColumns.SIZE, tonefile.length());
    contentValues.put(MediaStore.Audio.Media.IS_RINGTONE, true);
    contentValues.put(MediaStore.Audio.Media.IS_NOTIFICATION, true);
    contentValues.put(MediaStore.Audio.Media.IS_ALARM, true);
    contentValues.put(MediaStore.Audio.Media.IS_MUSIC, false);
    Uri generalaudiouri = MediaStore.Audio.Media.INTERNAL_CONTENT_URI;
    a.getContentResolver().delete(generalaudiouri, MediaStore.MediaColumns.DATA + "='" + tonefile.getAbsolutePath() + "'", null);
    return a.getContentResolver().insert(generalaudiouri, contentValues);
}