將SD卡的音頻設定為手機鈴聲後刪除,手機鈴聲沒有恢複到預設的問題

來源:互聯網
上載者:User

標籤:with   print   gif   解決辦法   通知   media   dex   work   boolean   

1. Android7.0,將儲存卡中MP3設定為鈴聲,刪除該MP3後,settings中的鈴聲沒有變化,來電鈴聲也沒有變化。

    原因:android7.0的新特性

          google 預設如此設計,在選擇鈴聲的過程中,會將刪除的鈴聲進行緩衝,在刪除鈴聲後,播放為快取檔案 
          
              1. google 目前將鈴聲分為actual default ringtone和cache ringtone,前者以ringtone為key將檔案uri儲存在xml檔案裡,後者是以stream file的形式儲存在 ringtone_cache 的resource中。 
  
              2. 在鈴聲初始化的時候,鈴聲是初始化在actual default ringtone裡,這個是可變的。不再是N版本之前把default鈴聲寫死。 
  
              3. 設定鈴聲時,會同時寫actual default ringtone 和 ringtone_cache。 
  
              4. 響鈴時,mediaplayer.java會優先播放ringtone_cache裡的stream resource檔案,所以就算原音樂檔被刪除,依舊會響該備份鈴聲。 
  
              5. 鬧鈴、通知音等,原理同上。

解決辦法:如果需要在刪除MP3後將來電鈴聲恢複為預設鈴聲,可以這麼做:

  1.從settings中進入鈴聲選擇介面,會調用getActualDefaultRingtoneUri,擷取當前的鈴聲uri。那麼我們需要在每次擷取uri的時候,進行判斷,該uri的音樂是否還存在。判斷方法:

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

代碼路徑:/frameworks/base / media/java/android/media/RingtoneManager.java

如果該uri音樂已經不存在,那麼將預設uri設定為鈴聲。由於7.0的預設鈴聲不再寫死,是可變的(親測是這樣,但沒具體看是怎麼做的),因此我們需要自己將第一次開機時讀到的預設uri存起來。

        private void setSettingIfNotSet(String settingName, Uri uri, long rowId) {            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);//                /// M: Adds log to debug setting ringtones.//                if (DEBUG) {//                    Log.v(TAG, "setSettingIfNotSet: name="//                        + settingName + ",value=" + rowId);//                }//            }            if (TextUtils.isEmpty(existingSettingValue)) {                // Set the setting to the given URI                Settings.System.putString(mContext.getContentResolver(), settingName,                        ContentUris.withAppendedId(uri, rowId).toString());                /// M: Adds log to debug setting ringtones.                Log.v(TAG, "setSettingIfNotSet: name=" + settingName + ",value=" + rowId);            } else {                /// M: Adds log to debug setting ringtones.                Log.e(TAG, "setSettingIfNotSet: name=" + settingName + " with value=" + existingSettingValue);            }        }

代碼路徑:/frameworks/base / media/java/android/media/MediaScanner.java

該settingsProvider欄位是我們自己定義的,在RingtoneManager.java中。

    /// M: Add for store and get default ringtone @{    /**     * M: The key used to store the default ringtone of voice call.     * @hide     * @internal     */    public static final String KEY_DEFAULT_RINGTONE = "mtk_audioprofile_default_ringtone";    /**     * M: The key used to store the default notification sound.     * @hide     * @internal     */    public static final String KEY_DEFAULT_NOTIFICATION = "mtk_audioprofile_default_notification";    /**     * M:The key used to store the default alarm sound.     * @hide     */    public static final String KEY_DEFAULT_ALARM = "mtk_audioprofile_default_alarm";    /// @}
    public 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;    }

那麼最後,就可以在getActualDefaultRingtoneUri()中進行判斷啦!

   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());        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());        }        Log.i(TAG, "Get actual default ringtone uri= " + uriString);        return uriString != null ? Uri.parse(uriString) : null;    }

 

 

     

將SD卡的音頻設定為手機鈴聲後刪除,手機鈴聲沒有恢複到預設的問題

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.