Cannot set the initial location of documents navigator using Storage Access Framework (SAF)
Asked Answered
H

2

13

The documentation says "Callers can set a document URI through EXTRA_INITIAL_URI to indicate the initial location of documents navigator."

But it won't resolve EXTRA_INITIAL_URI here. I tried setting the constant given for this as shown in the comment (EXTRA_INITIAL_URI = "android.provider.extra.INITIAL_URI"), but that does not work. How do I get it to resolve?

package com.ship.saftwo;
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import java.io.File;

public class MainActivity extends AppCompatActivity{
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = (Button) findViewById(R.id.button1);
        button.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {navigateToAppDirectory();}});}

    private static final int READ_REQUEST_CODE = 42;
    // adding this does not help: public static final String EXTRA_INITIAL_URI = "android.provider.extra.INITIAL_URI";

    public void navigateToAppDirectory() {
        Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
        Uri uri = Uri.parse(Environment.getExternalStorageDirectory().getPath() + File.separator + getResources().getString(R.string.app_name) + File.separator);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("*/*");
        intent.putExtra(Intent.EXTRA_INITIAL_URI, uri);
        //error message: Cannot resolve symbol 'EXTRA_INITIAL_URI'
        startActivityForResult(intent, READ_REQUEST_CODE);
    }
}
Hipbone answered 22/5, 2018 at 5:48 Comment(4)
Did you find the solution ??Steady
Did you find the solution ? If yes, please share it.Semiprofessional
@Steady https://mcmap.net/q/905135/-android-11-action_open_document_tree-set-initial-uri-to-the-documents-folder-duplicateHett
This might help you - https://mcmap.net/q/905135/-android-11-action_open_document_tree-set-initial-uri-to-the-documents-folder-duplicateHett
A
21

From DocumentsContract.EXTRA_INITIAL_URI:

Location should specify a document URI or a tree URI with document ID. If this URI identifies a non-directory, document navigator will attempt to use the parent of the document as the initial location.

As far as I'm aware

  • You cannot specify a starting location using an arbitrary URI, e.g. Uri.fromFile, it needs to originate from a DocumentsProvider
  • You cannot specify a starting location on API 25 and below

Assuming uri was retrieved from Intent.ACTION_OPEN_DOCUMENT_TREE:

DocumentFile file = DocumentFile.fromTreeUri(context, uri);
intent.putExtra(EXTRA_INITIAL_URI, file.getUri());
Amann answered 8/1, 2019 at 20:9 Comment(4)
how did you know that you cannot use an arbitrary uri and it had to originate from DocumentsProvider?Cusco
There is no need to use a DocumentFile, uri = DocumentsContract.buildDocumentUriUsingTree(uri, DocumentsContract.getTreeDocumentId(uri))Withdrawn
can you please add the code how exactly we can get the Uri?Pate
Uri uri = Uri.parse("content://com.android.externalstorage.documents/tree/primary%3ADocuments");Theola
P
1

I was able to set it like this :

    private fun requestUri() {
    val intent = Intent(Intent.ACTION_CREATE_DOCUMENT)
    intent.addCategory(Intent.CATEGORY_OPENABLE)
        .setType("application/text")
        .putExtra(Intent.EXTRA_TITLE, "DEST_FILE_NAME")
        .putExtra(DocumentsContract.EXTRA_INITIAL_URI, Environment.DIRECTORY_DOCUMENTS)
    requestUri.launch(intent) // my start activity for result logic 
}

private var requestUri = registerForActivityResult(StartActivityForResult()) { result ->
    if (result != null && result.resultCode == Activity.RESULT_OK) {
        result.data?.let { intent ->
            intent.data?.let { fileUri ->
               // u have a valid uri now 
            } ?: run {
               // show some error Ui
            }
        }
    }
}

in my app i can set DocumentsContract.EXTRA_INITIAL_URI to something like :

  • Environment.DIRECTORY_DOCUMENTS
  • Environment.DIRECTORY_DOWNLOADS

may this help some one :)

Pochard answered 1/6, 2021 at 9:2 Comment(2)
I've tried this solution but it doesn't work on Android Emulator API 30 Pixel_3a. It cannot set the initial location (folder). It also show ClassCastException in log: W/Bundle: Attempt to cast generated internal exception: java.lang.ClassCastException: java.lang.String cannot be cast to android.os.Parcelable. Environment.DIRECTORY_DOCUMENTS is a String. It may not be used as a URI (Parcelable)Promiscuity
Doesn't work on real device (Android 11) or emulator (Android 13). It just opens the last chosen path.Expansile

© 2022 - 2024 — McMap. All rights reserved.