android.system.ErrnoException错误

问题描述 投票:5回答:2

我正在尝试使用以下代码获取内部存储详细信息(用作内部存储器的存储)。

public void getinternalstorage() {
        StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
        double bytesavalible = (double) stat.getBlockSizeLong() * (double) stat.getAvailableBlocksLong();
        final double gb = bytesavalible / (1024 * 1024 * 1024);
        double total = (double) stat.getBlockSizeLong() * stat.getBlockCountLong();
        final double totalgb = total / (1024 * 1024 * 1024);
        final double per = (100 - (gb / totalgb) * 100);
        update_inte((int) (per * 1), round(totalgb, 2), round((gb), 2));
        TextView text2written = (TextView) findViewById(R.id.inter);
        text2written.setText(String.valueOf(round((totalgb - gb), 2)) + " GB " + "/ " + String.valueOf(round(totalgb, 2)) + " GB");
    }

我也采取了所需的权限。

适用于Android 5.0及以下版本 -

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

对于Android 6.0及更高版本,我正在请求运行时权限。

但我收到了大约10个用户的android.system.ErrnoException错误。全栈跟踪

Fatal Exception: java.lang.RuntimeException: Unable to resume activity {com.package.app.Main_Screen}: java.lang.IllegalArgumentException: Invalid path: /sdcard
       at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3121)
       at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3152)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1398)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:148)
       at android.app.ActivityThread.main(ActivityThread.java:5443)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
Caused by java.lang.IllegalArgumentException: Invalid path: /sdcard
       at android.os.StatFs.doStat(StatFs.java:46)
       at android.os.StatFs.(StatFs.java)
       at com.package.app.Main_Screen.getinternalstorage(Main_Screen.java:565)
       at com.package.app.Main_Screen.on_resume(Main_Screen.java:785)
       at com.package.app.Main_Screen.checkPermission(Main_Screen.java:1070)
       at com.package.app.Main_Screen.onResume(Main_Screen.java:779)
       at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1281)
       at android.app.Activity.performResume(Activity.java:6320)
       at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3110)
       at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3152)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1398)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:148)
       at android.app.ActivityThread.main(ActivityThread.java:5443)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
Caused by android.system.ErrnoException: statvfs failed: ENOENT (No such file or directory)
       at libcore.io.Posix.statvfs(Posix.java)
       at libcore.io.BlockGuardOs.statvfs(BlockGuardOs.java:298)
       at android.system.Os.statvfs(Os.java:500)
       at android.os.StatFs.doStat(StatFs.java:44)
       at android.os.StatFs.(StatFs.java)
       at com.package.app.Main_Screen.getinternalstorage(Main_Screen.java:565)
       at com.package.app.Main_Screen.on_resume(Main_Screen.java:785)
       at com.package.app.Main_Screen.checkPermission(Main_Screen.java:1070)
       at com.package.app.Main_Screen.onResume(Main_Screen.java:779)
       at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1281)
       at android.app.Activity.performResume(Activity.java:6320)
       at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3110)
       at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3152)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1398)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:148)
       at android.app.ActivityThread.main(ActivityThread.java:5443)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)

我从5.0到7.0 Android版本收到此错误

java android android-sdcard sd-card
2个回答
2
投票

I)从外部存储目录获取路径

Environment.getExternalStorageDirectory().getPath()

你会得到类似的东西:

 /storage/emulated/0
 /mnt/sdcard 
 /mnt/sdcard-ext 

但错误指出你只得到qazxsw poi:

由java.lang.IllegalArgumentException引起:android.os.StatFs上的android.os.StatFs.doStat(StatFs.java:46)中的路径:/ sdcard无效。(StatFs.java)

如果我们检查引发此错误的SDK方法:

/sdcard

函数private static StructStatVfs doStat(String path) { try { return Os.statvfs(path); } catch (ErrnoException e) { throw new IllegalArgumentException("Invalid path: " + path, e); } } 返回有关已安装文件系统的信息。 path是已挂载文件系统中任何文件的路径名。

因此,要避免此问题,您必须确保已安装SD卡!在这种情况下很难在所有生产用户中确保这一点,选项将是验证。

顺便说一句,我建议使用statvfs()

getAbsolutePath()

代替

Environment.getExternalStorageDirectory().getAbsolutePath();

要获取绝对路径,将其解析为当前目录(如果它是相对路径)后的路径,从而产生“完全限定路径”。


II)显示的其他错误消息是:

由android.system.ErrnoException引起:statvfs失败:libcore.io.Posix.statvfs(Posix.java)的ENOENT(没有这样的文件或目录)

请记住,您的应用程序无法读取内部存储,请记住,您必须在设备6.0+中手动要求Environment.getExternalStorageDirectory().getAbsolutePath(); (固有的WRITE_EXTERNAL_STORAGE)权限

这将是以下原因:

ENOENT(没有这样的文件或目录)

因为用户必须接受权限。


0
投票

嗨请逐步检查以下流程。

1)请先将运行时权限检查到最新设备的代码中,请参阅下面的链接。

READ_EXTERNAL_STORAGE

2)您需要使用环境变量。 Environment.getExternalStorageDirectory(); 。 Environment.java中有许多方法。这取决于您需要什么信息。例如,要获取外部存储名称,请使用Environment.getExternalStorageDirectory()。getName();还有其他方法可以利用它们。对于内部存储,api可能无法公开发布。

https://developer.android.com/training/permissions/requesting.html

请检查下面2链接那些也可以帮助你。

StatFs stat = new StatFs(type.getPath()); long bytesAvailable = (long)stat.getBlockSize()*(long)stat.getAvailableBlocks(); long megAvailable = bytesAvailable / (1024 * 1024); Log.i("TAG","Available size in MB : "+megAvailable);

Android get free size of internal/external memory

希望这可以帮助。

© www.soinside.com 2019 - 2024. All rights reserved.