如何解决添加管理外部存储权限后,我无法将APK上传到谷歌商店
我在 Google Play 商店有一个应用程序,我更新了代码以支持 Android 11 操作系统,我正在通过此权限使用移动存储
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
当我尝试在 Google 商店上传 APK 时,出现此问题
您的 APK 或 Android App Bundle 请求“android.permission.MANAGE_EXTERNAL_STORAGE”权限,但 Google Play 尚不支持。
我该如何解决?
解决方法
将 api 级别更改为小于 30,因为由于 covid-19,所有权限都已停止。 此临时上传限制仅影响面向 Android 11(API 级别 30)并请求所有文件访问权限的应用。
,https://support.google.com/googleplay/android-developer/answer/9956427?hl=en-GB
我想要么删除权限,要么等一会儿。
,听起来,针对 OS 11 的 apk 的上传被暂时阻止,直到 2021 年初,如本链接所述,请查看:
https://support.google.com/googleplay/android-developer/answer/9956427?hl=en
,如果你的目标 sdk 是 30 并且你想访问文件管理器
删除 MANAGE_EXTERNAL_STORAGE PERMISSION 并使用以下代码您将能够访问文件管理器
点击打开:-
private ActivityResultLauncher<Intent> importActivityRegister;
Intent chooseFile = new Intent(Intent.ACTION_GET_CONTENT);
chooseFile.addCategory(Intent.CATEGORY_OPENABLE);
chooseFile.setType("*/*");
importActivityRegister.launch(chooseFile);
从文件管理器返回后,它包含
importActivityRegister = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),new ActivityResultCallback<ActivityResult>() {
@Override
public void onActivityResult(ActivityResult result) {
if (result.getResultCode() == Activity.RESULT_OK) {
Uri content_describer = data.getData();
String realPath = new FilePathUtils(context).getPath(content_describer);
}
}
});
FilePathUtils 类是:-
public class FilePathUtils {
private static Uri contentUri = null;
Context context;
public FilePathUtils(Context context) {
this.context=context;
}
@SuppressLint("NewApi")
public String getPath(final Uri uri) {
// check here to KITKAT or new version
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
String selection = null;
String[] selectionArgs = null;
// DocumentProvider
if (isKitKat ) {
// ExternalStorageProvider
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
String fullPath = getPathFromExtSD(split);
if (fullPath != "") {
return fullPath;
} else {
return null;
}
}
// DownloadsProvider
if (isDownloadsDocument(uri)) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
final String id;
Cursor cursor = null;
try {
cursor = context.getContentResolver().query(uri,new String[]{MediaStore.MediaColumns.DISPLAY_NAME},null,null);
if (cursor != null && cursor.moveToFirst()) {
String fileName = cursor.getString(0);
String path = Environment.getExternalStorageDirectory().toString() + "/Download/" + fileName;
if (!TextUtils.isEmpty(path)) {
return path;
}
}
}
finally {
if (cursor != null)
cursor.close();
}
id = DocumentsContract.getDocumentId(uri);
if (!TextUtils.isEmpty(id)) {
if (id.startsWith("raw:")) {
return id.replaceFirst("raw:","");
}
String[] contentUriPrefixesToTry = new String[]{
"content://downloads/public_downloads","content://downloads/my_downloads"
};
for (String contentUriPrefix : contentUriPrefixesToTry) {
try {
final Uri contentUri = ContentUris.withAppendedId(Uri.parse(contentUriPrefix),Long.valueOf(id));
return getDataColumn(context,contentUri,null);
} catch (NumberFormatException e) {
//In Android 8 and Android P the id is not a number
return uri.getPath().replaceFirst("^/document/raw:","").replaceFirst("^raw:","");
}
}
}
}
else {
final String id = DocumentsContract.getDocumentId(uri);
if (id.startsWith("raw:")) {
return id.replaceFirst("raw:","");
}
try {
contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"),Long.valueOf(id));
}
catch (NumberFormatException e) {
e.printStackTrace();
}
if (contentUri != null) {
return getDataColumn(context,null);
}
}
}
// MediaProvider
if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
selection = "_id=?";
selectionArgs = new String[]{split[1]};
return getDataColumn(context,selection,selectionArgs);
}
if (isGoogleDriveUri(uri)) {
return getDriveFilePath(uri);
}
if(isWhatsAppFile(uri)){
return getFilePathForWhatsApp(uri);
}
if ("content".equalsIgnoreCase(uri.getScheme())) {
if (isGooglePhotosUri(uri)) {
return uri.getLastPathSegment();
}
if (isGoogleDriveUri(uri)) {
return getDriveFilePath(uri);
}
if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
{
// return getFilePathFromURI(context,uri);
return copyFileToInternalStorage(uri,"userfiles");
// return getRealPathFromURI(context,uri);
}
else
{
return getDataColumn(context,uri,null);
}
}
if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
}
else {
if(isWhatsAppFile(uri)){
return getFilePathForWhatsApp(uri);
}
if ("content".equalsIgnoreCase(uri.getScheme())) {
String[] projection = {
MediaStore.Images.Media.DATA
};
Cursor cursor = null;
try {
cursor = context.getContentResolver()
.query(uri,projection,selectionArgs,null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
if (cursor.moveToFirst()) {
return cursor.getString(column_index);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
return null;
}
private boolean fileExists(String filePath) {
File file = new File(filePath);
return file.exists();
}
private String getPathFromExtSD(String[] pathData) {
final String type = pathData[0];
final String relativePath = "/" + pathData[1];
String fullPath = "";
if ("primary".equalsIgnoreCase(type)) {
fullPath = Environment.getExternalStorageDirectory() + relativePath;
if (fileExists(fullPath)) {
return fullPath;
}
}
// Environment.isExternalStorageRemovable() is `true` for external and internal storage
// so we cannot relay on it.
//
// instead,for each possible path,check if file exists
// we'll start with secondary storage as this could be our (physically) removable sd card
fullPath = System.getenv("SECONDARY_STORAGE") + relativePath;
if (fileExists(fullPath)) {
return fullPath;
}
fullPath = System.getenv("EXTERNAL_STORAGE") + relativePath;
if (fileExists(fullPath)) {
return fullPath;
}
return fullPath;
}
private String getDriveFilePath(Uri uri) {
Uri returnUri = uri;
Cursor returnCursor = context.getContentResolver().query(returnUri,null);
/*
* Get the column indexes of the data in the Cursor,* * move to the first row in the Cursor,get the data,* * and display it.
* */
int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE);
returnCursor.moveToFirst();
String name = (returnCursor.getString(nameIndex));
String size = (Long.toString(returnCursor.getLong(sizeIndex)));
File file = new File(context.getCacheDir(),name);
try {
InputStream inputStream = context.getContentResolver().openInputStream(uri);
FileOutputStream outputStream = new FileOutputStream(file);
int read = 0;
int maxBufferSize = 1 * 1024 * 1024;
int bytesAvailable = inputStream.available();
//int bufferSize = 1024;
int bufferSize = Math.min(bytesAvailable,maxBufferSize);
final byte[] buffers = new byte[bufferSize];
while ((read = inputStream.read(buffers)) != -1) {
outputStream.write(buffers,read);
}
Log.e("File Size","Size " + file.length());
inputStream.close();
outputStream.close();
Log.e("File Path","Path " + file.getPath());
Log.e("File Size","Size " + file.length());
} catch (Exception e) {
Log.e("Exception",e.getMessage());
}
return file.getPath();
}
/***
* Used for Android Q+
* @param uri
* @param newDirName if you want to create a directory,you can set this variable
* @return
*/
private String copyFileToInternalStorage(Uri uri,String newDirName) {
Uri returnUri = uri;
Cursor returnCursor = context.getContentResolver().query(returnUri,new String[]{
OpenableColumns.DISPLAY_NAME,OpenableColumns.SIZE
},null);
/*
* Get the column indexes of the data in the Cursor,* * and display it.
* */
int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE);
returnCursor.moveToFirst();
String name = (returnCursor.getString(nameIndex));
String size = (Long.toString(returnCursor.getLong(sizeIndex)));
File output;
if(!newDirName.equals("")) {
File dir = new File(context.getFilesDir() + "/" + newDirName);
if (!dir.exists()) {
dir.mkdir();
}
output = new File(context.getFilesDir() + "/" + newDirName + "/" + name);
}
else{
output = new File(context.getFilesDir() + "/" + name);
}
try {
InputStream inputStream = context.getContentResolver().openInputStream(uri);
FileOutputStream outputStream = new FileOutputStream(output);
int read = 0;
int bufferSize = 1024;
final byte[] buffers = new byte[bufferSize];
while ((read = inputStream.read(buffers)) != -1) {
outputStream.write(buffers,read);
}
inputStream.close();
outputStream.close();
}
catch (Exception e) {
Log.e("Exception",e.getMessage());
}
return output.getPath();
}
private String getFilePathForWhatsApp(Uri uri){
return copyFileToInternalStorage(uri,"whatsapp");
}
private String getDataColumn(Context context,Uri uri,String selection,String[] selectionArgs) {
Cursor cursor = null;
final String column = "_data";
final String[] projection = {column};
try {
cursor = context.getContentResolver().query(uri,null);
if (cursor != null && cursor.moveToFirst()) {
final int index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(index);
}
}
finally {
if (cursor != null)
cursor.close();
}
return null;
}
private boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
private boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
private boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
private boolean isGooglePhotosUri(Uri uri) {
return "com.google.android.apps.photos.content".equals(uri.getAuthority());
}
public boolean isWhatsAppFile(Uri uri){
return "com.whatsapp.provider.media".equals(uri.getAuthority());
}
private boolean isGoogleDriveUri(Uri uri) {
return "com.google.android.apps.docs.storage".equals(uri.getAuthority()) || "com.google.android.apps.docs.storage.legacy".equals(uri.getAuthority());
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。