Nowadays due to the Google Play store's new policy, we do not access directly external storage using run time permission in Android OS 10 and 10 above. We use” MANAGE_EXTERNAL_STORAGE” run time permission but this permission is very sensitive so the Google Play store is not allowed to implement this permission.
We have an alternate solution for accessing external storage using media storage API and avoid ” MANAGE_EXTERNAL_STORAGE” sensitive permission implementation. You can manage your all device for accessing external storage using the below solution.
Step1: Required implementation in AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="28" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
…
android:requestLegacyExternalStorage="true"
…
>
Using the above code you easily access external storage in below Android OS 10.
Step2: Check runtime permission based on current device OS.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
//your code here for media storage API
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ActivityCompat.checkSelfPermission(ProductDetailsActivity.this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(ProductDetailsActivity.this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
REQUEST_WRITE_EXTERNAL_STORAGE);
return;
} else {
//your code here…
}
}
We can check runtime permission and manage permission based on the runtime check device SDK version.
Step3: Handle runtime permission.
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == REQUEST_WRITE_EXTERNAL_STORAGE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//your code here…
} else {
Toast.makeText(ProductDetailsActivity.this, getResources().getString(R.string.download_permission_fail_error_message), Toast.LENGTH_LONG).show();
}
}
}
How we can check file is exist or not in external storage for lower android 10 OS and above android 10 OS.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
if (checkFileIsExist(“FileName”)) {
// file is exist
} else {
// code for create or download new file.
}
} else {
File filePath = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
+ File.separator + “FileName”);
if (filePath.exists()) {
// file is exist
} else {
// code for create or download new file.
}
}
private boolean checkFileIsExist(String fileName) {
String name = "";
String[] projection = new String[]{
MediaStore.Files.FileColumns._ID,
MediaStore.Files.FileColumns.DISPLAY_NAME,
};
String selection = MediaStore.Files.FileColumns.DISPLAY_NAME + " = ?";
String[] selectionArgs = new String[]{fileName};
String sortOrder = MediaStore.Files.FileColumns._ID + " DESC";
Cursor cursor = mActivity.getContentResolver().query(
MediaStore.Files.getContentUri("external"),
projection,
selection,
selectionArgs,
sortOrder
);
int nameColumn = cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DISPLAY_NAME);
while (cursor.moveToNext()) {
name = cursor.getString(nameColumn);
}
if (name.equals("")) {
return false;
} else {
return true;
}
}
How we can create file download file in external storage for lower android 10 OS and above android 10 OS.
int count;
OutputStream output = null;
try {
URL url = new URL(“FileUrl”);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream input = new BufferedInputStream(url.openStream(), 8192);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, “FileName”);
contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "application/zip");
contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS + File.separator + getResources().getString(R.string.storageFolderName) + File.separator);
Uri fileUri = getContentResolver().insert(MediaStore.Files.getContentUri("external"), contentValues);
if (fileUri == null) {
Log.e("TAG", "Failed to create new MediaStore record");
} else {
output = getContentResolver().openOutputStream(fileUri);
}
} else {
String filePath = Environment.getExternalStorageDirectory().getAbsolutePath()
+ File.separator + “FileName”;
output = new FileOutputStream(filePath);
}
byte data[] = new byte[1024];
while ((count = input.read(data)) > 0) {
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception e) {
e.printStackTrace();
}
How we can delete file in external storage for android 10 and above OS.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
if(checkFileIsExist(“FileName”)) {
deleteFileByFileName((“FileName”);
}
}
private void deleteFileByFileName(String fileName) {
String selection = MediaStore.Images.Media.DISPLAY_NAME + " = ?";
String[] selectionArgs = new String[]{fileName};
getContentResolver().delete(MediaStore.Files.getContentUri("external"),selection,selectionArgs);
}
Using MediaStore API you can CRUD operation on external storage without runtime permission.