我正在使用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;
}
答案 0 :(得分:6)
我对图库图片或下载文档没有任何问题
您将在许多设备上使用。
但是当我从谷歌驱动器中选择一个文件时,我无法获得路径
没有路径。 ACTION_GET_CONTENT
不允许用户选择文件。它允许用户选择一段内容。该内容可能是本地文件。该内容也可能是:
您有两个主要选择。如果仅想要文件,请使用a third-party file chooser library替换问题中的所有代码。
或者,如果您仍想使用ACTION_GET_CONTENT
或ACTION_OPEN_DOCUMENT
,则可以Uri
中的data.getData()
获取onActivityResult()
并执行两项操作事情:
首先,使用DocumentFile.fromSingleUri()
获取指向DocumentFile
的{{1}}对象。您可以在Uri
上致电getName()
以获取内容的“显示名称”,这应该是用户可以识别的内容。
然后,使用DocumentFile
和ContentResolver
来获取内容本身,类似于使用openInputStream()
获取文件中的字节的方式。
答案 1 :(得分:5)
我也遇到了同样的问题,发现当我们从谷歌驱动器中选择图像时,它的uri就像下面一样
Array
(
[0] => Array
(
[Loc] => 124
[0] => 124
[34] => 1
[35] => 1
[38] => 2
[39] => 2
[40] => 1
[41] => 1
)
[1] => Array
(
[Loc] => 424
[0] => 424
[34] => 1
[35] => 1
[38] => 0
[39] => 0
[40] => 0
[41] => 0
)
[2] => Array
(
[Loc] => 1512
[0] => 1512
[34] => 1
[35] => 1
[38] => 0
[39] => 0
[40] => 0
[41] => 0
)
[3] => Array
(
[Loc] => 1612
[0] => 1612
[34] => 0
[35] => 0
[38] => 1
[39] => 1
[40] => 2
[41] => 2
)
[4] => Array
(
[Loc] => 1711
[0] => 1711
[34] => 0
[35] => 0
[38] => 1
[39] => 1
[40] => 1
[41] => 1
)
)
我们无法直接获取文件的路径,因为它不在我们的设备中。所以我们首先将文件下载到某个目的地然后我们可以使用该路径来完成我们的工作。以下是相同
的代码com.google.android.apps.docs.storage
现在您的文件已保存在所需的目标路径中,您可以使用它。
答案 2 :(得分:2)
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();
}