Android中如何用Intent直接打开指定文件夹并实现视频选取(适配Cordova)
Hey there! Let's figure out how to directly open your target folder and let users pick videos to send back to your Cordova app. Your current code has a few issues we can fix—let's break this down step by step.
Key Issues with Your Current Code
- You're using
Intent.ACTION_VIEWwhich is meant for viewing content, not selecting files. We need an action designed for file picking. - The MIME type
resource/folderisn't standard; we should usevideo/*to target video files specifically. Uri.fromFile(file)will throw aFileUriExposedExceptionon Android 7.0+ (API 24+), so we need to use FileProvider to generate a safe Uri.- There's no setup to direct the file picker straight to your target folder—we'll add that with Android's storage framework APIs.
Step 1: Configure FileProvider (Mandatory for Android 7.0+)
First, add FileProvider to your AndroidManifest.xml to avoid the file Uri exposure error:
<provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider>
Then create res/xml/file_paths.xml to define which directories FileProvider can access:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-path name="external_files" path="."/> </paths>
Step 2: Updated Intent Code to Open Target Folder & Pick Videos
Replace your existing Intent code with this:
// Define your target folder File targetFolder = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/folder_name/"); // Create intent for picking video files Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); intent.setType("video/*"); // Target all video types intent.addCategory(Intent.CATEGORY_OPENABLE); // Ensure we can open the selected file // Directly open the target folder (API 29+ / Android 10+) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { Uri initialFolderUri = FileProvider.getUriForFile( this.cordova.getContext(), this.cordova.getContext().getPackageName() + ".fileprovider", targetFolder ); intent.putExtra(Intent.EXTRA_INITIAL_URI, initialFolderUri); } else { // Fallback for older Android versions intent.setDataAndType(Uri.fromFile(targetFolder), "video/*"); } // Grant read permission to the file picker intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_READ_URI_PERMISSION); // Launch the picker and wait for result if (this.cordova != null) { this.cordova.startActivityForResult( (CordovaPlugin) this, Intent.createChooser(intent, title), (srcType + 1) * 16 + returnType + 1 ); }
Step 3: Handle the Selected Video in onActivityResult
Once the user picks a video, you need to process the returned Uri and pass it to your Cordova app's JS layer:
@Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == Activity.RESULT_OK && data != null) { Uri selectedVideoUri = data.getData(); // Convert Uri to a real file path (works for most cases) String videoPath = getRealPathFromUri(selectedVideoUri); // Pass the path to your Cordova JS callback here // Example: callbackContext.success(videoPath); } } // Helper method to get real file path from Uri private String getRealPathFromUri(Uri uri) { String path = ""; ContentResolver resolver = this.cordova.getContext().getContentResolver(); String[] projection = {MediaStore.Video.Media.DATA}; Cursor cursor = resolver.query(uri, projection, null, null, null); if (cursor != null) { int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA); cursor.moveToFirst(); path = cursor.getString(columnIndex); cursor.close(); } return path; }
Step 4: Add Required Permissions
Don't forget to add these permissions to your AndroidManifest.xml:
<!-- For Android < 13 --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <!-- For Android 13+ --> <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
Also, make sure your Cordova plugin requests runtime permissions (Android 6.0+ requires this). You can use Cordova's cordova-plugin-android-permissions to handle this easily.
Important Notes
- Android Version Compatibility: The
EXTRA_INITIAL_URIparameter only works on Android 10+ (API 29). On older versions, some file managers might still open the default directory instead of your target—this is a limitation of older Android storage APIs. - File Manager Behavior: Some third-party file managers might not respect the
EXTRA_INITIAL_URIsetting. For maximum reliability, you might want to consider using a custom file picker library (like Material File Picker) wrapped into a Cordova plugin. - SAF vs Direct Path: On Android 10+, direct access to external storage paths is restricted. Using
ACTION_OPEN_DOCUMENTgives you a persistent Uri that you can use with ContentResolver to read the file content, even if the file moves.
内容的提问来源于stack exchange,提问作者Charlize Smith

