Android P将SD卡的音频设置为手机铃声后删除,手机铃声没有恢复到默认的问题

1. Android9.0,将存储卡中MP3设置为铃声,删除该MP3后,settings中的铃声没有变化,来电铃声也没有变化。

    原因:android9.0的新特性

    解决办法:如果需要在删除MP3后将来电铃声恢复为默认铃声,可以这么做:

/frameworks/base / media/java/android/media/MediaScanner.java

先在开机时候,将默认的系统铃声保存:

private void setRingtoneIfNotSet(String settingName, Uri uri, long rowId) {
    if (wasRingtoneAlreadySet(settingName)) {
        return;
    }

    ContentResolver cr = mContext.getContentResolver();
    String existingSettingValue = Settings.System.getString(cr, settingName);
    if (TextUtils.isEmpty(existingSettingValue)) {
        final Uri settingUri = Settings.System.getUriFor(settingName);
        final Uri ringtoneUri = ContentUris.withAppendedId(uri, rowId);
        RingtoneManager.setActualDefaultRingtoneUri(mContext,
                RingtoneManager.getDefaultType(settingUri), ringtoneUri);
        String defaultName = null;
        switch (settingName) {
            case Settings.System.NOTIFICATION_SOUND:
                defaultName = RingtoneManager.KEY_DEFAULT_NOTIFICATION;
                break;
            case Settings.System.RINGTONE:
                defaultName = RingtoneManager.KEY_DEFAULT_RINGTONE;
                break;
            case Settings.System.ALARM_ALERT:
                defaultName = RingtoneManager.KEY_DEFAULT_ALARM;
                break;
        }
        if (defaultName != null) {
            Settings.System.putString(mContext.getContentResolver(), defaultName,
                    ContentUris.withAppendedId(uri, rowId).toString());
        }
    }
    Settings.System.putInt(cr, settingSetIndicatorName(settingName), 1);
}

当后续铃声不存在时候,则直接判断查找铃声:

frameworks/base / media/java/android/media/RingtoneManager.java

/**
 * start to check ringtone exist
 *
 * @hide
 */
private static boolean isRingtoneExist(Context context, Uri uri) {
    if (uri == null) {
        Log.e(TAG, "Check ringtone exist with null uri!");
        return false;
    }
    boolean exist = false;
    try {
        AssetFileDescriptor fd = context.getContentResolver().openAssetFileDescriptor(uri, "r");
        if (fd == null) {
            exist = false;
        } else {
            fd.close();
            exist = true;
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
        exist = false;
    } catch (IOException e) {
        e.printStackTrace();
        exist = true;
    }
    //Log.d(TAG, uri + " is exist " + exist);
    return exist;
}

/**
 * check ringtone exist on Db
 *
 * @hide
 */
private static boolean isRingtoneExistByQueryDb(Context context, Uri uri){
    if (uri == null) {
        Log.e(TAG, "isRingtoneExistByQueryDb --> Check ringtone exist with null uri!");
        return false;
    }
    boolean exist = false;
    try {
        Cursor cursor = context.getContentResolver().query(uri
                ,new String[]{MediaStore.Files.FileColumns.DATA},null,null,null);
        if (cursor != null && cursor.moveToFirst()) {
            int path_index = cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DATA);
            String path = cursor.getString(path_index);
            //Log.d(TAG,"isRingtoneExistByQueryDb path = " + path);
            if(path != null && !"".equals(path)){
                exist = true;
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    Log.d(TAG,"isRingtoneExistByQueryDb " + uri + " is exist = " + exist);
    return exist;
}

/**
 * get default ringtone uri
 *
 * @hide
 */
private static Uri getDefaultRingtoneUri(Context context, int type) {
    Uri defaultUri = null;
    String uriString = null;
    ContentResolver resolver = context.getContentResolver();
    switch (type) {
        case TYPE_RINGTONE:
            uriString = Settings.System.getString(resolver, KEY_DEFAULT_RINGTONE);
            break;

        case TYPE_NOTIFICATION:
            uriString = Settings.System.getString(resolver, KEY_DEFAULT_NOTIFICATION);
            break;

        case TYPE_ALARM:
            uriString = Settings.System.getString(resolver, KEY_DEFAULT_ALARM);
            break;

        default:
            Log.e(TAG, "getDefaultRingtoneUri with unsupport type!");
            return null;
    }
    defaultUri = (uriString == null ? null : Uri.parse(uriString));
    Log.d(TAG, "getDefaultRingtoneUri: type = " + type + ", default uri = " + defaultUri);
    return defaultUri;
}
/***
 * finish to check ringtone exist
 */

/**
 * Gets the current default sound's {@link Uri}. This will give the actual
 * sound {@link Uri}, instead of using this, most clients can use
 * {@link System#DEFAULT_RINGTONE_URI}.
 * 
 * @param context A context used for querying.
 * @param type The type whose default sound should be returned. One of
 *            {@link #TYPE_RINGTONE}, {@link #TYPE_NOTIFICATION}, or
 *            {@link #TYPE_ALARM}.
 * @return A {@link Uri} pointing to the default sound for the sound type.
 * @see #setActualDefaultRingtoneUri(Context, int, Uri)
 */
public static Uri getActualDefaultRingtoneUri(Context context, int type) {
    String setting = getSettingForType(type);
    if (setting == null) return null;
    final String uriString = Settings.System.getStringForUser(context.getContentResolver(),
            setting, context.getUserId());
    Uri ringtoneUri = uriString != null ? Uri.parse(uriString) : null;

    //start to check ringtone exist
    try {
        boolean isExist = isRingtoneExist(context, Uri.parse(uriString)) || isRingtoneExistByQueryDb(context, Uri.parse(uriString));
        Log.d(TAG,"getActualDefaultRingtoneUri isExist = " + isExist);
        if (uriString != null && !isExist){
            Log.i(TAG, "Get actual default setdefaultURi= " + uriString);
            Uri defaultUri = getDefaultRingtoneUri(context,type);
            setActualDefaultRingtoneUri(context,type,defaultUri);
            return defaultUri;
        }
        Log.d(TAG,"getActualDefaultRingtoneUri 2222 uriString = "+uriString);
    } catch (Exception ex){
        Log.d(TAG, ex.getMessage());
    }
    //finish to check ringtone exist

    // If this doesn't verify, the user id must be kept in the uri to ensure it resolves in the
    // correct user storage
    if (ringtoneUri != null
            && ContentProvider.getUserIdFromUri(ringtoneUri) == context.getUserId()) {
        ringtoneUri = ContentProvider.getUriWithoutUserId(ringtoneUri);
    }

    return ringtoneUri;
}

当铃声不存在时候,会重新读取数据库文件找到对应的铃声,再次设置到系统中,而达到还原的效果。

猜你喜欢

转载自blog.csdn.net/liuminx/article/details/106815080