android自定义minitype,Android SAF的uri解析

import android.app.Activity;

import android.content.ContentUris;

import android.content.Context;

import android.content.Intent;

import android.database.Cursor;

import android.net.Uri;

import android.os.Build;

import android.os.Environment;

import android.provider.DocumentsContract;

import android.provider.MediaStore;

import android.provider.OpenableColumns;

import android.support.v4.provider.DocumentFile;

import java.io.BufferedReader;

import java.io.IOException;

import java.util.List;

public class MySafUtil {

private static final String TAG = MySafUtil.class.getSimpleName();

/**

* @param activity

* @param miniType 类型

* @param category 可打开:Intent.CATEGORY_OPENABLE

* @param isMultiple 是否可多选

* @param OPEN_DOCUMENT_CODE

*/

public static void openDocument(Activity activity,String miniType,String category

,boolean isMultiple,int OPEN_DOCUMENT_CODE) {

Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);

//文档需要是可以打开的 Intent.CATEGORY_OPENABLE

intent.addCategory(category);

//指定文档的minitype为text类型

intent.setType(miniType);

//是否支持多选,默认不支持

intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE,isMultiple);

activity.startActivityForResult(intent,OPEN_DOCUMENT_CODE);

}

public interface OnDocumentActionCallback {

void onResult(String path);

}

public static void handleOpenDocumentAction(Context context,Intent data

,OnDocumentActionCallback callback) {

if (data == null) {

return;

}

//获取文档指向的uri,注意这里是指单个文件。

Uri uri = data.getData();

//根据该Uri可以获取该Document的信息,其数据列的名称和解释可以在DocumentsContact类的内部类Document中找到

//我们在此查询的信息仅仅只是演示作用

Cursor cursor = context.getContentResolver().query(uri,null,

null,null,null,null);

StringBuilder sb = new StringBuilder(" open document Uri =>");

sb.append(uri.toString());

if (cursor != null && cursor.moveToFirst()) {

String documentId = cursor.getString(cursor.getColumnIndex(

DocumentsContract.Document.COLUMN_DOCUMENT_ID));

String name = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));

// String path = cursor.getString(cursor.getColumnIndex(OpenableColumns.));

int sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE);

String size = null;

if (!cursor.isNull(sizeIndex)) {

// Technically the column stores an int, but cursor.getString()

// will do the conversion automatically.

size = cursor.getString(sizeIndex);

} else {

size = "Unknown";

}

sb.append(" name ").append(name).append(" size ").append(size);

}

DocumentFile documentFile = DocumentFile.fromSingleUri(context,uri);

if (callback != null)

callback.onResult(uriDoc2FilePath(context,documentFile));

//以下为直接从该uri中获取InputSteam,并读取出文本的内容的操作,这个是纯粹的java流操作,大家应该已经很熟悉了

//我就不多解释了。另外这里也可以直接使用OutputSteam,向文档中写入数据。

// BufferedReader br = null;

// try {

// InputStream is = context.getContentResolver().openInputStream(uri);

// br = new BufferedReader(new InputStreamReader(is));

// String line;

// sb.append("\r\n content : ");

// while((line = br.readLine())!=null){

// sb.append(line);

// }

showToast(sb.toString());

// } catch (IOException e) {

// e.printStackTrace();

// }finally {

// closeSafe(br);

// }

}

public static void closeSafe(BufferedReader bufferedReader) {

if (bufferedReader != null)

try {

bufferedReader.close();

} catch (IOException e) {

e.printStackTrace();

}

}

/**

* 打开目录,打开文档树

*

* @param activity

* @param OPEN_TREE_CODE

*/

public static void openDocTree(Activity activity,int OPEN_TREE_CODE) {

Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);

activity.startActivityForResult(intent,OPEN_TREE_CODE);

}

