使用File对象在Android(API> 24)中捕获和保存视频?

问题描述 投票:0回答:1

我在要录制视频的位置编写代码,然后在录制5秒钟后将其保存。我有以下代码可以在API <24上正常工作,但是对于API> 24,我会收到错误消息。

代码:

public void startRecording()
{
    File mediaFile = new
            File(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)
            + "/myvideo.mp4");


    Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
    intent.putExtra(MediaStore.EXTRA_DURATION_LIMIT,5);
    fileUri = Uri.fromFile(mediaFile);

    intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
    startActivityForResult(intent, VIDEO_CAPTURE);
}

protected void onActivityResult(int requestCode,
                                int resultCode, Intent data) {

    if (requestCode == VIDEO_CAPTURE) {
        if (resultCode == RESULT_OK) {
            Toast.makeText(this, "Video has been saved to:\n" +
                    data.getData(), Toast.LENGTH_LONG).show();
        } else if (resultCode == RESULT_CANCELED) {
            Toast.makeText(this, "Video recording cancelled.",
                    Toast.LENGTH_LONG).show();
        } else {
            Toast.makeText(this, "Failed to record video",
                    Toast.LENGTH_LONG).show();
        }
    }
}

错误:

2019-10-08 01:15:43.483 21573-21573/com.mobilecomputing.learn2sign E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.mobilecomputing.learn2sign, PID: 21573
    android.os.FileUriExposedException: file:///storage/emulated/0/myvideo.mp4 exposed beyond app through ClipData.Item.getUri()
        at android.os.StrictMode.onFileUriExposed(StrictMode.java:1978)
        at android.net.Uri.checkFileUriExposed(Uri.java:2371)
        at android.content.ClipData.prepareToLeaveProcess(ClipData.java:963)
        at android.content.Intent.prepareToLeaveProcess(Intent.java:10228)
        at android.content.Intent.prepareToLeaveProcess(Intent.java:10213)
        at android.app.Instrumentation.execStartActivity(Instrumentation.java:1854)
        at android.app.Activity.startActivityForResult(Activity.java:4599)
        at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:676)
        at android.app.Activity.startActivityForResult(Activity.java:4557)
        at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:663)
        at com.mobilecomputing.learn2sign.PlayHelpVideo.startRecording(PlayHelpVideo.java:125)
        at com.mobilecomputing.learn2sign.PlayHelpVideo$1.onClick(PlayHelpVideo.java:46)
        at android.view.View.performClick(View.java:6669)
        at android.view.View.performClickInternal(View.java:6638)
        at android.view.View.access$3100(View.java:789)
        at android.view.View$PerformClick.run(View.java:26145)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6898)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:537)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

我检查了该错误是由于File对象的语法,并且API> 24不支持它。

尽管我可以找到其他有效的代码,但我对此代码是否有细微调整感到好奇,这也使其适用于API> 24。也许在同一行上。

有人可以帮我吗?

编辑:

我已经尝试过:https://inthecheesefactory.com/blog/how-to-share-access-to-file-with-fileprovider-on-android-nougat/en,但是这样做也会导致应用程序在API 22上崩溃。

java android video-capture
1个回答
0
投票

您可以使用FileProvider类授予对特定文件或文件夹的访问权限,以使其他应用程序可以访问它们。创建您自己的继承FileProvider的类,以确保您的FileProvider与在导入的依赖项中声明的FileProviders不冲突,如此处所述。

file:// URI替换content:// URI的步骤:

添加扩展FileProvider的类

public class GenericFileProvider extends FileProvider {}

在下面的<provider>中添加FileProvider AndroidManifest.xml标签<application>标签。指定唯一的权限android:authorities属性以避免冲突,导入依赖项可能指定${applicationId}.provider和其他常用权限。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    ...
    <application
        ...
        <provider
            android:name=".GenericFileProvider"
            android:authorities="${applicationId}.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths"/>
        </provider>
    </application>
</manifest>

然后在paths.xml文件夹中创建provider_ res/xml文件。如果文件夹不存在,则可能需要创建该文件夹。该文件的内容如下所示。它描述了我们希望共享名为“ external_files”的根文件夹(path=".")上对外部存储的访问。

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_files" path="."/>
</paths>

最后一步是更改下面的代码行

fileUri = Uri.fromFile(mediaFile);

to

fileUri= FileProvider.getUriForFile(context, context.getApplicationContext().getPackageName() + ".my.package.name.provider", mediaFile);
© www.soinside.com 2019 - 2024. All rights reserved.