Android

[해결법]MediaPlayer: Couldn’t open java.io.FileNotFoundException: No content provider: MediaPlayer: Couldn’t open content://0@settings/system/ringtone_cache open failed: ENOENT (No such file or directory)

여태 몰랐다. 오류가 발생하고 있음을… 오류는 발생하였지만, 정상 동작하였기 때문에 알 수 없었다. 그러다 몇 일 전 테스트 하는 과정에 우연히 오류로그를 보게되었다.

2020-06-23 08:12:33.281 13494-13494/com.test.test W/MediaPlayer: Couldn't open 
    java.io.FileNotFoundException: No content provider: 
        at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1673)
        at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1503)
        at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1420)
        at android.media.MediaPlayer.attemptDataSource(MediaPlayer.java:1101)
        at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1073)
        at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1001)
        at android.media.Ringtone.setUri(Ringtone.java:332)
        at android.media.RingtoneManager.getRingtone(RingtoneManager.java:728)
        at android.media.RingtoneManager.getRingtone(RingtoneManager.java:703)
        at android.media.RingtoneManager.getRingtone(RingtoneManager.java:666)
        at com.test.test.SettingActivity.o(:1094)
        at com.test.test.SettingActivity.c(:986)
        at com.test.test.SettingActivity.onCreate(:276)
        at android.app.Activity.performCreate(Activity.java:7825)
        at android.app.Activity.performCreate(Activity.java:7814)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1306)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7356)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
2020-06-23 08:12:33.282 13494-13494/com.test.test 

■오류가 밸상한 코드

    private String getRingToneName() {
        try {
            SharedPreferences sp = getSharedPreferences(MY_PM_PREF, Activity.MODE_PRIVATE);
            Uri pickedUri = Uri.parse(sp.getString(POWER_OFF_RINGTONE, ""));
            RingtoneManager ringtoneManager = new RingtoneManager(SettingActivity.this);            
 
            Ringtone ringtone = ringtoneManager.getRingtone(SettingActivity.this, pickedUri);

            return ringtone.getTitle(SettingActivity.this);
         
        } catch (Exception e){
            return "";
        }
    }

오류가 발생한 위치 : Ringtone ringtone = ringtoneManager.getRingtone(SettingActivity.this, pickedUri);

벨소리를 지정한 경우에는 FileNotFoundException이 발생하지 않는다. 벨소리를 지정하지 않은 경우에 발생한다.

SharedPreferences 클래스를 사용하여 저장해둔 벨소리 정보(sp.getString(POWER_OFF_RINGTONE,””) 가 없어서 발생하는 케이스이다.

 

해결방법 : 벨소리를 설정하기 전이라면, 휴대폰에 설정된 기본 벨소리 정보를 가져올 수 있다. getDefaultUri(RingtoneManager.TYPE_RINGTONE) 메소드를 사용하면 된다. if문을 사용하여 분기하였다.

 

■오류 해결 코드

    private String getRingToneName() {
        try {
            SharedPreferences sp = getSharedPreferences(MY_PM_PREF, Activity.MODE_PRIVATE);
            Uri pickedUri = Uri.parse(sp.getString(POWER_OFF_RINGTONE, ""));
            RingtoneManager ringtoneManager = new RingtoneManager(SettingActivity.this);
            Ringtone ringtone;
            
            if( sp.getString(POWER_OFF_RINGTONE, "").equals("")) {
                pickedUri = ringtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
                ringtone = ringtoneManager.getRingtone(SettingActivity.this, pickedUri);
            }else{
               ringtone = ringtoneManager.getRingtone(SettingActivity.this, pickedUri);
            }

            return ringtone.getTitle(SettingActivity.this);

        } catch (Exception e){
            return "" ;
        }
    }

생각하지도 못했던 곳에서 오류가 발생하였다. 하나의 오류가 이렇게 해결이 되니, 앱의 안정성에 도움이 되겠지만….코로나 여파일까, 아니면 fabric 서비스의 종료일까… 이유는 알 수 없지만, 일일 설치자 수가 급격하게 떨어졌다. 기존에 하루 2000명 대의 사람들이 다운받았던 앱인데, 몇 달 전부터 800명대를 유지하고 있다. 

 

■ 추가적으로 open failed: ENOENT (No such file or directory) 오류가 발생한다면 저장소 권한 부여가 필요하다.

2020-06-23 08:55:23.395 12005-12005/com.test.test W/MediaPlayer: Couldn't open content://0@settings/system/ringtone_cache
    java.io.FileNotFoundException: open failed: ENOENT (No such file or directory)
        at android.database.DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(DatabaseUtils.java:149)
        at android.content.ContentProviderProxy.openTypedAssetFile(ContentProviderNative.java:705)
        at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1689)
        at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1505)
        at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1422)
        at android.media.MediaPlayer.attemptDataSource(MediaPlayer.java:1111)
        at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1073)
        at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1008)
        at com.lge.media.MediaPlayerEx.setDataSource(MediaPlayerEx.java:222)
        at android.media.Ringtone.setUri(Ringtone.java:565)
        at android.media.RingtoneManager.getRingtone(RingtoneManager.java:791)
        at android.media.RingtoneManager.getRingtone(RingtoneManager.java:763)
        at android.media.RingtoneManager.getRingtone(RingtoneManager.java:726)
        at com.test.test.SettingActivity.getPowerOffRingToneName(SettingActivity.java:392)
        at com.test.test.SettingActivity.loadSharedPref(SettingActivity.java:376)
        at com.test.test.SettingActivity.onCreate(SettingActivity.java:231)
        at android.app.Activity.performCreate(Activity.java:7812)
        at android.app.Activity.performCreate(Activity.java:7801)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1307)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3298)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3462)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2063)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7615)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:964)

 휴대폰에 있는mp3 파일등의 미디어 정보를 가져오고자 할때, 저장소권한을 부여 후 가져올 수 있다. 하지만, 벨소리 마져 저장소 권한이 필요한지는 몰랐다. 아이러니하게도 권한을 부여하지 않으면 오류만 발생할 뿐 벨소리 제목도 가져올 수 있고 벨소리 또한  정상적으로 동작한다. 안드로이드 운영체제의 구멍인가??????????????

 

Leave a Reply

error: Content is protected !!