public static void handleDocTreeAction(Context context,Intent data

,OnDocumentActionCallback callback) throws NumberFormatException {

if (data==null)

return;

Uri treeUri = data.getData();

//授予打开的文档树永久性的读写权限

final int takeFlags = data.getFlags()

& (Intent.FLAG_GRANT_READ_URI_PERMISSION

| Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

context.getContentResolver().takePersistableUriPermission(treeUri,takeFlags);

//使用DocumentFile构建一个根文档,之后的操作可以在该文档上进行

DocumentFile mDocFile = DocumentFile.fromTreeUri(context,treeUri);

// Uri uriDocFile = mDocFile.getUri();

// //显示结果toast

// L.d(TAG," open tree uriDocFile =>" + uriDocFile);

// final List pathDocF = uriDocFile.getPathSegments();

// L.d(TAG," open tree PathSegmentsDocFile =>" + pathDocF.toString());

//

// L.d(TAG," open tree uri =>" + treeUri);

// final List paths = treeUri.getPathSegments();

// L.d(TAG," open tree PathSegments =>" + paths.toString());

String path = uriDoc2FilePath(context,mDocFile);

if (callback!=null)

callback.onResult(path);

L.d(TAG," open tree path =>" + path);

L.d(TAG," open tree path --------------------------------" );

}

/**

*

* @param context

* @param mDocumentFile 如果是SAF文档的uri,要先 DocumentFile.fromTreeUri(context,treeUri)

* 后得到的DocumentFile.getUri();

* @return

*/

public static String uri2FilePath(Context context,Uri mDocumentFile

) {

Uri selectedUri = mDocumentFile;

if (selectedUri == null) {

return null;

}

if ( Build.VERSION.SDK_INT >= 19

&& DocumentsContract.isDocumentUri(context,selectedUri)) {

// 如果是Android 4.4之後的版本,而且屬於文件URI

final String authority = selectedUri.getAuthority();

L.d(TAG,"uri2FilePath authority ="+authority);

// 判斷Authority是否為本地端檔案所使用的

if ("com.android.externalstorage.documents".equals(authority)) {

// 外部儲存空間

final String docId = DocumentsContract.getDocumentId(selectedUri);

final String[] divide = docId.split(":");

final String type = divide[0];

if ("primary".equals(type)) {

String path = Environment.getExternalStorageDirectory().getAbsolutePath().concat("/").concat(divide[1]);

return path;

} else {

String path = "/storage/".concat(type).concat("/").concat(divide[1]);

return path;

}

} else if ("com.android.providers.downloads.documents".equals(authority)) {

// 下載目錄

// 下載目錄

final String docId = DocumentsContract.getDocumentId(selectedUri);

String path = null;

/**

* 用SAF 选啦 '下载内容' 后,id = "downloads",

* 看了一下,其实就是 Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)

*/

final String DOC_ID_DOWNLOADS = "downloads";

if (docId.equals(DOC_ID_DOWNLOADS)) {

path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();

}else {

if (docId.startsWith("raw:")) {

L.d(TAG,"uriDoc2FilePath -> providers.downloads.documents 2");

path = docId.replaceFirst("raw:","");

}else {

final Uri downloadUri;

downloadUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"),Long.parseLong(docId));

path = queryMediaAbsolutePath(context,downloadUri);

}

}

L.d(TAG,"uriDoc2FilePath -> com.android.providers.downloads.documents path ="+path);

return path;

} else if ("com.android.providers.media.documents".equals(authority)) {

// 圖片、影音檔案

final String docId = DocumentsContract.getDocumentId(selectedUri);

final String[] divide = docId.split(":");

final String type = divide[0];

Uri mediaUri = null;

if ("image".equals(type)) {

mediaUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;

} else if ("video".equals(type)) {

mediaUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;

} else if ("audio".equals(type)) {

mediaUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;

} else {

return null;

}

mediaUri = ContentUris.withAppendedId(mediaUri,Long.parseLong(divide[1]));

String path = queryMediaAbsolutePath(context,mediaUri);

return path;

}

} else {

L.d(TAG,"uri2FilePath 一般的URI ");

// 如果是一般的URI

final String scheme = selectedUri.getScheme();

String path = null;

if ("content".equals(scheme)) {

// 內容URI

path = queryMediaAbsolutePath(context,selectedUri);

} else if ("file".equals(scheme)) {

// 檔案URI

path = selectedUri.getPath();

}

return path;

}

return null;

}

/**

*

* @param context

* @param mDocumentFile

* @return

*/

public static String uriDoc2FilePath(Context context,DocumentFile mDocumentFile

) throws NumberFormatException{

if (mDocumentFile == null) {

return null;

}

Uri selectedUri = mDocumentFile.getUri();

if (selectedUri == null) {

return null;

}

if ( Build.VERSION.SDK_INT >= 19

&& DocumentsContract.isDocumentUri(context,selectedUri)) {

// 如果是Android 4.4之後的版本,而且屬於文件URI

final String authority = selectedUri.getAuthority();

L.d(TAG,"uriDoc2FilePath authority ="+authority);

// 判斷Authority是否為本地端檔案所使用的

if ("com.android.externalstorage.documents".equals(authority)) {

// 外部儲存空間

final String docId = DocumentsContract.getDocumentId(selectedUri);

final String[] divide = docId.split(":");

final String type = divide[0];

if ("primary".equals(type)) {

String path = Environment.getExternalStorageDirectory().getAbsolutePath().concat("/").concat(divide[1]);

return path;

} else {

String path = "/storage/".concat(type).concat("/").concat(divide[1]);

return path;

}

} else if ("com.android.providers.downloads.documents".equals(authority)) {

L.d(TAG,"uriDoc2FilePath -> providers.downloads.documents 1");

// 下載目錄

final String docId = DocumentsContract.getDocumentId(selectedUri);

String path = null;

/**

* 用SAF 选啦 '下载内容' 后,id = "downloads",

* 看了一下,其实就是 Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)

*/

final String DOC_ID_DOWNLOADS = "downloads";

if (docId.equals(DOC_ID_DOWNLOADS)) {

L.d(TAG,"uriDoc2FilePath -> providers.downloads.documents 2 uri.path="+selectedUri.getPath());

path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();

}else {

if (docId.startsWith("raw:")) {

L.d(TAG,"uriDoc2FilePath -> providers.downloads.documents 3");

path = docId.replaceFirst("raw:","");

}else {

L.d(TAG,"uriDoc2FilePath -> providers.downloads.documents 4");

final Uri downloadUri;

downloadUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"),Long.parseLong(docId));

path = queryMediaAbsolutePath(context,downloadUri);

}

}

L.d(TAG,"uriDoc2FilePath -> com.android.providers.downloads.documents path ="+path);

return path;

} else if ("com.android.providers.media.documents".equals(authority)) {

// 圖片、影音檔案

final String docId = DocumentsContract.getDocumentId(selectedUri);

final String[] divide = docId.split(":");

final String type = divide[0];

Uri mediaUri = null;

if ("image".equals(type)) {

mediaUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;

} else if ("video".equals(type)) {

mediaUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;

} else if ("audio".equals(type)) {

mediaUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;

} else {

return null;

}

mediaUri = ContentUris.withAppendedId(mediaUri,Long.parseLong(divide[1]));

String path = queryMediaAbsolutePath(context,mediaUri);

return path;

}

} else {

L.d(TAG,"uri2FilePath 一般的URI ");

// 如果是一般的URI

final String scheme = selectedUri.getScheme();

String path = null;

if ("content".equals(scheme)) {

// 內容URI

path = queryMediaAbsolutePath(context,selectedUri);

} else if ("file".equals(scheme)) {

// 檔案URI

path = selectedUri.getPath();

}

return path;

}

return null;

}

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

final String[] projection = {MediaStore.MediaColumns.DATA};

Cursor cursor = null;

try {

cursor = context.getContentResolver().query(uri,projection,null,null,null);

if (cursor != null && cursor.moveToFirst()) {

final int index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);

return cursor.getString(index);

}

} catch (final Exception ex) {

ex.printStackTrace();

if (cursor != null) {

cursor.close();

}

}

return null;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值