Reputation:
I am trying to get Internal Storage details(Storage which is used as Internal Memory) using below code.
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");
}
I have also taken the required permissions.
For Android 5.0 and below-
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
For android 6.0 and above I am requesting runtime permissions.
But I have received android.system.ErrnoException
error from around 10 users.
Full Stack Trace
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)
I am receiving this error from 5.0 to 7.0 Android Version
Upvotes: 8
Views: 4947
Reputation: 126455
I) Getting the path from the External Storage Directory with
Environment.getExternalStorageDirectory().getPath()
you will get something like:
/storage/emulated/0
/mnt/sdcard
/mnt/sdcard-ext
but the error points out that you are only gettin /sdcard
:
Caused by java.lang.IllegalArgumentException: Invalid path: /sdcard at android.os.StatFs.doStat(StatFs.java:46) at android.os.StatFs.(StatFs.java)
If we check the SDK method that raise this error:
private static StructStatVfs doStat(String path) {
try {
return Os.statvfs(path);
} catch (ErrnoException e) {
throw new IllegalArgumentException("Invalid path: " + path, e);
}
}
The function statvfs() returns information about a mounted filesystem. path is the pathname of any file within the mounted filesystem.
So, to avoid this problem you must be sure that the SD Card is mounted! In this case is difficult assure this in all your production users, the option would be a validation.
btw, i recommend the use of getAbsolutePath()
Environment.getExternalStorageDirectory().getAbsolutePath();
instead of
Environment.getExternalStorageDirectory().getPath();
To get the absolute path, the path after resolving it against the current directory if it's relative, resulting in a "fully qualified path".
II) The other error message displayed is:
Caused by android.system.ErrnoException: statvfs failed: ENOENT (No such file or directory) at libcore.io.Posix.statvfs(Posix.java)
Remember, your application can´t read the internal Storage, remember, you must require WRITE_EXTERNAL_STORAGE
(inherent READ_EXTERNAL_STORAGE
) permission manually in devices 6.0+
This would be the cause of:
ENOENT (No such file or directory)
because the user must accept the permission.
Upvotes: 5
Reputation: 1373
Hi Please check below step by step process.
1) Please check runtime permission first into your code for latest devices see below link for it.
https://developer.android.com/training/permissions/requesting.html
2) You need to use the environment variable. Environment.getExternalStorageDirectory(); . There are many methods in Environment.java . It depends on what information you need . For example to get external storage name you use Environment.getExternalStorageDirectory().getName(); there are other methos you can make use of them. For Internal storage the api's may not be available publicly .
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);
Please check below 2 link those also helps you.
Android get free size of internal/external memory
How to Check available space on android device ? on SD card?
Hope this helps.
Upvotes: 0