繁体   English   中英

如何以编程方式访问 android 11 中的隐藏文件?

[英]How to access hidden files in android 11 programmatically?

我想在我的应用程序中显示 whatsapp 状态。 到目前为止,我已经完成了以下工作:

public final String getStatusPath(boolean z) {
    if (Build.VERSION.SDK_INT < 30) {
        if (z) {
            return Environment.getExternalStorageDirectory().getAbsolutePath() + "/WhatsApp Business/Media/.Statuses";
        }
        return Environment.getExternalStorageDirectory().getAbsolutePath() + "/WhatsApp/Media/.Statuses";
    } else if (z) {
        return Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/media/com.whatsapp.w4b/WhatsApp Business/Media/.Statuses";
    } else {
        return Environment.getExternalStorageDirectory().getAbsolutePath()+ "/Android/media/com.whatsapp/WhatsApp/Media/.Statuses";
    }
}

private ArrayList<WhatStatusData> getStatusList() {
    ArrayList<WhatStatusData> arrayList = new ArrayList<>();

    File[] listFiles = new File(FileConstants.INSTANCE.getStatusPath(isBusiness)).listFiles();
    int i = 0;
    if (listFiles != null) {
        if (listFiles.length == 0) {
            Arrays.sort(listFiles);
        }

        int length = listFiles.length;
        while (i < length) {
            File file = listFiles[i];
            i++;
            String absolutePath = file.getAbsolutePath();
            Uri fromFile = Uri.fromFile(file);
            String name = file.getName();

            if (!name.equals(".nomedia")) {
                arrayList.add(new WhatStatusData(absolutePath, fromFile, name));
            }
        }
    }
    return arrayList;
}

在清单中

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

但我没有在 android 11 中获取数据。在其他版本中,代码工作正常。

得到解决方案 在 android 11 中获取隐藏文件访问的可能性有两种

  1. 正如@Subarata Talukder 所说,给予 MANAGE_EXTERNAL_STORAGE 权限
  2. 使用存储管理器授予特定文件夹访问权限,如下所述(不使用 MANAGE_EXTERNAL_STORAGE 权限)

在这里,我将展示如何以编程方式访问 whatsapp 状态

    //give permissions in manifest
    <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    //give run time permissions

    static final int REQUEST_PERMISSION_KEY = 1;

    int REQUEST_ACTION_OPEN_DOCUMENT_TREE = 101;

    SharedPreferences sharedPreferences;

