系统设置铃声的界面,仍然是 frameworks/base/packages/SoundPicker/src/com/android/soundpicker/RingtonePickerActivity.java ,在 RingtonePickerActivity.BadgedRingtoneAdapter 中 bindView 进行加载显示。
设置默认铃声等使用的系统 frameworks/base/media/java/android/media/RingtoneManager.java 中 setActualDefaultRingtoneUri 接口。
RingtonePickerActivity 中设置铃声URI时。存在从存储中删除的文件,uri依然存在的情况,这是因为删除文件不会触发media的数据库重新加载,所以uri依然可以使用。重启机器后这个URI就会被判定无效。
可以在 RingtoneManager.java 中对应的 setActualDefaultRingtoneUri /getActualDefaultRingtoneUri 接口中进行处理,参照 openDefaultRingtoneUri 方法中,先行判断 uri 指向的文件是否存在。不存在重新给一个默认铃声
public static @Nullable AssetFileDescriptor openDefaultRingtoneUri(
@NonNull Context context, @NonNull Uri uri) throws FileNotFoundException {
// Try cached ringtone first since the actual provider may not be
// encryption aware, or it may be stored on CE media storage
final int type = getDefaultType(uri);
final Uri cacheUri = getCacheForType(type, context.getUserId());
final Uri actualUri = getActualDefaultRingtoneUri(context, type);
final ContentResolver resolver = context.getContentResolver();
AssetFileDescriptor afd = null;
if (cacheUri != null) {
afd = resolver.openAssetFileDescriptor(cacheUri, "r");
// 判断文件是否存在,为NULL表示文件不存在
if (afd != null) {
return afd;
}
}
if (actualUri != null) {
afd = resolver.openAssetFileDescriptor(actualUri, "r");
}
return afd;
}
... ...
public static void setActualDefaultRingtoneUri(Context context, int type, Uri ringtoneUri) {
AssetFileDescriptor afd = null;
if (cacheUri != null) {
afd = resolver.openAssetFileDescriptor(cacheUri, "r");
// 判断文件是否存在,为NULL表示文件不存在
if (afd == null) {
// 当设置 uri 没有对应文件时,拿系统有的文件设置为默认铃声
String filename = getDefaultRingtoneFilename(type);
Uri baseUri = MediaStore.Audio.Media.INTERNAL_CONTENT_URI;
try (Cursor cursor = context.getContentResolver().query(baseUri,
new String[] { MediaColumns._ID },
MediaColumns.DISPLAY_NAME + "=?",
new String[] { filename }, null)) {
if (cursor.moveToFirst()) {
ringtoneUri = context.getContentResolver().canonicalizeOrElse(
ContentUris.withAppendedId(baseUri, cursor.getLong(0)));
}
} catch (Exception e){
e.printStackTrace();
}
}
}
String setting = getSettingForType(type);
if (setting == null) return;
... ...
}