3

I have targeted Android API level 30 and tried to create multiple file descriptors for a single file from the URI from the default file picker which looks like this.

content://com.android.externalstorage.documents/document/E8A6-89C4%3AMovies%2FTestFile.mp4 

content://com.android.externalstorage.documents/document/primary%3ATestFile.mp4

I am using the below code to create 10 threads to asynchronously access a file with ParcelFileDescriptors.

public class TestActivity extends AppCompatActivity {

    public static final String TAG = "TEST_LOG";
    
    private Button pickFileBtn;
    final int VIDEO_REQUEST_CODE = 111;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) {
        super.onCreate(savedInstanceState, persistentState);
        setContentView(R.layout.test_activity);
        pickFileBtn = findViewById(R.id.pick_file);
        pickFileBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                pickFile();        
            }
        });
    }

    private void pickFile() {
        Intent intent = new Intent();
        intent.setType("video/*");
        intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        startActivityForResult(intent, VIDEO_REQUEST_CODE);
    }

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

        if (requestCode == VIDEO_REQUEST_CODE) {
            if (resultCode == RESULT_OK) {
                loadFrame(data.getData());
            }
        }
    }

    void loadFrame(Uri uri) {
        for (int i = 0; i < 10; i++) {
            new Thread(new CustomRunnable(uri)).start();
        }
    }
}


class CustomRunnable implements Runnable {
    private Uri uri;

    public CustomRunnable(Uri uri) {
        this.uri = uri;
    }

    @Override
    public void run() {
        try {
            ParcelFileDescriptor descriptor = null;
            try {
                descriptor = CustomApplication.appContext.getContentResolver().openFileDescriptor(uri, "r");
                // Working with the descriptor here.
            } catch (Exception e) {
                Log.e(TestActivity.TAG, String.format("Failed to obtain parcelFileDescriptor for %s.%s", uri.toString(), e.getMessage()));
            } finally {
                if (descriptor != null)
                    descriptor.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Failed to obtain r parcelFileDescriptor for content://com.android.externalstorage.documents/document/primary%3ATestFile.mp4.Permission Denial: reading com.android.externalstorage.ExternalStorageProvider uri content://com.android.externalstorage.documents/document/primary%3ATestFile.mp4 from pid=6190, uid=12283 requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs

This can create around 5 descriptors and throws File Not Found Exception for the rest. But, It can successfully create all the required descriptors when I use URI from the media store. And the media store URI looks like this.

content://media/external/video/media/268019

I have tried to reuse the 5 descriptors but when I try to read the files using them, I get an error saying EBML header parsing failed

I have also tried to obtain access to a specific folder using Intent.ACTION_OPEN_DOCUMENT_TREE and then picking a file, but the result is the same, that it only opens 5 descriptors.

Why do opening descriptors from the default file picker only create 5 descriptors and why I can not reuse them.

  • 1
    `openMode` Please put the used value in your post. – blackapps Dec 08 '21 at 08:44
  • 1
    To begin with the bginning: `access_request.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); access_request.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);`Better remove these lines as they do nothing and only confuse other people thinking they are needed. Also for `intent_load_file` remove them. – blackapps Dec 08 '21 at 08:53
  • `And the code I am using to create file descriptor` It is unclear when you call that code. – blackapps Dec 08 '21 at 08:54
  • `I have also tried allowing access to a specific folder by`. No, not allowing but obtaining. You can not allow access. You should be glad if access is granted to you. Glad if you obtain it. – blackapps Dec 08 '21 at 08:57
  • 1
    Ok. But on `It is unclear when you call that code.` you did not react. – blackapps Dec 08 '21 at 12:31
  • Android version of used device? – blackapps Dec 08 '21 at 13:20
  • 1
    `have tried to reuse the 5 descriptors` What do you mean with that? – blackapps Dec 08 '21 at 13:21
  • @blackapps Android version 10. – Md. Mahfujur Rahman Arif Dec 08 '21 at 14:46
  • You did not react on all my remarks... – blackapps Dec 08 '21 at 14:49
  • @blackapps I needed to access a single file asynchronously from multiple threads and this is why I needed multiple file descriptors. `have tried to reuse the 5 descriptors` What I tried to mean by this is that I tried to reuse the 5 successfully created descriptors from different threads. And two threads never tried to access the same descriptor at the same time. – Md. Mahfujur Rahman Arif Dec 08 '21 at 14:55
  • But on `It is unclear when you call that code.` you still did not react. – blackapps Dec 08 '21 at 16:45
  • @blackapps could you please help me with the problem? – Md. Mahfujur Rahman Arif Dec 09 '21 at 02:43
  • @blackapps I don't understand what you mean by `You still did not react`. Please tell me what to do. – Md. Mahfujur Rahman Arif Dec 09 '21 at 04:57
  • When do you call that code? And from where!? – blackapps Dec 09 '21 at 06:35
  • Ok. Thanks. But the question where and when you call that function is still not answered. Somewhere in your code you will call that function like `loadFrame(url);`. My question since yesterday is: Where do you have that call? When is loadFrame(url) called? – blackapps Dec 09 '21 at 09:39
  • @blackapps is it okay now? – Md. Mahfujur Rahman Arif Dec 12 '21 at 05:39
  • So you call it from onActivityResult. Finally. I further can only say that i tested opening file descripters on several phones with different Android versions. For all tipes of content schemes i could open twenty descriotors. Thats why i want to know what kind of device you use. – blackapps Dec 12 '21 at 07:28
  • @blackapps I don't have any problem with this type URI `content://media/external/video/media/268019` but the problem arises for this type of URI `content://com.android.externalstorage.documents/document/E8A6-89C4%3AMovies%2FTestFile.mp4` – Md. Mahfujur Rahman Arif Dec 12 '21 at 12:37
  • I know. I can open 20 at all kind of devices i told you. – blackapps Dec 12 '21 at 16:56

0 Answers0