Forked from Sonderman/AndroidManifest required permissions.xml
Created
May 5, 2024 11:13
-
-
Save SwShard/35ff7fea1f1b4e356fad9b1c0bc21fbb to your computer and use it in GitHub Desktop.
Solution: How to access Android/data or Android/obb folders in Android 11+ No root
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> | |
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> | |
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/> | |
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/> | |
<uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES"/> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Call anywhere in your main code | |
if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.R){ | |
requestAllFilesPermission() | |
requestDocumentPermission("data") | |
requestDocumentPermission("obb") | |
} | |
@RequiresApi(Build.VERSION_CODES.R) | |
private fun requestAllFilesPermission(){ | |
val intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION) | |
intent.addCategory("android.intent.category.DEFAULT") | |
intent.data = Uri.fromParts("package",packageName,null) | |
startActivity(intent) | |
} | |
@RequiresApi(Build.VERSION_CODES.Q) | |
private fun requestDocumentPermission(folder: String) { | |
val storageManager = application.getSystemService(Context.STORAGE_SERVICE) as StorageManager | |
val intent = storageManager.primaryStorageVolume.createOpenDocumentTreeIntent() | |
val targetDirectory = "Android%2F$folder" // add your directory to be selected by the user | |
var uri = intent.getParcelableExtra<Uri>("android.provider.extra.INITIAL_URI") as Uri | |
var scheme = uri.toString() | |
scheme = scheme.replace("/root/", "/document/") | |
scheme += "%3A$targetDirectory" | |
uri = Uri.parse(scheme) | |
intent.putExtra("android.provider.extra.INITIAL_URI", uri) | |
startActivityForResult(intent, REQUEST_CODE) | |
} | |
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { | |
super.onActivityResult(requestCode, resultCode, data) | |
if (resultCode == RESULT_OK && requestCode == REQUEST_CODE) { | |
if (data != null) { | |
data.data?.let { treeUri -> | |
// treeUri is the Uri of the file | |
// if life long access is required the takePersistableUriPermission() is used | |
contentResolver.takePersistableUriPermission( | |
treeUri, | |
Intent.FLAG_GRANT_READ_URI_PERMISSION or | |
Intent.FLAG_GRANT_WRITE_URI_PERMISSION | |
) | |
readSDK30(treeUri) | |
} | |
} | |
} | |
} | |
private fun readSDK30(treeUri: Uri) { | |
val tree = DocumentFile.fromTreeUri(this, treeUri)!! | |
val uriList = arrayListOf<Uri>() | |
listFiles(tree).forEach { uri -> | |
uriList.add(uri) | |
Log.i("Uri Log:",uri.toString()) | |
// Collect all the Uri from here | |
} | |
} | |
private fun listFiles(folder: DocumentFile): List<Uri> { | |
return if (folder.isDirectory) { | |
folder.listFiles().mapNotNull { file -> | |
if (file.name != null) file.uri else null | |
} | |
} else { | |
emptyList() | |
} | |
} | |
// For more access to documents visit here: https://developer.android.com/training/data-storage/shared/documents-files#examine-metadata |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment