Androidファイル選択とアプリストレージ(画像、動画、ドキュメント)からのファイルの選択)を使用しています。「getPath」関数があります。uriからパスを取得しています。ギャラリーには問題ありません。画像またはドキュメントをダウンロードします。しかし、Googleドライブからファイルを選択すると、パスを取得できません。これは、Googleドライブの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;
}
ギャラリーの画像やドキュメントのダウンロードに問題はありません
あなたは、多くのデバイスで。
しかし、Googleドライブからファイルを選択すると、パスを取得できません
パスはありません。 _ACTION_GET_CONTENT
_では、ユーザーはファイルを選択できません。これにより、ユーザーはコンテンツの一部を選択できます。そのコンテンツmightはローカルファイルである可能性があります。そのコンテンツは次のようになることもあります。
2つの主なオプションがあります。 onlyがfilesを必要とする場合は、- a third -party file chooser library 質問のすべてのコードを置き換えます。
または、_ACTION_GET_CONTENT
_または_ACTION_OPEN_DOCUMENT
_を引き続き使用する場合は、data.getData()
から取得したUri
をonActivityResult()
で取得し、それで2つのことを行います。
まず、DocumentFile.fromSingleUri()
を使用して、そのDocumentFile
を指すUri
オブジェクトを取得します。 DocumentFile
でgetName()
を呼び出して、コンテンツの「表示名」を取得できます。これは、ユーザーが認識できるものでなければなりません。
次に、ContentResolver
を使用してファイル自体のバイト数を取得するのと同じように、FileInputStream
とopenInputStream()
を使用してコンテンツ自体を取得します。
私も同じ問題で立ち往生しており、Googleドライブから画像を選択すると、そのURIは以下のようになります
com.google.Android.apps.docs.storage
デバイスにないため、ファイルのパスを直接取得できません。そのため、最初に特定の宛先にファイルをダウンロードしてから、そのパスを使用して作業を行うことができます。以下は同じコードです
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();
}
これで、ファイルが目的の宛先パスに保存され、使用できるようになります。
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();
}