【发布时间】:2021-08-18 10:39:26
【问题描述】:
请指导我如何在 android 11 中访问 whatsapp 状态文件夹? 我在 Play 商店中看到了不需要任何特殊许可但仍能显示状态的状态保护应用程序? 告诉我如何访问 android 11 中的 WhatsApp/Media/.Statuses 文件夹?
请指导我如何在 android 11 中访问 whatsapp 状态文件夹? 我在 Play 商店中看到了不需要任何特殊许可但仍能显示状态的状态保护应用程序? 告诉我如何访问 android 11 中的 WhatsApp/Media/.Statuses 文件夹?
如果您明确允许 Android 11 的 WhatsApp 文件夹权限,您可以使用 DocumentTreeIntent 解决它,您可以这样做。
if (Constants.isPackageInstalled(getActivity(), "com.whatsapp")) {
Intent intent;
StorageManager sm = (StorageManager) getActivity().getSystemService(STORAGE_SERVICE);
String statusDir = getWhatsupFolder();
String str = "android.provider.extra.INITIAL_URI";
if (Build.VERSION.SDK_INT >= 29) {
intent = sm.getPrimaryStorageVolume().createOpenDocumentTreeIntent();
String scheme = ((Uri) intent.getParcelableExtra(str)).toString().replace("/root/", "/document/");
String stringBuilder = scheme +
"%3A" +
statusDir;
intent.putExtra(str, Uri.parse(stringBuilder));
} else {
intent = new Intent("android.intent.action.OPEN_DOCUMENT_TREE");
intent.putExtra(str, Uri.parse(statusDir));
}
intent.addFlags(2);
intent.addFlags(1);
intent.addFlags(128);
intent.addFlags(64);
startActivityForResult(intent, REQUEST_ACTION_OPEN_DOCUMENT_TREE);
return;
}
在使用此代码之前,您必须检查是否安装了 WhatsApp,因此首先要检查的是这里的代码。
try {
context.getPackageManager().getPackageInfo(packageName, 0);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
授予权限后,您必须通过此代码检索文件
private DocumentFile[] getFromSdcard() {
DocumentFile fromTreeUri = DocumentFile.fromTreeUri(requireContext().getApplicationContext(), Uri.parse(namedataprefs));
if (fromTreeUri != null && fromTreeUri.exists() && fromTreeUri.isDirectory() && fromTreeUri.canRead() && fromTreeUri.canWrite()) {
return fromTreeUri.listFiles();
}
return null;
}
DocumentFile[] allFiles = getFromSdcard();
//to get signal file path
String path = allFiles[0].getUri().toString();
您可以从下面的代码中获取有关文档树意图的更多详细信息,仅用于理解目的
参考:How to check which StorageVolume we have access to, and which we don't?
requestAccessButton.setOnClickListener {
storageVolumes = storageManager.storageVolumes
val primaryVolume = storageManager.primaryStorageVolume
val intent = primaryVolume.createOpenDocumentTreeIntent()
startActivityForResult(intent, 1)
}
}
private fun checkAccessToStorageVolumes() {
val storageVolumePathsWeHaveAccessTo = HashSet<String>()
val persistedUriPermissions = contentResolver.persistedUriPermissions
persistedUriPermissions.forEach {
storageVolumePathsWeHaveAccessTo.add(it.uri.toString())
}
val storageManager = getSystemService(Context.STORAGE_SERVICE) as StorageManager
val storageVolumes = storageManager.storageVolumes
for (storageVolume in storageVolumes) {
val uuid = if (storageVolume.isPrimary) {
// Primary storage doesn't get a UUID here.
"primary"
} else {
storageVolume.uuid
}
val volumeUri = uuid?.let { buildVolumeUriFromUuid(it) }
when {
uuid == null ->
Log.d("AppLog", "UUID is null for ${storageVolume.getDescription(this)}!")
storageVolumePathsWeHaveAccessTo.contains(volumeUri) ->
Log.d("AppLog", "Have access to $uuid")
else -> Log.d("AppLog", "Don't have access to $uuid")
}
}
}
private fun buildVolumeUriFromUuid(uuid: String): String {
return DocumentsContract.buildTreeDocumentUri(
"com.android.externalstorage.documents",
"$uuid:"
).toString()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
Log.d("AppLog", "resultCode:$resultCode")
val uri = data?.data ?: return
val takeFlags =
Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
contentResolver.takePersistableUriPermission(uri, takeFlags)
Log.d("AppLog", "granted uri: ${uri.path}")
}
【讨论】: