I\'m using Android file selection and selecting files from app storage (images, videos, documents). I have an function \"getPath\" . Im getting path from uri. I have no problem
I was also stuck with the same issue and found that when we choose image from google drive its uri is like below
com.google.android.apps.docs.storage
and we cant directly get the path of file as it is not in our device. So we first download the file to a certain destination and then we can use that path to do our work. Below is the code for the same
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();
}
now your file is saved at the desired destination path and you can use it.
I have no problem with gallery images or download documents
You will, on many devices.
But when i select a file from google drive i cant get path
There is no path. ACTION_GET_CONTENT
does not allow the user to choose a file. It allows the user to choose a piece of content. That content might be a local file. That content might also be:
You have two main options. If you only want files, then use a third-party file chooser library to replace all of the code in your question.
Or, if you still want to use ACTION_GET_CONTENT
or ACTION_OPEN_DOCUMENT
, you can take the Uri
that you get from data.getData()
in onActivityResult()
and do two things with it:
First, use DocumentFile.fromSingleUri()
to get a DocumentFile
object pointing to that Uri
. You can call getName()
on the DocumentFile
to get a "display name" for the content, which should be something that the user will recognize.
Then, use a ContentResolver
and openInputStream()
to get at the content itself, similar to how you might use a FileInputStream
to get at the bytes in a file.
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();
}