web-dev-qa-db-fra.com

Comment obtenir le chemin du fichier depuis un URI pointant vers un PDF document?

Actuellement, mon code ouvre la vue des téléchargements par défaut et ne me montre que les PDF que j'ai téléchargés. Je choisis un fichier PDF et je reçois ceci:

content: //com.Android.providers.downloads.documents/document/1171

Je veux avoir ceci:

/storage/emulated/0/Download/ch22Databases.pdf

Ma question est comment puis-je faire cela dans Android?

Mon code:

public void PDF() {
    PDF = (Button) findViewById(R.id.FindPDFBtn);//Finds the button in design and put it into a button variable.
    PDF.setOnClickListener(//Listens for a button click.
        new View.OnClickListener() {//Creates a new click listener.
            @Override
            public void onClick(View v) {//does what ever code is in here when the button is clicked
                Intent intent = new Intent();
                intent.setType("application/pdf");
                intent.setAction(Intent.ACTION_GET_CONTENT);
                startActivityForResult(Intent.createChooser(intent, "Select a PDF "), SELECT_PDF);
            }
        }
    );
}

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

    //PDF
    if (resultCode == RESULT_OK) {
        if (requestCode == SELECT_PDF) {
            Uri selectedUri_PDF = data.getData();
            SelectedPDF = getPDFPath(selectedUri_PDF);
        }
    }
}

public String getPDFPath(Uri uri) {
    String[] projection = { MediaStore.Images.Media.DATA };
    Cursor cursor = getContentResolver().query(uri, projection, null, null, null);
    int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
    cursor.moveToFirst();
    return cursor.getString(column_index);
}
9
Lazar Kukolj

Ajoutez cet extrait ci-dessous dans votre méthode getPDFPath:

public String getPDFPath(Uri uri){

     final String id = DocumentsContract.getDocumentId(uri);
     final Uri contentUri = ContentUris.withAppendedId(
                    Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));

     String[] projection = { MediaStore.Images.Media.DATA };
     Cursor cursor = getContentResolver().query(contentUri, projection, null, null, null);
     int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
     cursor.moveToFirst();
     return cursor.getString(column_index);
}

Dans votre cas, ce code concerne spécifiquement les documents de DownloadProvider, pour une vérification ultérieure de la mise en œuvre Réponse de Paul Burke . Personnellement, j'utilise sa bibliothèque aFileChooser pour éviter ce genre de problème.

4
Gueorgui Obregon

Voici deux solutions

1) Vous pouvez utiliser le code ci-dessous. Il peut gérer n'importe quel type de fichier et de n'importe quel dossier.

private String getPath(final Uri uri) {

    final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KitKat;
    if(isKitKat) {
        // MediaStore (and general)
        return getForApi19(uri);
    } else if ("content".equalsIgnoreCase(uri.getScheme())) {

        // Return the remote address
        if (isGooglePhotosUri(uri))
            return uri.getLastPathSegment();

        return getDataColumn(uri, null, null);
    }
    // File
    else if ("file".equalsIgnoreCase(uri.getScheme())) {
        return uri.getPath();
    }

    return null;
}

@TargetApi(19)
private String getForApi19(Uri uri) {
    Log.e(tag, "+++ API 19 URI :: " + uri);
    if (DocumentsContract.isDocumentUri(this, uri)) {
        Log.e(tag, "+++ Document URI");
        // ExternalStorageProvider
        if (isExternalStorageDocument(uri)) {
            Log.e(tag, "+++ External Document URI");
            final String docId = DocumentsContract.getDocumentId(uri);
            final String[] split = docId.split(":");
            final String type = split[0];

            if ("primary".equalsIgnoreCase(type)) {
                Log.e(tag, "+++ Primary External Document URI");
                return Environment.getExternalStorageDirectory() + "/" + split[1];
            }

            // TODO handle non-primary volumes
        }
        // DownloadsProvider
        else if (isDownloadsDocument(uri)) {
            Log.e(tag, "+++ Downloads External Document URI");
            final String id = DocumentsContract.getDocumentId(uri);
            final Uri contentUri = ContentUris.withAppendedId(
                    Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));

            return getDataColumn(contentUri, null, null);
        }
        // MediaProvider
        else if (isMediaDocument(uri)) {
            Log.e(tag, "+++ Media Document URI");
            final String docId = DocumentsContract.getDocumentId(uri);
            final String[] split = docId.split(":");
            final String type = split[0];

            Uri contentUri = null;
            if ("image".equals(type)) {
                Log.e(tag, "+++ Image Media Document URI");
                contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
            } else if ("video".equals(type)) {
                Log.e(tag, "+++ Video Media Document URI");
                contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
            } else if ("audio".equals(type)) {
                Log.e(tag, "+++ Audio Media Document URI");
                contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
            }

            final String selection = "_id=?";
            final String[] selectionArgs = new String[] {
                    split[1]
            };

            return getDataColumn(contentUri, selection, selectionArgs);
        }
    } else if ("content".equalsIgnoreCase(uri.getScheme())) {
        Log.e(tag, "+++ No DOCUMENT URI :: CONTENT ");

        // Return the remote address
        if (isGooglePhotosUri(uri))
            return uri.getLastPathSegment();

        return getDataColumn(uri, null, null);
    }
    // File
    else if ("file".equalsIgnoreCase(uri.getScheme())) {
        Log.e(tag, "+++ No DOCUMENT URI :: FILE ");
        return uri.getPath();
    }
    return null;
}

