web-dev-qa-db-fra.com

obtenir le chemin depuis l'URI de Google Drive

J'utilise Android sélection de fichiers et sélection de fichiers à partir du stockage de l'application (images, vidéos, documents). J'ai une fonction "getPath". Je reçois un chemin depuis uri. Je n'ai aucun problème avec la galerie images ou télécharger des documents. Mais lorsque je sélectionne un fichier sur google drive, je ne peux pas obtenir le chemin d'accès. 3D12 "Pouvez-vous m'aider à ce sujet?

C'est aussi ma fonction "getPath".

public static String getPath(final Context context, final Uri uri) {

    // check here to KitKat or new version
    final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KitKat;

    // DocumentProvider
    if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {

        // ExternalStorageProvider
        if (isExternalStorageDocument(uri)) {
            final String docId = DocumentsContract.getDocumentId(uri);
            final String[] split = docId.split(":");
            final String type = split[0];

            if ("primary".equalsIgnoreCase(type)) {
                return Environment.getExternalStorageDirectory() + "/"
                        + split[1];
            }
        }
        // DownloadsProvider
        else if (isDownloadsDocument(uri)) {

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

            return getDataColumn(context, contentUri, null, null);
        }
        // MediaProvider
        else if (isMediaDocument(uri)) {
            final String docId = DocumentsContract.getDocumentId(uri);
            final String[] split = docId.split(":");
            final String type = split[0];

            Uri contentUri = null;
            if ("image".equals(type)) {
                contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
            } else if ("video".equals(type)) {
                contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
            } else if ("audio".equals(type)) {
                contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
            }

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

            return getDataColumn(context, contentUri, selection,
                    selectionArgs);
        }
        else if(isGoogleDriveUri(uri)){
                //Get google drive path here

        }
    }
    // MediaStore (and general)
    else if ("content".equalsIgnoreCase(uri.getScheme())) {

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

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

    return nopath;
}

public static String iStreamToString(InputStream is1)
{
    BufferedReader rd = new BufferedReader(new InputStreamReader(is1), 4096);
    String line;
    StringBuilder sb =  new StringBuilder();
    try {
        while ((line = rd.readLine()) != null) {
            sb.append(line);
        }
        rd.close();

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    String contentOfMyInputStream = sb.toString();
    return contentOfMyInputStream;
}
9

Je n'ai aucun problème avec les images de la galerie ou les documents à télécharger

Vous le ferez sur de nombreux appareils.

Mais quand je sélectionne un fichier de Google Drive, je ne peux pas obtenir de chemin

Il n'y a pas de chemin. ACTION_GET_CONTENT Ne permet pas à l'utilisateur de choisir un fichier. Il permet à l'utilisateur de choisir un élément de contenu. Ce contenu peut être un fichier local. Ce contenu pourrait également être:

  • Quelque chose sur un serveur de fichiers sur le résea
  • Quelque chose dans un service de stockage en nuage, tel que Google Drive, et qui n'est donc pas sur l'appareil pour le moment
  • Quelque chose dans n volume crypté
  • Quelque chose qui est un fichier, mais qui n'est pas un fichier auquel vous pouvez accéder directement, comme depuis stockage interne d'une autre application
  • Etc

Vous avez deux options principales. Si vous seulement voulez des fichiers , utilisez alors n troisième -party file chooser library pour remplacer tout le code de votre question.

Ou, si vous souhaitez toujours utiliser ACTION_GET_CONTENT Ou ACTION_OPEN_DOCUMENT, Vous pouvez prendre le Uri que vous obtenez de data.getData() dans onActivityResult() et faites deux choses avec:

  • Tout d'abord, utilisez DocumentFile.fromSingleUri() pour obtenir un objet DocumentFile pointant vers cet Uri. Vous pouvez appeler getName() sur le DocumentFile pour obtenir un "nom d'affichage" pour le contenu, qui devrait être quelque chose que l'utilisateur reconnaîtra.

  • Ensuite, utilisez un ContentResolver et openInputStream() pour obtenir le contenu lui-même, de la même manière que vous pourriez utiliser un FileInputStream pour obtenir les octets d'un fichier.

5
CommonsWare

J'étais également coincé avec le même problème et j'ai constaté que lorsque nous choisissons l'image de Google Drive, son uri est comme ci-dessous

com.google.Android.apps.docs.storage

et nous ne pouvons pas obtenir directement le chemin du fichier car il n'est pas dans notre appareil. Nous téléchargeons donc d'abord le fichier vers une certaine destination, puis nous pouvons utiliser ce chemin pour faire notre travail. Voici le code pour le même

FileOutputStream fos = null;
    try {
         fos = new FileOutputStream(getDestinationFilePath());
         try (BufferedOutputStream out = new BufferedOutputStream(fos); 
         InputStream in = mContext.getContentResolver().openInputStream(uri)) 
           {
            byte[] buffer = new byte[8192];
            int len = 0;

            while ((len = in.read(buffer)) >= 0) {
                  out.write(buffer, 0, len);
                 }

             out.flush();
            } finally {
                       fos.getFD().sync();
                      }

                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }

            File file = new File(destinationFilePath);
            if (Integer.parseInt(String.valueOf(file.length() / 1024)) > 1024) {
            InputStream imageStream = null;



            try {
                 imageStream = mContext.getContentResolver().openInputStream(uri);
                        } catch (FileNotFoundException e) {
                            e.printStackTrace();
                        }

maintenant, votre fichier est enregistré sur le chemin de destination souhaité et vous pouvez l'utiliser.

4
Ankit Shukla
Get file path from Google Drive we can easily access by Using File Provider by using following steps Code is working fine.

1) Add provider path in AndroidManifest file inside Applcation Tag.
<application
        Android:allowBackup="true"
        Android:icon="@mipmap/ic_launcher"
        Android:label="@string/app_name"
        Android:roundIcon="@mipmap/ic_launcher_round"
        Android:supportsRtl="true"
        Android:theme="@style/AppTheme">
        <activity Android:name="com.satya.filemangerdemo.activity.MainActivity">
            <intent-filter>
                <action Android:name="Android.intent.action.MAIN" />

                <category Android:name="Android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <provider
            Android:name="Android.support.v4.content.FileProvider"
            Android:authorities="${applicationId}.provider"
            Android:exported="false"
            Android:grantUriPermissions="true">
            <meta-data
                Android:name="Android.support.FILE_PROVIDER_PATHS"
                Android:resource="@xml/provider_paths"/>
        </provider>
    </application>


2) provider_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <cache-path
        name="my_cache"
        path="." />
    <cache-path
        name="cache"
        path="." />
    <external-cache-path
        name="external_cache"
        path="." />
    <files-path
        name="files"
        path="." />
</paths>

3)FileUtils.Java

