最近升级到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);
}
答案 0 :(得分:0)
在具有较高SDK目标(例如27)的较旧操作系统下显示视频不需要时髦的处理,而仅是旧的urifile东西。这是答案的链接:
Video capturing crash on Samsung android 5 with FileProvider