i tried to get read edit manage storage in android java and output permission denied and not found in device setting - Stack Ove

时间: 2025-01-06 admin 业界

i developed app can read all documents like pdf, and office PowerPoint, excel, word and the main activity i want to show a list of all documents available on device so user can open any document inside app and not only browsing files from storage i tried this code but not working and tried another multiple solutions in stackoverflow and other websites and nothing work at end. my code

mainactivity before on create

private static final int PDF_SELECTION_CODE = 200;
    private static final int PERMISSION_REQUEST_CODE = 100;
    private RecyclerView recyclerView;
    private DocumentAdapter documentAdapter;
    private ArrayList<File> documentList;

inside on create

recyclerView = findViewById(R.id.recyclerView);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
            loadDocuments();
        } else {
            loadDocuments();
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            // Scoped Storage
            loadDocumentsWithScopedStorage();
        } else {
            // Legacy Storage
            loadDocumentsWithScopedStorage();
        }

        loadDocumentsWithMediaStore();

after on create

private void getDocuments(@NonNull File dir) {
        File[] files = dir.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    getDocuments(file);
                } else if (file.getName().endsWith(".pdf") ||
                        file.getName().endsWith(".doc") ||
                        file.getName().endsWith(".docx") ||
                        file.getName().endsWith(".txt")) {
                    documentList.add(file);
                }
            }
        }
    }

    private void loadDocumentsWithScopedStorage() {
        documentList = new ArrayList<>();
        Uri collection = MediaStore.Files.getContentUri("external");

        String[] projection = {
                MediaStore.Files.FileColumns.DATA,
                MediaStore.Files.FileColumns.DISPLAY_NAME
        };

        // Filter for specific document types
        String selection = MediaStore.Files.FileColumns.MIME_TYPE + " IN (?, ?, ?, ?)";
        String[] selectionArgs = new String[]{
                "application/pdf",
                "application/msword",
                "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
                "text/plain"
        };

        Cursor cursor = getContentResolver().query(collection, projection, selection, selectionArgs, null);

        if (cursor != null) {
            int dataIndex = cursor.getColumnIndex(MediaStore.Files.FileColumns.DATA);

            while (cursor.moveToNext()) {
                String filePath = cursor.getString(dataIndex);
                File file = new File(filePath);
                documentList.add(file);
            }
            cursor.close();
        }

        documentAdapter = new DocumentAdapter(documentList, file -> {
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setDataAndType(android.Uri.fromFile(file), "*/*");
            startActivity(intent);
        });
        recyclerView.setAdapter(documentAdapter);
    }

    private void loadDocumentsWithMediaStore() {
        documentList = new ArrayList<>();
        Uri collection = MediaStore.Files.getContentUri("external");

        String[] projection = {
                MediaStore.Files.FileColumns.DATA,
                MediaStore.Files.FileColumns.DISPLAY_NAME
        };

        String selection = MediaStore.Files.FileColumns.MIME_TYPE + " IN (?, ?, ?, ?)";
        String[] selectionArgs = new String[]{
                "application/pdf",
                "application/msword",
                "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
                "text/plain"
        };

        try (Cursor cursor = getContentResolver().query(collection, projection, selection, selectionArgs, null)) {
            if (cursor != null) {
                int dataIndex = cursor.getColumnIndex(MediaStore.Files.FileColumns.DATA);

                while (cursor.moveToNext()) {
                    String filePath = cursor.getString(dataIndex);
                    File file = new File(filePath);
                    documentList.add(file);
                }
            }
        }

        documentAdapter = new DocumentAdapter(documentList, file -> {
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setDataAndType(android.Uri.fromFile(file), "*/*");
            startActivity(intent);
        });
        recyclerView.setAdapter(documentAdapter);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == PERMISSION_REQUEST_CODE) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                loadDocuments();
            } else {
                Toast.makeText(this, "Permission denied", Toast.LENGTH_SHORT).show();
            }
        }
    }

Document Adapter

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import java.io.File;
import java.util.ArrayList;

public class DocumentAdapter extends RecyclerView.Adapter<DocumentAdapter.DocumentViewHolder> {

    private final ArrayList<File> documentList;
    private final OnDocumentClickListener listener;

    public DocumentAdapter(ArrayList<File> documentList, OnDocumentClickListener listener) {
        this.documentList = documentList;
        this.listener = listener;
    }

