我正在尝试在 onActivityResult 中获取最近录制的视频。但我不明白这个内容提供商是如何工作的。我不习惯用 Java 为 Android 编程,所以这可能是一件简单的事情,但我自己无法解决。
问题只是如何使用应用程序文件夹中的提供程序将 content://media/external/video/media/17877 获取到本地文件,无需额外访问
这是我正在调试的代码部分:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
....
} else if (requestCode == CAMERA_REQUEST_VIDEO) {
if (resultCode == Activity.RESULT_OK && data != null) {
....
Uri selectedMediaUri = data.getData();
String strMediaFile = getRealPathFromURI(getApplicationContext(),selectedMediaUri);
Log.d("App","got link:"+selectedMediaUri+" File:"+strMediaFile);
File fileCameraTemp = new File(strCameraTempFile);
File fileCameraResult = new File(strMediaFile);
Uri sharedFileUri = FileProvider.getUriForFile(this, "de.xyz.app.fileprovider", fileCameraResult);
InputStream is = getContentResolver().openInputStream(sharedFileUri);
FileOutputStream fos = new FileOutputStream(fileCameraTemp);
byte[] buf = new byte[1024];
int len;
while ((len = is.read(buf)) > 0) {
fos.write(buf, 0, len);
}
is.close();
fos.close();
....
}
我正在尝试将视频文件存储到本地可访问的文件中。
getRealPathFromURI 函数:
public String getRealPathFromURI(Context context, Uri contentUri) {
Cursor cursor = null;
try {
String[] proj = { MediaStore.Images.Media.DATA };
cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} finally {
if (cursor != null) {
cursor.close();
}
}
}
所以我得到的日志输出如下:
App: onActivityResult
D App: CAMERA_REQUEST_VIDEO
D App: No valid strCameraTempFile:/storage/emulated/0/cameraresult.mp4 -> using data
D App: got data
D App: got link:content://media/external/video/media/17877 File:/storage/emulated/0/DCIM/Camera/20230824_113912.mp4
W System.err: java.io.FileNotFoundException: open failed: EACCES (Permission denied)
W System.err: at android.os.ParcelFileDescriptor.openInternal(ParcelFileDescriptor.java:315)
W System.err: at android.os.ParcelFileDescriptor.open(ParcelFileDescriptor.java:220)
W System.err: at androidx.core.content.FileProvider.openFile(FileProvider.java:566)
W System.err: at android.content.ContentProvider.openAssetFile(ContentProvider.java:1733)
W System.err: at android.content.ContentProvider.openTypedAssetFile(ContentProvider.java:1915)
W System.err: at android.content.ContentProvider.openTypedAssetFile(ContentProvider.java:1982)
W System.err: at android.content.ContentProvider$Transport.openTypedAssetFile(ContentProvider.java:511)
W System.err: at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1701)
W System.err: at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1517)
W System.err: at android.content.ContentResolver.openInputStream(ContentResolver.java:1201)
W System.err: at de.versicherungsmarkt.vemamaklerapp.VemaMaklerApp.onActivityResult(VemaMaklerApp.java:484)
W System.err: at android.app.Activity.dispatchActivityResult(Activity.java:8300)
W System.err: at android.app.ActivityThread.deliverResults(ActivityThread.java:5353)
W System.err: at android.app.ActivityThread.handleSendResult(ActivityThread.java:5401)
W System.err: at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51)
W System.err: at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
W System.err: at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
W System.err: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2267)
W System.err: at android.os.Handler.dispatchMessage(Handler.java:107)
W System.err: at android.os.Looper.loop(Looper.java:237)
W System.err: at android.app.ActivityThread.main(ActivityThread.java:8167)
W System.err: at java.lang.reflect.Method.invoke(Native Method)
W System.err: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496)
W System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)
我的 Android 清单中有一个 Provider:
<provider android:name="androidx.core.content.FileProvider" android:authorities="de.xyz.app.fileprovider" android:exported="false" android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths"/>
</provider>
具有以下配置:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-files-path name="images" path="Pictures"/>
<cache-path name="cache" path="."/>
<files-path name="files" path="."/>
<external-path name="external" path="." />
<cache-path name="cache" path="." />
<external-cache-path name="external_cache" path="." />
</paths>
我不知道该怎么做才能完成这项工作,希望有人可以帮助我
strCameraTempFile 是本地应用程序文件夹中的文件。
getRealPathFromURI 函数
删除该功能。
然后,替换:
Uri sharedFileUri = FileProvider.getUriForFile(this, "de.xyz.app.fileprovider", fileCameraResult);
InputStream is = getContentResolver().openInputStream(sharedFileUri);
与:
InputStream is = getContentResolver().openInputStream(selectedMediaUri);
此时,将内容复制到标识为
fileCameraTemp
的文件系统路径的代码应该可以更好地工作。您还可以删除其余的 FileProvider
配置,以及现有代码中现在未使用的变量。