skip to Main Content

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".

2

Answers


  1. 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

    Login or Signup to reply.
  2. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search