    @NonNull
    @Override
    public DocumentViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(android.R.layout.simple_list_item_1, parent, false);
        return new DocumentViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull DocumentViewHolder holder, int position) {
        File document = documentList.get(position);
        holder.textView.setText(document.getName());
        holder.itemView.setOnClickListener(v -> listener.onDocumentClick(document));
    }

    @Override
    public int getItemCount() {
        return documentList.size();
    }

    public interface OnDocumentClickListener {
        void onDocumentClick(File file);
    }

    static class DocumentViewHolder extends RecyclerView.ViewHolder {
        TextView textView;

        public DocumentViewHolder(@NonNull View itemView) {
            super(itemView);
            textView = itemView.findViewById(android.R.id.text1);
        }
    }
}

i tried all solution from browsing stackoverflow questions and searching google and asking gemini and chatgpt

code is not working and not showing a list of documents files no code error shown and when i run app only output a toast message "Permission Denied".

i developed app can read all documents like pdf, and office PowerPoint, excel, word and the main activity i want to show a list of all documents available on device so user can open any document inside app and not only browsing files from storage i tried this code but not working and tried another multiple solutions in stackoverflow and other websites and nothing work at end. my code

mainactivity before on create

private static final int PDF_SELECTION_CODE = 200;
    private static final int PERMISSION_REQUEST_CODE = 100;
    private RecyclerView recyclerView;
    private DocumentAdapter documentAdapter;
    private ArrayList<File> documentList;

inside on create

recyclerView = findViewById(R.id.recyclerView);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
            loadDocuments();
        } else {
            loadDocuments();
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            // Scoped Storage
            loadDocumentsWithScopedStorage();
        } else {
            // Legacy Storage
            loadDocumentsWithScopedStorage();
        }

        loadDocumentsWithMediaStore();

after on create

private void getDocuments(@NonNull File dir) {
        File[] files = dir.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    getDocuments(file);
                } else if (file.getName().endsWith(".pdf") ||
                        file.getName().endsWith(".doc") ||
                        file.getName().endsWith(".docx") ||
                        file.getName().endsWith(".txt")) {
                    documentList.add(file);
                }
            }
        }
    }

    private void loadDocumentsWithScopedStorage() {
        documentList = new ArrayList<>();
        Uri collection = MediaStore.Files.getContentUri("external");

        String[] projection = {
                MediaStore.Files.FileColumns.DATA,
                MediaStore.Files.FileColumns.DISPLAY_NAME
        };

        // Filter for specific document types
        String selection = MediaStore.Files.FileColumns.MIME_TYPE + " IN (?, ?, ?, ?)";
        String[] selectionArgs = new String[]{
                "application/pdf",
                "application/msword",
                "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
                "text/plain"
        };

        Cursor cursor = getContentResolver().query(collection, projection, selection, selectionArgs, null);

        if (cursor != null) {
            int dataIndex = cursor.getColumnIndex(MediaStore.Files.FileColumns.DATA);

            while (cursor.moveToNext()) {
                String filePath = cursor.getString(dataIndex);
                File file = new File(filePath);
                documentList.add(file);
            }
            cursor.close();
        }

        documentAdapter = new DocumentAdapter(documentList, file -> {
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setDataAndType(android.net.Uri.fromFile(file), "*/*");
            startActivity(intent);
        });
        recyclerView.setAdapter(documentAdapter);
    }

    private void loadDocumentsWithMediaStore() {
        documentList = new ArrayList<>();
        Uri collection = MediaStore.Files.getContentUri("external");

        String[] projection = {
                MediaStore.Files.FileColumns.DATA,
                MediaStore.Files.FileColumns.DISPLAY_NAME
        };

        String selection = MediaStore.Files.FileColumns.MIME_TYPE + " IN (?, ?, ?, ?)";
        String[] selectionArgs = new String[]{
                "application/pdf",
                "application/msword",
                "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
                "text/plain"
        };

        try (Cursor cursor = getContentResolver().query(collection, projection, selection, selectionArgs, null)) {
            if (cursor != null) {
                int dataIndex = cursor.getColumnIndex(MediaStore.Files.FileColumns.DATA);

                while (cursor.moveToNext()) {
                    String filePath = cursor.getString(dataIndex);
                    File file = new File(filePath);
                    documentList.add(file);
                }
            }
        }

        documentAdapter = new DocumentAdapter(documentList, file -> {
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setDataAndType(android.net.Uri.fromFile(file), "*/*");
            startActivity(intent);
        });
        recyclerView.setAdapter(documentAdapter);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == PERMISSION_REQUEST_CODE) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                loadDocuments();
            } else {
                Toast.makeText(this, "Permission denied", Toast.LENGTH_SHORT).show();
            }
        }
    }

Document Adapter

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import java.io.File;
import java.util.ArrayList;

public class DocumentAdapter extends RecyclerView.Adapter<DocumentAdapter.DocumentViewHolder> {

    private final ArrayList<File> documentList;
    private final OnDocumentClickListener listener;

