一、安卓微信关联文件打开,解锁便捷新体验
1.1 直接在微信中点击文件
在工作中,我们经常会通过微信接收各种文件,如文档、表格、PPT 等。安卓微信关联文件打开功能使得我们可以直接在微信中点击文件,快速跳转到相应的应用程序进行查看和编辑,无需再繁琐地寻找文件存储路径然后手动打开。这大大提高了工作效率,让我们能够更加迅速地处理工作任务,及时回复客户或上级的需求。
1.2 无缝衔接多应用
通过关联文件打开,安卓微信可以与众多其他应用实现无缝衔接。例如,当收到一个 PDF 文件时,可以直接关联到专业的 PDF 阅读器,享受更丰富的阅读和标注功能;如果是图片文件,可以轻松关联到图片编辑软件,进行快速的裁剪、调色等操作。这种多应用的协同工作方式,为用户提供了更多的选择和可能性,满足不同场景下的需求。
1.3 便捷的文件管理
关联文件打开后,我们可以在相应的应用中对文件进行管理,如保存、另存为、分享等操作更加方便。同时,一些应用还提供了云存储功能,我们可以将重要文件上传到云端,确保文件的安全性和可访问性。这样,即使更换设备或者在不同的地方,也能轻松获取所需文件。
二、系统开发实现之主配置文件-关联配置
AndroidManifest.xml
<activity
android:name=".FullscreenActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="@string/app_name_Studio"
android:theme="@style/Theme.CyberWinOSAnd.Fullscreen">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<!--未来之窗2024-09-15-->
<category
android:name="android.intent.category.MULTIWINDOW_LAUNCHER"
>
</category>
</intent-filter>
<intent-filter >
<action android:name="android.intent.action.VIEW">
</action>
<category android:name="android.intent.category.DEFAULT">
</category>
<category android:name="android.intent.category.BROWSABLE">
</category>
<action android:name="android.intent.action.EDIT">
</action>
<action android:name="android.intent.action.PICK">
</action>
<data android:mimeType="text/*">
</data>
<data android:mimeType="application/sql">
</data>
<data android:mimeType="application/php">
</data>
<data android:mimeType="application/x-php">
</data>
<data android:mimeType="application/x-javascript">
</data>
<data android:mimeType="application/javascript">
</data>
<data android:mimeType="application/pdf" />
<!--音视频-->
<data android:mimeType="video/*" />
<data android:mimeType="audio/*" />
<!--图片-->
<data android:mimeType="image/*" />
</intent-filter>
<intent-filter
>
<action
android:name="android.intent.action.VIEW"
>
</action>
<category
android:name="android.intent.category.DEFAULT"
>
</category>
<category
android:name="android.intent.category.BROWSABLE"
>
</category>
<data
android:scheme="http"
android:host="pastebin.com"
android:pathPattern="/.*"
>
</data>
</intent-filter>
<intent-filter
>
<action
android:name="android.intent.action.SEND"
>
</action>
<category
android:name="android.intent.category.DEFAULT"
>
</category>
<data
android:mimeType="text/plain"
>
</data>
</intent-filter>
</activity>
三、系统开发之权限
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<!-- 在 屏幕最顶部显示addview-->
<uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW" />
四、系统开发之接受文件关联
Intent intent = getIntent();
if (Intent.ACTION_VIEW.equals(intent.getAction())) {
Uri data = intent.getData();
if (data != null) {
// 根据数据的类型和内容进行处理
String filePath = data.getPath();
String 文件专业转化 = Cyber_Public_Var.getFileAbsolutePath(main_instance,data);
// 可以对文件路径进行进一步处理
Toast.makeText(Cyber_Public_Var.cyber_main_instance, "关联启动"+filePath+",文件专业转化="+文件专业转化, Toast.LENGTH_SHORT).show();
if ("application/pdf".equals(intent.getType())) {
// 处理 PDF 文件相关逻辑,比如使用 PDF 查看库打开文件
} else {
// 处理其他类型的数据
}
}
}
五、文件路径转换
/**
* 根据Uri获取文件绝对路径,解决Android4.4以上版本Uri转换 兼容Android 10
*
* @param context
* @param imageUri
*/
public static String getFileAbsolutePath(Context context, Uri imageUri) {
if (context == null || imageUri == null) {
return null;
}
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.KITKAT) {
return getRealFilePath(context, imageUri);
}
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT && android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.Q && DocumentsContract.isDocumentUri(context, imageUri)) {
if (isExternalStorageDocument(imageUri)) {
String docId = DocumentsContract.getDocumentId(imageUri);
String[] split = docId.split(":");
String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
}
} else if (isDownloadsDocument(imageUri)) {
String id = DocumentsContract.getDocumentId(imageUri);
Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
return getDataColumn(context, contentUri, null, null);
} else if (isMediaDocument(imageUri)) {
String docId = DocumentsContract.getDocumentId(imageUri);
String[] split = docId.split(":");
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;
}
String selection = MediaStore.Images.Media._ID + "=?";
String[] selectionArgs = new String[]{split[1]};
return getDataColumn(context, contentUri, selection, selectionArgs);
}
}
// MediaStore (and general)
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q){
return uriToFileApiQ(context,imageUri);
}
else if ("content".equalsIgnoreCase(imageUri.getScheme())) {
// Return the remote address
if (isGooglePhotosUri(imageUri)) {
return imageUri.getLastPathSegment();
}
return getDataColumn(context, imageUri, null, null);
}
// File
else if ("file".equalsIgnoreCase(imageUri.getScheme())) {
return imageUri.getPath();
}
return null;
}
//此方法 只能用于4.4以下的版本
private static String getRealFilePath(final Context context, final Uri uri) {
if (null == uri) {
return null;
}
final String scheme = uri.getScheme();
String data = null;
if (scheme == null) {
data = uri.getPath();
} else if (ContentResolver.SCHEME_FILE.equals(scheme)) {
data = uri.getPath();
} else if (ContentResolver.SCHEME_CONTENT.equals(scheme)) {
String[] projection = {MediaStore.Images.ImageColumns.DATA};
Cursor cursor = context.getContentResolver().query(uri, projection, null, null, null);
// Cursor cursor = context.getContentResolver().query(uri, new String[]{MediaStore.Images.ImageColumns.DATA}, null, null, null);
if (null != cursor) {
if (cursor.moveToFirst()) {
int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
if (index > -1) {
data = cursor.getString(index);
}
}
cursor.close();
}
}
return data;
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is ExternalStorageProvider.
*/
private static 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 static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
Cursor cursor = null;
String column = MediaStore.Images.Media.DATA;
String[] projection = {column};
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst()) {
int index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(index);
}
} finally {
if (cursor != null) {
cursor.close();
}
}
return null;
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is MediaProvider.
*/
private static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is Google Photos.
*/
private static boolean isGooglePhotosUri(Uri uri) {
return "com.google.android.apps.photos.content".equals(uri.getAuthority());
}
/**
* Android 10 以上适配 另一种写法
* @param context
* @param uri
* @return
*/
private static String getFileFromContentUri(Context context, Uri uri) {
if (uri == null) {
return null;
}
String filePath;
String[] filePathColumn = {MediaStore.MediaColumns.DATA, MediaStore.MediaColumns.DISPLAY_NAME};
ContentResolver contentResolver = context.getContentResolver();
Cursor cursor = contentResolver.query(uri, filePathColumn, null,
null, null);
if (cursor != null) {
cursor.moveToFirst();
try {
filePath = cursor.getString(cursor.getColumnIndex(filePathColumn[0]));
return filePath;
} catch (Exception e) {
} finally {
cursor.close();
}
}
return "";
}
/**
* Android 10 以上适配
* @param context
* @param uri
* @return
*/
@RequiresApi(api = Build.VERSION_CODES.Q)
private static String uriToFileApiQ(Context context, Uri uri) {
File file = null;
//android10以上转换
if (uri.getScheme().equals(ContentResolver.SCHEME_FILE)) {
file = new File(uri.getPath());
} else if (uri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) {
//把文件复制到沙盒目录
ContentResolver contentResolver = context.getContentResolver();
Cursor cursor = contentResolver.query(uri, null, null, null, null);
if (cursor.moveToFirst()) {
String displayName = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
try {
InputStream is = contentResolver.openInputStream(uri);
File cache = new File(context.getExternalCacheDir().getAbsolutePath(), Math.round((Math.random() + 1) * 1000) + displayName);
FileOutputStream fos = new FileOutputStream(cache);
FileUtils.copy(is, fos);
file = cache;
fos.close();
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return file.getAbsolutePath();
}
/**
* 通过文件路径 uri的转字符也可以
* @param filePath
* @return
*/
public static String getMimeType(String filePath) {
String ext = MimeTypeMap.getFileExtensionFromUrl(filePath);
return MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext);
}
六、阿雪技术观
拥抱开源与共享,见证科技进步奇迹,畅享人类幸福时光!
让我们积极投身于技术共享的浪潮中,不仅仅是作为受益者,更要成为贡献者。无论是分享自己的代码、撰写技术博客,还是参与开源项目的维护和改进,每一个小小的举动都可能成为推动技术进步的巨大力量