public class FileUtils {
    private static Uri contentUri = null;
 @SuppressLint("NewApi")
    public static String getPath(final Context context, final Uri uri) {
        // check here to KitKat or new version
        final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KitKat;
        // DocumentProvider
        if (isKitKat && DocumentsContract.isDocumentUri(context, uri))
          {
            / MediaProvider
             if (isMediaDocument(uri)) {
                 if (isGoogleDriveUri(uri)) {
                return getDriveFilePath(uri, context);
            }


          }
      }

4) isGoogleDriveUri method 

  private static boolean isGoogleDriveUri(Uri uri) {
        return "com.google.Android.apps.docs.storage".equals(uri.getAuthority()) || "com.google.Android.apps.docs.storage.legacy".equals(uri.getAuthority());
    }

5)getDriveFilePath method 
 private static String getDriveFilePath(Uri uri, Context context) {
        Uri returnUri = uri;
        Cursor returnCursor = context.getContentResolver().query(returnUri, null, null, null, null);
        /*
         * Get the column indexes of the data in the Cursor,
         *     * move to the first row in the Cursor, get the data,
         *     * and display it.
         * */
        int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
        int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE);
        returnCursor.moveToFirst();
        String name = (returnCursor.getString(nameIndex));
        String size = (Long.toString(returnCursor.getLong(sizeIndex)));
        File file = new File(context.getCacheDir(), name);
        try {
            InputStream inputStream = context.getContentResolver().openInputStream(uri);
            FileOutputStream outputStream = new FileOutputStream(file);
            int read = 0;
            int maxBufferSize = 1 * 1024 * 1024;
            int bytesAvailable = inputStream.available();

            //int bufferSize = 1024;
            int bufferSize = Math.min(bytesAvailable, maxBufferSize);

            final byte[] buffers = new byte[bufferSize];
            while ((read = inputStream.read(buffers)) != -1) {
                outputStream.write(buffers, 0, read);
            }
            Log.e("File Size", "Size " + file.length());
            inputStream.close();
            outputStream.close();
            Log.e("File Path", "Path " + file.getPath());
            Log.e("File Size", "Size " + file.length());
        } catch (Exception e) {
            Log.e("Exception", e.getMessage());
        }
        return file.getPath();
    }
0
satyawan hajare