天天看點

java.lang.IllegalArgumentException: Invalid path解決方案

功能:讀取外置存儲的資訊。

現象:在反彈插拔TF卡之後,會彈出強制關閉

機率:反複插拔TF卡會出現,在一定時間内多次插拔,可以達到必現

Logcat:

E/AndroidRuntime( 2920): FATAL EXCEPTION: main
E/AndroidRuntime( 2920): Process: com.borqs.factorytest, PID: 2920
E/AndroidRuntime( 2920): java.lang.RuntimeException: Error receiving broadcast Intent { act=android.intent.action.MEDIA_MOUNTED dat=file:///mnt/external_sd flg=0x4000010 (has extras) } in [email protected]
E/AndroidRuntime( 2920): at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:876)
E/AndroidRuntime( 2920): at android.os.Handler.handleCallback(Handler.java:739)
E/AndroidRuntime( 2920): at android.os.Handler.dispatchMessage(Handler.java:95)
E/AndroidRuntime( 2920): at android.os.Looper.loop(Looper.java:135)
E/AndroidRuntime( 2920): at android.app.ActivityThread.main(ActivityThread.java:5280)
E/AndroidRuntime( 2920): at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime( 2920): at java.lang.reflect.Method.invoke(Method.java:372)
E/AndroidRuntime( 2920): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:963)
E/AndroidRuntime( 2920): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:758)
E/AndroidRuntime( 2920): Caused by: java.lang.IllegalArgumentException: Invalid path: /mnt/external_sd
E/AndroidRuntime( 2920): at android.os.StatFs.doStat(StatFs.java:46)
E/AndroidRuntime( 2920): at android.os.StatFs.<init>(StatFs.java:39)
E/AndroidRuntime( 2920): at com.borqs.factorytest.activity.ComprehensiveTest.measureApproximateStorage(ComprehensiveTest.java:1001)
E/AndroidRuntime( 2920): at com.borqs.factorytest.activity.ComprehensiveTest.measureApproximateStorageAndRamAndRomAndCPU(ComprehensiveTest.java:945)
E/AndroidRuntime( 2920): at com.borqs.factorytest.activity.ComprehensiveTest.access$700(ComprehensiveTest.java:54)
E/AndroidRuntime( 2920): at com.borqs.factorytest.activity.ComprehensiveTest$7.onReceive(ComprehensiveTest.java:771)
E/AndroidRuntime( 2920): at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:866)
E/AndroidRuntime( 2920): ... 8 more
E/AndroidRuntime( 2920): Caused by: android.system.ErrnoException: statvfs failed: EIO (I/O error)
E/AndroidRuntime( 2920): at libcore.io.Posix.statvfs(Native Method)
E/AndroidRuntime( 2920): at libcore.io.BlockGuardOs.statvfs(BlockGuardOs.java:298)
E/AndroidRuntime( 2920): at android.system.Os.statvfs(Os.java:459)
E/AndroidRuntime( 2920): at android.os.StatFs.doStat(StatFs.java:44)
E/AndroidRuntime( 2920): ... 14 more
           

源碼:

// sd card ext
if(Environment.getExternalStorageDirectory().getPath().equals("/storage/emulated/0")) {
    if((new File("/mnt/sdcard_ext")).exists()) {
        stat = new StatFs("/mnt/sdcard_ext");
    } else if(!mSdPath.equals("")) {
        if((new File(mSdPath)).exists()) {
        stat = new StatFs(mSdPath);//-------------出錯行
    }
} else {
    callShellCommand_Sdcard("mount");
    mSdPath = "/storage/" + mSdPath.substring(mSdPath.lastIndexOf("/") + 1);
    if((new File(mSdPath)).exists()) {
        stat = new StatFs(mSdPath);
    }
}
           

解決方案:

在AndroidManifest.xml添加permission

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

解決原理:

1. 看log

    抛出了java.lang.IllegalArgumentException: Invalid path: /mnt/external_sd

    傳入的參數不合法,具體是非法路徑。問題出在這個位址上.

    E/AndroidRuntime( 2920): at android.os.StatFs.doStat(StatFs.java:46)

    E/AndroidRuntime( 2920): at android.os.StatFs.<init>(StatFs.java:39)

    執行初始化的的時候挂的

2.看源碼錯誤位置

    new StatFs(mSdPath);

3.得出可能結論

    或許是因為檔案讀寫出問題

4. 看docs

READ_EXTERNAL_STORAGE

added in  API level 16

String READ_EXTERNAL_STORAGE      

Allows an application to read from external storage.

Any app that declares the 

WRITE_EXTERNAL_STORAGE

 permission is implicitly granted this permission.

This permission is enforced starting in API level 19. Before API level 19, this permission is not enforced and all apps still have access to read from external storage. You can test your app with the permission enforced by enabling Protect USB storage under Developer options in the Settings app on a device running Android 4.1 or higher.

Also starting in API level 19, this permission is not required to read/write files in your application-specific directories returned by 

getExternalFilesDir(String)

and 

getExternalCacheDir()

.

Note: If both your 

minSdkVersion

 and 

targetSdkVersion

 values are set to 3 or lower, the system implicitly grants your app this permission. If you don't need this permission, be sure your 

targetSdkVersion

 is 4 or higher.

Protection level: dangerous

Constant Value: "android.permission.READ_EXTERNAL_STORAGE"

對檔案進行讀寫的話,都需要這個權限,那麼擷取這個資訊,說不定也需要這個權限。

繼續閱讀