检查是否在按钮单击时授予运行时权限

    if(sharedPreferences.getString("WATREE","").equals("")){
                if(checkAndRequestPermissions()){
                    if (SDK_INT >= Build.VERSION_CODES.Q) {
                        askPermission();
                    }else {
                        callActivity();
                    }
                }
            }else{
                callActivity();
            }



    private  boolean checkAndRequestPermissions() {

      int writePerm = ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE);
      int readPerm = ContextCompat.checkSelfPermission(getApplicationContext(),Manifest.permission.READ_EXTERNAL_STORAGE);

      List<String> listPermissionsNeeded = new ArrayList<>();
      if (writePerm != PackageManager.PERMISSION_GRANTED) {
          listPermissionsNeeded.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
      }

    if(readPerm != PackageManager.PERMISSION_GRANTED) {
        listPermissionsNeeded.add(Manifest.permission.READ_EXTERNAL_STORAGE);
    }

      if (!listPermissionsNeeded.isEmpty()) {
        ActivityCompat.requestPermissions(GBV_StartActivity.this,
                listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]),
                REQUEST_PERMISSION_KEY);
        return false;
    }
      return true;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
      super.onRequestPermissionsResult(requestCode, permissions, grantResults);
      if (requestCode == REQUEST_PERMISSION_KEY) {
          try {

              Map<String, Integer> permsLogin = new HashMap<>();
              // Initialize the map with both permissions
              permsLogin.put(Manifest.permission.WRITE_EXTERNAL_STORAGE, PackageManager.PERMISSION_GRANTED);
              permsLogin.put(Manifest.permission.READ_EXTERNAL_STORAGE, PackageManager.PERMISSION_GRANTED);

              // Fill with actual results from user
              if (grantResults.length > 0) {
                  for (int i = 0; i < permissions.length; i++)
                      permsLogin.put(permissions[i], grantResults[i]);
                  // Check for both permissions
                  if (permsLogin.get(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
                        && permsLogin.get(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {

                      if (SDK_INT >= Build.VERSION_CODES.Q) {
                        askPermission();
                    }else {
                        callActivity();
                    }

                    // process the normal flow
                    //else any one or both the permissions are not granted
                } else {

                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

                        if (shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)
                                || shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE)) {

                            showDialogOK((dialog, which) -> {
                                switch (which) {
                                    case DialogInterface.BUTTON_POSITIVE:
                                        checkAndRequestPermissions();
                                        break;
                                    case DialogInterface.BUTTON_NEGATIVE:
                                        // proceed with logic by disabling the related features or quit the app.
                                        break;
                                }
                            });
                        }
                        //permission is denied (and never ask again is  checked)
                        //shouldShowRequestPermissionRationale will return false
                        else {
                            Toast.makeText(getApplicationContext(), "Go to settings and enable permissions.", Toast.LENGTH_LONG)
                                    .show();

                            finish();
                            //proceed with logic by disabling the related features or quit the app.
                        }
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

private void showDialogOK(DialogInterface.OnClickListener okListener) {

    android.app.AlertDialog.Builder alertDialogBuilder = new android.app.AlertDialog.Builder(GBV_StartActivity.this);

    alertDialogBuilder.setMessage("You need to allow access to the permissions.")
            .setCancelable(false)
            .setPositiveButton("OK", okListener)
            .setNegativeButton("Cancel", okListener);

    android.app.AlertDialog alertDialog = alertDialogBuilder.create();

    // show it
    alertDialog.show();

}
public void callActivity(){

    startActivity(new Intent(GBV_StartActivity.this, MainActivity.class));
}

private String getWhatsupFolder() {

    String oldPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/WhatsApp/Media/.Statuses";
    String oldBusinessPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/WhatsApp Business/Media/.Statuses";

    String newPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/media/com.whatsapp/WhatsApp/Media/.Statuses";
    String newBusinessPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/media/com.whatsapp.w4b/WhatsApp Business/Media/.Statuses";

    String finalPath;


    if(new File(newBusinessPath).exists()){
        finalPath = "Android%2Fmedia%2Fcom.whatsapp.w4b%2FWhatsApp Business%2FMedia%2F.Statuses";
    }else if(new File(newPath).exists()){
        finalPath = "Android%2Fmedia%2Fcom.whatsapp%2FWhatsApp%2FMedia%2F.Statuses";
    }else if(new File(oldBusinessPath).exists()){
        finalPath = "WhatsApp Business%2FMedia%2F.Statuses";
    }else {
        finalPath = "WhatsApp%2FMedia%2F.Statuses";
    }
    return finalPath;
}


@RequiresApi(Build.VERSION_CODES.Q)
private void askPermission() {
    StorageManager storageManager = (StorageManager) getSystemService(STORAGE_SERVICE);
    Intent intent =  storageManager.getPrimaryStorageVolume().createOpenDocumentTreeIntent();

    String targetDirectory = getWhatsupFolder(); // add your directory to be selected by the user
    Uri uri = intent.getParcelableExtra("android.provider.extra.INITIAL_URI");
    String scheme = uri.toString();
    scheme = scheme.replace("/root/", "/document/");
    scheme += "%3A"+targetDirectory;
    uri = Uri.parse(scheme);

    Log.w("TAG", "askPermission: uri::"+uri );
    intent.putExtra("android.provider.extra.INITIAL_URI", uri);
    startActivityForResult(intent, REQUEST_ACTION_OPEN_DOCUMENT_TREE);
}


@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent intent) {
    super.onActivityResult(requestCode, resultCode, intent);

    if (requestCode == this.REQUEST_ACTION_OPEN_DOCUMENT_TREE && resultCode == -1) {
        Uri data = intent.getData();
        try {
            getContentResolver().takePersistableUriPermission(data, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        } catch (Exception e) {
            e.printStackTrace();
        }
        SharedPreferences.Editor editor2 = sharedPreferences.edit();
        editor2.putString("WATREE", data.toString());
        editor2.apply();

        callActivity();
    }
}

现在,在授予所有权限后,尝试从存储中获取图像或视频,如下所示:

    if (SDK_INT >= Build.VERSION_CODES.Q) {
        DocumentFile[] allFiles = getFromSdcard();
        if (allFiles != null) {

            for(int i = 0 ; i <allFiles.length ; i++){
                if (!allFiles[i].getUri().toString().contains(".nomedia")) {
                        Log.e("path:",allFiles[i].getUri().toString());
                        //add data in your arraylist
                }
            }
        }
    }else {
        String oldPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/WhatsApp/Media/.Statuses";
        String oldBusinessPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/WhatsApp Business/Media/.Statuses";

        String newPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/media/com.whatsapp/WhatsApp/Media/.Statuses";
        String newBusinessPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/media/com.whatsapp.w4b/WhatsApp Business/Media/.Statuses";

        String finalPath;
        if (!new File(oldPath).exists()) {
            if (!new File(oldBusinessPath).exists()) {

                if (!new File(newPath).exists()) {
                    if (!new File(newBusinessPath).exists()) {
                        finalPath = oldPath;
                    } else {
                        finalPath = newBusinessPath;
                    }
                } else {
                    finalPath = newPath;
                }
            } else {
                finalPath = oldBusinessPath;
            }
        } else {
            finalPath = oldPath;
        }
        File file2 = new File(finalPath);
        if (file2.exists()) {
            File[] listFiles = file2.listFiles();

            if (listFiles != null) {
                for (int i = 0; i < listFiles.length; i++) {
                    
                        Log.e("path:",listFiles[i].getPath()+"");
                        //add data in your arraylist
                }
            }
        }
    }



    public DocumentFile[] getFromSdcard() {
    DocumentFile fromTreeUri = DocumentFile.fromTreeUri(getContext(), Uri.parse(sharedPreferences.getString("WATREE","")));
    if (fromTreeUri == null || !fromTreeUri.exists() || !fromTreeUri.isDirectory() || !fromTreeUri.canRead() || !fromTreeUri.canWrite()) {
        return null;
    }
    return fromTreeUri.listFiles();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM