admin 管理员组文章数量: 887016
目录
- 序言
- 打开文件管理器
- 分享操作
- 文件Uri转化为String
序言
一般都会集成Umeng的分享,基本的分享都可以满足,但是要想分享文件,比如pdf、doc、ppt等类型时,umeng就不能满足需求了,此时可以考虑调用系统分享,其实称为手机中可打开此文件的软件更为合适;
打开文件管理器
打开手机文件管理器直接上代码:
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");//设置类型,这里设置任意类型,用*代替即可。
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(intent, 1);
常用的打开指定类型的文件管理器:
类型 | 代码 |
---|---|
打开任意文件 | intent.setType(“* / *”); |
选择图片 | intent.setType(“image/*”) |
打开PDF文件 | intent.setType(“application/pdf”) |
打开apk文件 | intent.setType(“application/vnd.android.package-archive”) |
打开PPT文件 | intent.setType(“application/vnd.ms-powerpoint”) |
打开Excel文件 | intent.setType(“application/vnd.ms-excel”) |
打开Word文件 | intent.setType(“application/msword”) |
打开文本文件 | intent.setType(“text/plain”) |
选择音频 | intent.setType(“audio/*”) |
选择视频 | intent.setType(“video/*”) |
同时选择视频、图片 | intent.setType(“video/;image/”) |
分享操作
1、调用可以打开此文件的所有应用
/**
* 调用系统应用打开文件(系统分享)
*
* @param context
* @param filePath 文件路径
*/
public void openFileThirdApp(Context context, String filePath) {
if (TextUtils.isEmpty(filePath)) {
ToastUtils.getInstance().showToast("文件不存在,请重新选择");
return;
}
File file = new File(filePath);
checkFileUriExposure();
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
intent.setType("*/*"); //分享文件类型
context.startActivity(Intent.createChooser(intent, "分享"));
}
2、分享到指定应用:
主要是通过设置Intent的ComponentName来指定应用,比如分享至微信好友:new ComponentName(“com.tencent.mm”,“com.tencent.mm.ui.tools.ShareImgUI”);
/**
* 分享至指定APP
*
* @param context
* @param filePath 文件路径
* @param appType app的type
*/
public void shareFileForWhichApp(Context context, String filePath, int appType) {
if (TextUtils.isEmpty(filePath)) {
ToastUtils.getInstance().showToast("文件不存在,请重新选择");
return;
}
File file = new File(filePath);
checkFileUriExposure();
Intent intent = new Intent(Intent.ACTION_SEND);
if (appType == WEICHAT) {
ComponentName comp = new ComponentName("com.tencent.mm", "com.tencent.mm.ui.tools.ShareImgUI");
intent.setComponent(comp);
} else if (appType == WEICHAT_CIRCE) {
ComponentName comp = new ComponentName("com.tencent.mm", "com.tencent.mm.ui.tools.ShareToTimeLineUI");
intent.setComponent(comp);
} else if (appType == QQ) {
ComponentName comp = new ComponentName("com.tencent.mobileqq", "com.tencent.mobileqq.activity.JumpActivity");
intent.setComponent(comp);
} else if (appType == QQ_CIRCE) {
ComponentName comp = new ComponentName("com.qzone", "com.qzonex.module.operation.ui.QZonePublishMoodActivity");
intent.setComponent(comp);
}
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file)); //传输图片或者文件 采用流的方式
String type = "*/*";//根据文件后缀获取分享的文件类型
for (int i = 0; i < MATCH_ARRAY.length; i++) {
//判断文件的格式
if (filePath.contains(MATCH_ARRAY[i][0])) {
type = MATCH_ARRAY[i][1];
break;
}
}
intent.setType(type);
// intent.setType("image/*"); //分享文件
context.startActivity(Intent.createChooser(intent, "分享"));
}
根据二维数组获取分享文件的类型:
private static final String[][] MATCH_ARRAY = {
//{后缀名, 文件类型}
{".3gp", "video/3gpp"},
{".apk", "application/vnd.android.package-archive"},
{".asf", "video/x-ms-asf"},
{".avi", "video/x-msvideo"},
{".bin", "application/octet-stream"},
{".bmp", "image/bmp"},
{".c", "text/plain"},
{".class", "application/octet-stream"},
{".conf", "text/plain"},
{".cpp", "text/plain"},
{".doc", "application/msword"},
{".exe", "application/octet-stream"},
{".gif", "image/gif"},
{".gtar", "application/x-gtar"},
{".gz", "application/x-gzip"},
{".h", "text/plain"},
{".htm", "text/html"},
{".html", "text/html"},
{".jar", "application/java-archive"},
{".java", "text/plain"},
{".jpeg", "image/jpeg"},
{".jpg", "image/jpeg"},
{".js", "application/x-javascript"},
{".log", "text/plain"},
{".m3u", "audio/x-mpegurl"},
{".m4a", "audio/mp4a-latm"},
{".m4b", "audio/mp4a-latm"},
{".m4p", "audio/mp4a-latm"},
{".m4u", "video/vnd.mpegurl"},
{".m4v", "video/x-m4v"},
{".mov", "video/quicktime"},
{".mp2", "audio/x-mpeg"},
{".mp3", "audio/x-mpeg"},
{".mp4", "video/mp4"},
{".mpc", "application/vnd.mpohun.certificate"},
{".mpe", "video/mpeg"},
{".mpeg", "video/mpeg"},
{".mpg", "video/mpeg"},
{".mpg4", "video/mp4"},
{".mpga", "audio/mpeg"},
{".msg", "application/vnd.ms-outlook"},
{".ogg", "audio/ogg"},
{".pdf", "application/pdf"},
{".png", "image/png"},
{".pps", "application/vnd.ms-powerpoint"},
{".ppt", "application/vnd.ms-powerpoint"},
{".prop", "text/plain"},
{".rar", "application/x-rar-compressed"},
{".rc", "text/plain"},
{".rmvb", "audio/x-pn-realaudio"},
{".rtf", "application/rtf"},
{".sh", "text/plain"},
{".tar", "application/x-tar"},
{".tgz", "application/x-compressed"},
{".txt", "text/plain"},
{".wav", "audio/x-wav"},
{".wma", "audio/x-ms-wma"},
{".wmv", "audio/x-ms-wmv"},
{".wps", "application/vnd.ms-works"},
{".xml", "text/plain"},
{".z", "application/x-compress"},
{".zip", "application/zip"},
{"", "*/*"}
};
调用分享前必须执行下面的方法,否则会报如下说的错误
/**
* 分享前必须执行本代码,主要用于兼容SDK18以上的系统
* 否则会报android.os.FileUriExposedException: file:///xxx.pdf exposed beyond app through ClipData.Item.getUri()
*/
private void checkFileUriExposure() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
builder.detectFileUriExposure();
}
}
文件Uri转化为String
我在使用过程中遇到,从微信下载的路径(内部存储/tencent/MicroMsg/Download)选择的pdf、doc文件时报java.lang.IllegalArgumentException: column ‘_data’ does not exist错误;
但是当我将文件移动位置(内部存储/tencent/MicroMsg/WeiXin)就不会报错,选择其他图片都没问题,暂时没找到原因
public String getPathFromUri(final Context context, final Uri uri) {
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);
}
}
// MediaStore (and general)
else if ("content".equalsIgnoreCase(uri.getScheme())) {
return getDataColumn(context, uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
/**
* Get the value of the data column for this Uri. This is useful for
* MediaStore Uris, and other file-based ContentProviders.
*
* @param context The context.
* @param uri The Uri to query.
* @param selection (Optional) Filter used in the query.
* @param selectionArgs (Optional) Selection arguments used in the query.
* @return The value of the _data column, which is typically a file path.
*/
private String getDataColumn(Context context, Uri uri, String selection,
String[] selectionArgs) {
Cursor cursor = null;
final String column = "_data";
final String[] projection = {
column
};
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
null);
if (cursor != null && cursor.moveToFirst()) {
final int column_index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(column_index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is ExternalStorageProvider.
*/
private boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is DownloadsProvider.
*/
private boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is MediaProvider.
*/
private boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
好了,使用以上方法可以进行文件分享了,可以愉快的去开发了。。。。
版权声明:本文标题:Android 调用系统分享图片、视频等文件 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.freenas.com.cn/jishu/1726385463h950006.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论