从Google云端硬盘URI获取路径

Gök*_*eci 8 android uri filepath google-drive-android-api

我正在使用Android文件选择并从应用程序存储(图像,视频,文档)中选择文件.我有一个函数"getPath".我从uri得到路径.我对图库图像或下载文档没有任何问题.但是当我从谷歌驱动器中选择一个文件时,我无法获得路径.这是google drive uri"content://com.google.android.apps.docs.storage/document/acc%3D25%3Bdoc%3D12"你能帮我解决一下吗?

这也是我的"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;
}
Run Code Online (Sandbox Code Playgroud)

Com*_*are 7

我对图库图像或下载文档没有任何问题

你会在许多设备上.

但是当我从谷歌驱动器中选择一个文件时,我无法获得路径

没有路径.ACTION_GET_CONTENT不允许用户选择文件.它允许用户选择一段内容.该内容可能是本地文件.该内容也可能是:

您有两个主要选择.如果您需要文件,请使用第三方文件选择器库替换问题中的所有代码.

或者,如果您仍然想要使用ACTION_GET_CONTENT或者ACTION_OPEN_DOCUMENT,您可以从中Uri获取data.getData(),onActivityResult()并使用它做两件事:

  • 首先,用于DocumentFile.fromSingleUri()获取DocumentFile指向该对象的对象Uri.你可以叫getName()DocumentFile得到一个"显示名称"的内容,这应该是用户将认识.

  • 然后,使用ContentResolveropenInputStream()在内容本身,类似于如何使用一个获得FileInputStream获得在一个文件中的字节数.

  • @ShwetaChauhan:读取字节。然后,对那些字节进行处理。什么是“做什么”在很大程度上取决于内容和应用程序的功能。 (2认同)

Ank*_*kla 5

我也遇到了同样的问题,发现当我们从Google驱动器中选择图片时,其uri如下所示

com.google.android.apps.docs.storage
Run Code Online (Sandbox Code Playgroud)

我们无法直接获取文件路径,因为它不在我们的设备中。因此,我们首先将文件下载到某个目标位置,然后可以使用该路径进行工作。下面是相同的代码

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();
                        }
Run Code Online (Sandbox Code Playgroud)

现在,您的文件将保存在所需的目标路径中,您可以使用它了。


sat*_*are 5

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();
    }
Run Code Online (Sandbox Code Playgroud)