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

Java 使用文件对象在Android(API>;24)中捕获和保存视频?,java,android,video-capture,Java,Android,Video Capture,我想录制一段视频,然后在录制完成后保存5秒钟。我有下面的代码,它在API24,我会得到错误 代码: 错误: 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.FileUriExposedExce

我想录制一段视频,然后在录制完成后保存5秒钟。我有下面的代码,它在API<24时运行良好,但是对于API>24,我会得到错误

代码:

错误:

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也工作。也许是在同一条线上

有人能帮我吗

编辑:

我已经尝试过了:但这样做也会导致API 22上的应用程序崩溃

更新:

根据回复的答案中的一个进行更改后,代码在API<24或更少的情况下工作,不会正常崩溃。但是,在API>24上,虽然不会崩溃,但createImageFile()函数会引发异常:

private File createImageFile() throws IOException {
    // Create an image file name
    String imageFileName = "myvideo";
    File storageDir = new File(Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_DCIM), "Camera");
    File image = File.createTempFile(
            imageFileName,  /* prefix */
            ".mp4",         /* suffix */
            storageDir      /* directory */
    );

    // Save a file: path for use with ACTION_VIEW intents
    Log.v("myTag","FAB create image");
    mCurrentPhotoPath = "file:" + image.getAbsolutePath();
    return image;
}
这是从以下函数调用的:

public void startRecording()
{

    Log.v("myTag","FAB recording");
    File mediaFile = null;
    try {
        mediaFile = createImageFile();
    } catch (IOException ex) {
        Log.v("myTag","Exception");
        return;
    }


    Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
    intent.putExtra(MediaStore.EXTRA_DURATION_LIMIT,5);
    //fileUri = Uri.fromFile(mediaFile);
    fileUri = FileProvider.getUriForFile(PlayHelpVideo.this,
            BuildConfig.APPLICATION_ID + ".provider",
            mediaFile);
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
    startActivityForResult(intent, VIDEO_CAPTURE);
}

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

文件://
URI替换为
内容://
URI的步骤:

添加扩展FileProvider的类

在下的
AndroidManifest.xml
中添加文件提供者
标记
标签。为该应用程序指定唯一的权限
android:authorities
属性以避免冲突,已导入 依赖项可以指定
${applicationId}.provider
和其他 常用的权威机构

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

fileUri = Uri.fromFile(mediaFile);


完成此操作后,“我的记录”按钮停止在api>24上工作。仍然在emulator API<24上工作。这确实帮助我的应用程序免于崩溃。然而,我的“晶圆厂”按钮不起作用或调用录制活动
public class GenericFileProvider extends FileProvider {}
<?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>
<?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);
fileUri= FileProvider.getUriForFile(context, context.getApplicationContext().getPackageName() + ".my.package.name.provider", mediaFile);