    public DocumentAdapter(ArrayList<File> documentList, OnDocumentClickListener listener) {
        this.documentList = documentList;
        this.listener = listener;
    }

    @NonNull
    @Override
    public DocumentViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(android.R.layout.simple_list_item_1, parent, false);
        return new DocumentViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull DocumentViewHolder holder, int position) {
        File document = documentList.get(position);
        holder.textView.setText(document.getName());
        holder.itemView.setOnClickListener(v -> listener.onDocumentClick(document));
    }

    @Override
    public int getItemCount() {
        return documentList.size();
    }

    public interface OnDocumentClickListener {
        void onDocumentClick(File file);
    }

    static class DocumentViewHolder extends RecyclerView.ViewHolder {
        TextView textView;

        public DocumentViewHolder(@NonNull View itemView) {
            super(itemView);
            textView = itemView.findViewById(android.R.id.text1);
        }
    }
}

i tried all solution from browsing stackoverflow questions and searching google and asking gemini and chatgpt

code is not working and not showing a list of documents files no code error shown and when i run app only output a toast message "Permission Denied".

Share Improve this question asked yesterday Progromatic WorldProgromatic World 791 silver badge8 bronze badges 1
  • 2 READ_EXTERNAL_STORAGE is deprecated and ignored on recent Android versions. developer.android.com/reference/android/… – Robert Commented yesterday
Add a comment  | 

3 Answers 3

Reset to default 1

Solution: Access All Documents with MANAGE_EXTERNAL_STORAGE Permission (Android 10 and higher)

- Add the MANAGE_EXTERNAL_STORAGE Permission in the Manifest:

In your AndroidManifest.xml, you need to declare the MANAGE_EXTERNAL_STORAGE permission to allow your app to request access to all files on the device:

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

- Request the MANAGE_EXTERNAL_STORAGE Permission at Runtime:

Starting from Android 10 (API 29), to access files outside of scoped storage, you need to request MANAGE_EXTERNAL_STORAGE permission at runtime. This is different from regular file access permissions.

Here's how you can check and request it:

private static final int MANAGE_EXTERNAL_STORAGE_REQUEST_CODE = 200;

// Check if we have the permission
private boolean isPermissionGranted() {
    return Environment.isExternalStorageManager();
}

// Request the permission
private void requestPermission() {
    if (!isPermissionGranted()) {
        Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
        startActivityForResult(intent, MANAGE_EXTERNAL_STORAGE_REQUEST_CODE);
    } else {
        loadDocuments(); // Once permission is granted, load documents
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == MANAGE_EXTERNAL_STORAGE_REQUEST_CODE) {
        if (isPermissionGranted()) {
            loadDocuments(); // Once permission is granted, load documents
        } else {
            Toast.makeText(this, "Permission Denied", Toast.LENGTH_SHORT).show();
        }
    }
}

The ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION intent opens the system settings where users can grant access to all files on the device. Once granted, your app will be able to access documents in directories beyond the scope of scoped storage.

- Load Documents After Permission is Granted:

Once the permission is granted, you can access all files on the device.

i am afraid you cannot achieve what you want,because google make changes on file system access permission from Android 10.your app can only access its own private folders and shared folders on device like Downloads,Document,DCIM,Pictures.to access other folders is not allowed any more,unless your app is specifically used for file management or a system app. even if the files in shared folders you can access must be type of media,other types are also forbidden.so you have to use the file browsing app in the system to read document on the device. your app cannot read all the documents on device. you can know more about the permission changes from here google android developer

Mainfest XML

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

MainActivity JAVA

    @SuppressLint("NewApi")
        private boolean isPermissionGranted() {
            return Environment.isExternalStorageManager();
        }
        private void requestPermission() {
            if (!isPermissionGranted()) {
                try {
                    Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
                    intent.setData(Uri.parse("package:" + getApplicationContext().getPackageName()));
                    startActivity(intent);
                } catch (ActivityNotFoundException e) {
                    Log.e("MainActivity", "Activity not found", e);
                }
            } else {
                loadDocuments();
            }
        }
@Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == PDF_SELECTION_CODE && resultCode == RESULT_OK && data != null) {
            Uri selectedFileUri = data.getData();
            startMuPDFActivity(selectedFileUri);
        }else{
            Uri selectedFileUri = data.getData();
            startMuPDFActivity(selectedFileUri);
        }
        if (requestCode == MANAGE_EXTERNAL_STORAGE_REQUEST_CODE) {
            if (isPermissionGranted()) {
                loadDocuments(); // Once permission is granted, load documents
            } else {
                Toast.makeText(this, "Permission Denied", Toast.LENGTH_SHORT).show();
            }
        }
    }

This code is working for me.