Android-具有旧版SDK的java.lang.RuntimeException捕获视频

时间:2018-08-21 22:03:46

标签: android video camera sdk

最近升级到SDK 27,现在我遇到了与相机相关的基于文件的操作问题,这些操作与旧版Android SDK 15至17(OS小于或等于5.0)有关。操作系统的新版本(6至8)似乎很好。 FileProvider.getUriForFile和设置权限已解决了大多数问题,但是对于捕获视频,尝试保存视频时出现以下错误:

08-21 20:37:43.290 13831-13847/? E/GPS: [assist_gps_request_set_id][line = 1232] : Failed with INVALID SET-ID TYPE
08-21 20:37:46.500 16162-16162/? E/CursorWindow: Failed to read row 0, column -1 from a CursorWindow which has 1 rows, 2 columns.
08-21 20:37:46.530 16162-16162/? E/AndroidRuntime: FATAL EXCEPTION: main
    java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=2002, result=-1, data=Intent 
    { act=inline-data dat=content://com.mycompany.myapp.provider/external_files/myapp/311414eb-35fd-4a73-8368-b9b72b5b5717/1283_311414eb-35fd-4a73-8368-b9b72b5b5717_4fae434e-5a18-406f-8bf7-bf78668d4bd4.mp4 (has extras) }} to activity {com.sec.android.app.camera/com.sec.android.app.camera.Camcorder}: java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.
      at android.app.ActivityThread.deliverResults(ActivityThread.java:2992)
      at android.app.ActivityThread.handleSendResult(ActivityThread.java:3035)
      at android.app.ActivityThread.access$1100(ActivityThread.java:127)
      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1189)
      at android.os.Handler.dispatchMessage(Handler.java:99)
      at android.os.Looper.loop(Looper.java:137)
      at android.app.ActivityThread.main(ActivityThread.java:4507)
      at java.lang.reflect.Method.invokeNative(Native Method)
      at java.lang.reflect.Method.invoke(Method.java:511)
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:978)
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:745)
      at dalvik.system.NativeStart.main(Native Method)
    Caused by: java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.
      at android.database.CursorWindow.nativeGetLong(Native Method)
      at android.database.CursorWindow.getLong(CursorWindow.java:523)
      at android.database.AbstractWindowedCursor.getLong(AbstractWindowedCursor.java:75)
      at android.database.CursorWrapper.getLong(CursorWrapper.java:106)
      at com.sec.android.app.camera.Camcorder.onActivityResult(Camcorder.java:2419)
      at android.app.Activity.dispatchActivityResult(Activity.java:4653)
      at android.app.ActivityThread.deliverResults(ActivityThread.java:2988)
      at android.app.ActivityThread.handleSendResult(ActivityThread.java:3035) 
      at android.app.ActivityThread.access$1100(ActivityThread.java:127) 
      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1189) 
      at android.os.Handler.dispatchMessage(Handler.java:99) 
      at android.os.Looper.loop(Looper.java:137) 
      at android.app.ActivityThread.main(ActivityThread.java:4507) 
      at java.lang.reflect.Method.invokeNative(Native Method) 
      at java.lang.reflect.Method.invoke(Method.java:511) 
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:978) 
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:745) 
      at dalvik.system.NativeStart.main(Native Method) 
08-21 20:37:46.550 13831-13848/? E/android.os.Debug: !@Dumpstate > dumpstate -k -t -n -z -d -o /data/log/dumpstate_app_error
08-21 20:37:49.510 13802-13829/? E/AudioHardware: AudioStreamOutALSA::standby spdifenable =0
08-21 20:37:52.070 13831-13958/? E/Watchdog: !@Sync 10

有问题的代码是:

   private void pickFromCamera() {
        mCaptureFileName = "MyTestFile.mp4";
        Intent captureIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
        int captureDefault = mField.getMaxLength();
        captureIntent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, captureDefault);
        captureIntent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0);
        captureIntent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, 524288000L); // 50 mb

        File output = new File(mDirectory, mCaptureFileName);
        Uri uri = FileProvider.getUriForFile(
                VideoCaptureViewActivity.this,
                VideoCaptureViewActivity.this.getApplicationContext()
                        .getPackageName() + ".provider", output);
        Utilities.setUriForPackages(getApplicationContext(),captureIntent,uri);
        captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
        this.startActivityForResult(captureIntent, PICK_FROM_CAMERA);
    }


    /*
     * Used to support new SDK 27 changes to support older devices URI operations - photos, recordings, etc.
     */
    public static void setUriForPackages(Context context, Intent captureIntent, Uri uri) {
        if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP) {
            List<ResolveInfo> resInfoList = context.getPackageManager().queryIntentActivities(captureIntent, PackageManager.MATCH_DEFAULT_ONLY);
            for (ResolveInfo resolveInfo : resInfoList) {
                String packageName = resolveInfo.activityInfo.packageName;
                context.grantUriPermission(packageName, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
            }
        }
        else
            captureIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    }

特定设备是运行Android 4.0.4的三星平板电脑

更新

这是工作代码:

private void pickFromCamera() {
    mCaptureFileName = "MyTestFile.mp4";
    Intent captureIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
    int captureDefault = mField.getMaxLength();
    captureIntent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, captureDefault);
    captureIntent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0);
    captureIntent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, 524288000L); // 50 mb

    File output = new File(mDirectory, mCaptureFileName);
    Uri uri;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        uri = FileProvider.getUriForFile(
                VideoCaptureViewActivity.this,
                VideoCaptureViewActivity.this.getApplicationContext()
                        .getPackageName() + ".provider", output);
    } else {
        uri = Uri.fromFile(output);
    }
    Utilities.setUriForPackages(getApplicationContext(),captureIntent,uri);
    captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
    this.startActivityForResult(captureIntent, PICK_FROM_CAMERA);
}


/*
 * Used to support new SDK 27 changes to support older devices URI operations - photos, recordings, etc.
 */
public static void setUriForPackages(Context context, Intent captureIntent, Uri uri) {
    if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP) {
        List<ResolveInfo> resInfoList = context.getPackageManager().queryIntentActivities(captureIntent, PackageManager.MATCH_DEFAULT_ONLY);
        for (ResolveInfo resolveInfo : resInfoList) {
            String packageName = resolveInfo.activityInfo.packageName;
            context.grantUriPermission(packageName, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
        }
    }
    else
        captureIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
}

1 个答案:

答案 0 :(得分:0)

在具有较高SDK目标(例如27)的较旧操作系统下显示视频不需要时髦的处理,而仅是旧的urifile东西。这是答案的链接:

Video capturing crash on Samsung android 5 with FileProvider