Android 微信,手机文件管理,通过自己软件打开
一、安卓微信关联文件打开,解锁便捷新体验
1.1 直接在微信中点击文件
在工作中,我们经常会通过微信接收各种文件,如文档、表格、PPT 等。安卓微信关联文件打开功能使得我们可以直接在微信中点击文件,快速跳转到相应的应用程序进行查看和编辑,无需再繁琐地寻找文件存储路径然后手动打开。这大大提高了工作效率,让我们能够更加迅速地处理工作任务,及时回复客户或上级的需求。
1.2 无缝衔接多应用
通过关联文件打开,安卓微信可以与众多其他应用实现无缝衔接。例如,当收到一个 PDF 文件时,可以直接关联到专业的 PDF 阅读器,享受更丰富的阅读和标注功能;如果是图片文件,可以轻松关联到图片编辑软件,进行快速的裁剪、调色等操作。这种多应用的协同工作方式,为用户提供了更多的选择和可能性,满足不同场景下的需求。
1.3 便捷的文件管理
关联文件打开后,我们可以在相应的应用中对文件进行管理,如保存、另存为、分享等操作更加方便。同时,一些应用还提供了云存储功能,我们可以将重要文件上传到云端,确保文件的安全性和可访问性。这样,即使更换设备或者在不同的地方,也能轻松获取所需文件。
二、系统开发实现之主配置文件-关联配置
AndroidManifest.xml
<activityandroid: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--><categoryandroid: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><actionandroid:name="android.intent.action.VIEW"></action><categoryandroid:name="android.intent.category.DEFAULT"></category><categoryandroid:name="android.intent.category.BROWSABLE"></category><dataandroid:scheme="http"android:host="pastebin.com"android:pathPattern="/.*"></data></intent-filter><intent-filter><actionandroid:name="android.intent.action.SEND"></action><categoryandroid:name="android.intent.category.DEFAULT"></category><dataandroid: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 addressif (isGooglePhotosUri(imageUri)) {return imageUri.getLastPathSegment();}return getDataColumn(context, imageUri, null, null);}// Fileelse 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);}
六、阿雪技术观
拥抱开源与共享,见证科技进步奇迹,畅享人类幸福时光!
让我们积极投身于技术共享的浪潮中,不仅仅是作为受益者,更要成为贡献者。无论是分享自己的代码、撰写技术博客,还是参与开源项目的维护和改进,每一个小小的举动都可能成为推动技术进步的巨大力量