/**
 * Get the value of the data column for this Uri. This is useful for
 * MediaStore Uris, and other file-based ContentProviders.
 *
 * @param uri The Uri to query.
 * @param selection (Optional) Filter used in the query.
 * @param selectionArgs (Optional) Selection arguments used in the query.
 * @return The value of the _data column, which is typically a file path.
 */
public String getDataColumn(Uri uri, String selection,
                            String[] selectionArgs) {

    Cursor cursor = null;
    final String column = "_data";
    final String[] projection = {
            column
    };

    try {
        cursor = getContentResolver().query(uri, projection, selection, selectionArgs,
                null);
        if (cursor != null && cursor.moveToFirst()) {
            final int index = cursor.getColumnIndexOrThrow(column);
            return cursor.getString(index);
        }
    } finally {
        if (cursor != null)
            cursor.close();
    }
    return null;
}


/**
 * @param uri The Uri to check.
 * @return Whether the Uri authority is ExternalStorageProvider.
 */
public static boolean isExternalStorageDocument(Uri uri) {
    return "com.Android.externalstorage.documents".equals(uri.getAuthority());
}

/**
 * @param uri The Uri to check.
 * @return Whether the Uri authority is DownloadsProvider.
 */
public static boolean isDownloadsDocument(Uri uri) {
    return "com.Android.providers.downloads.documents".equals(uri.getAuthority());
}

/**
 * @param uri The Uri to check.
 * @return Whether the Uri authority is MediaProvider.
 */
public static boolean isMediaDocument(Uri uri) {
    return "com.Android.providers.media.documents".equals(uri.getAuthority());
}

/**
 * @param uri The Uri to check.
 * @return Whether the Uri authority is Google Photos.
 */
public static boolean isGooglePhotosUri(Uri uri) {
    return "com.google.Android.apps.photos.content".equals(uri.getAuthority());
}

C'est la meilleure solution pour parcourir les fichiers.

J'espère que ça va aider.

Autrement

2) Une autre solution que j'ai trouvée est

Ajouter une dépendance dans build.gradle de Module: app

compile 'in.gauriinfotech:commons:1.0.8'

Ensuite, dans votre code, utilisez

String fullPath = Commons.getPath(uri, context);

Assurez-vous que vous avez ajouté l'autorisation ci-dessous dans Manifest.xml

<uses-permission Android:name="Android.permission.READ_EXTERNAL_STORAGE" />
1
ELITE

Uri uri = intent.getData ();

                String uriString = uri.toString();

                File myFile = new File(uriString);

                final String path = myFile.getAbsolutePath();

                String displayName = null;

                if (uriString.startsWith("content://")) {
                    Cursor cursor = null;
                    try {
                        cursor = getActivity().getContentResolver().query(uri, null, null, null, null);
                        if (cursor != null && cursor.moveToFirst()) {
                            displayName = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
                            tvFile.setVisibility ( View.VISIBLE );
                            tvFile.setText ( displayName );

                            final String finalDisplayName = displayName;
                            tvFile.setOnClickListener ( new View.OnClickListener () {
                                @Override
                                public void onClick(View v) {
                                    File dir = Environment.getExternalStorageDirectory();
                                    File yourFile = new File(dir, path+ finalDisplayName );

                                    Toast.makeText ( getActivity (),"hiiiii"+yourFile,Toast.LENGTH_SHORT ).show ();
                                }
                            } );
                            //Toast.makeText ( getActivity (),"hii"+displayName,Toast.LENGTH_LONG ).show ();
                        }
                    } finally {
                        cursor.close();
                    }
                } else if (uriString.startsWith("file://")) {
                    displayName = myFile.getName();
                   // Toast.makeText ( getActivity (),"hii"+displayName,Toast.LENGTH_LONG ).show ();
                }
1
bijal

Ma question est comment puis-je faire cela dans Android?

Vous pas. ACTION_GET_CONTENT a peu à voir avec les fichiers. 

Si vous avez absolument besoin d'un fichier, utilisez une bibliothèque de sélecteur de fichiers , et non pas ACTION_GET_CONTENT.

Si vous souhaitez utiliser ACTION_GET_CONTENT, arrêtez d’essayer d’obtenir le chemin du système de fichiers. Utilisez ContentResolver et openInputStream() pour lire le contenu du contenu, si la Uri a un schéma file, content ou Android.resource. Utilisez une API client HTTP si la variable Uri a un schéma http ou https

1
CommonsWare