IllegalArgumentException: 无效的列名 latitude

huangapple go评论83阅读模式
英文:

IllegalArgumentException: Invalid column latitude

问题

根据文档中的说明,我尝试使用ContentResolver查询文件大小,代码如下:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == video_request_code) {
        if (resultCode == RESULT_OK) {
            Uri uri = data.getData();
            String[] projection = {OpenableColumns.SIZE, OpenableColumns.DISPLAY_NAME};
            Cursor cur = getContentResolver().query(uri, projection, null, null, null);
            try {
                if (cur != null && cur.moveToFirst()) {
                    int sizeIndex = cur.getColumnIndex(OpenableColumns.SIZE);
                    Log.e("size", "" + cur.getLong(sizeIndex));
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (cur != null)
                    cur.close();
            }
        }
    }
}

然后出现以下错误信息:

java.lang.IllegalArgumentException: Invalid column latitude
        at android.app.ActivityThread.deliverResults(ActivityThread.java:4845)
        ...
        at com.my.package.MainActivity.onActivityResult(MainActivity.java:146)
        ...

虽然崩溃指向了Cursor cur = getContentResolver().query(uri, null, null, null, null);,但如您所见,代码中并未查询纬度列(latitude column)。实际上,在崩溃发生时,并没有查询任何列。

仅当在运行 Android 10 的设备上从 Google 相册选择文件时,我才能复现这个问题。


我的问题:

为什么会出现这种情况,我应该如何解决?


编辑:

我尝试传递了列的投影(projection)。为了测试,我传递了以下内容:

String[] projection = {OpenableColumns.SIZE, OpenableColumns.DISPLAY_NAME};
Cursor cur = getContentResolver().query(uri, projection, null, null, null);

但我仍然收到相同的错误消息。

英文:

Following the documentation
I tried querying ContentResolver to get the file size, like this:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == video_request_code) {
        if (resultCode == RESULT_OK) {
            Uri uri = data.getData();
            Cursor cur = getContentResolver().query(uri, null, null, null, null);
            try {
                if (cur != null && cur.moveToFirst()){
                    if (uri.getScheme() != null){
                        if (uri.getScheme().equals("content")) {
                            int sizeIndex = cur.getColumnIndex(OpenableColumns.SIZE);
                            Log.e("size", ""+cur.getLong(sizeIndex));
                        }else if (uri.getScheme().equals("file")) {
                            File ff = new File(uri.getPath());
                            Log.e("size", ""+ff.length());
                        }
                    }
                }
            }catch (Exception e){
                e.printStackTrace();
            }
            finally {
                if (cur != null)
                    cur.close();
            }
        }
    }
}

Then I get the following error:

java.lang.IllegalArgumentException: Invalid column latitude
        at android.app.ActivityThread.deliverResults(ActivityThread.java:4845)
        at android.app.ActivityThread.handleSendResult(ActivityThread.java:4886)
        at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7356)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
     Caused by: java.lang.IllegalArgumentException: Invalid column latitude
        at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:170)
        at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:140)
        at android.content.ContentProviderProxy.query(ContentProviderNative.java:423)
        at android.content.ContentResolver.query(ContentResolver.java:944)
        at android.content.ContentResolver.query(ContentResolver.java:880)
        at android.content.ContentResolver.query(ContentResolver.java:836)
        at com.my.package.MainActivity.onActivityResult(MainActivity.java:146)
        ...

The crash is pointing to Cursor cur = getContentResolver().query(uri, null, null, null, null);, but as you can see, I'm not querying the latitude column. In fact, at the time of the crash, I have not queried any column.

I could only reproduce this when selecting a file from Google Photo on a device running Android 10.


My Question:

Why is this happening and how can I overcome it?


Edit:

I tried passing the projection of the columns. To test, I passed the following:

String[] projection = {OpenableColumns.SIZE, OpenableColumns.DISPLAY_NAME};
Cursor cur = getContentResolver().query(uri, projection, null, null, null);

But I still get the same error.

答案1

得分: 1

我在Android 10+中遇到了相同的问题。这个问题是由Android 10引入的分区存储所导致的。

解决方案:
我对这个问题的解决方案是从Uri创建一个输入流。请查看下面的代码片段。

fun getVideoRealPath(
        context: Context, uri: Uri
    ): File? {
        val contentResolver = context.contentResolver ?: return null

        // 在应用程序数据目录内创建文件路径
        val filePath = (context.applicationInfo.dataDir + File.separator
                + System.currentTimeMillis())
        val file = File(filePath)
        try {
            val inputStream = contentResolver.openInputStream(uri) ?: return null
            val outputStream: OutputStream = FileOutputStream(file)
            val buf = ByteArray(1024)
            var len: Int
            while (inputStream.read(buf).also { len = it } > 0) outputStream.write(buf, 0, len)
            outputStream.close()
            inputStream.close()
        } catch (ignore: IOException) {
            return null
        }
        return file
    }
英文:

I got the same issue in Android 10+. This issue is due to scoped storage which is introduced in Android 10.

Solutions:
My solution to this problem is to create an input stream from a Uri. Check the code snippet below.

fun getVideoRealPath(
        context: Context, uri: Uri
    ): File? {
        val contentResolver = context.contentResolver ?: return null

        // Create file path inside app's data dir
        val filePath = (context.applicationInfo.dataDir + File.separator
                + System.currentTimeMillis())
        val file = File(filePath)
        try {
            val inputStream = contentResolver.openInputStream(uri) ?: return null
            val outputStream: OutputStream = FileOutputStream(file)
            val buf = ByteArray(1024)
            var len: Int
            while (inputStream.read(buf).also { len = it } > 0) outputStream.write(buf, 0, len)
            outputStream.close()
            inputStream.close()
        } catch (ignore: IOException) {
            return null
        }
        return file
    }

答案2

得分: -3

我找到了解决方案。

Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

当我使用这个时,会显示问题。

Intent galleryIntent = new Intent(Intent.ACTION_GET_CONTENT);
galleryIntent.setType("video/*");
galleryIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
galleryIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, false);
galleryIntent.addCategory(Intent.CATEGORY_OPENABLE);

这个方法效果很好,你将会得到大小和临时文件路径。

请参考这些链接。

https://github.com/ivpusic/react-native-image-crop-picker/blob/95b9ba77181b627c8dd1c27369b21a3c69dc4a3d/android/src/main/java/com/reactnative/ivpusic/imagepicker/PickerModule.java#L369

https://github.com/ivpusic/react-native-image-crop-picker/blob/master/android/src/main/java/com/reactnative/ivpusic/imagepicker/RealPathUtil.java

祈祷一切顺利。

英文:

I found the solution

Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

When I use this, it shows the issue.

Intent galleryIntent = new Intent(Intent.ACTION_GET_CONTENT);
galleryIntent.setType("video/*");
galleryIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
galleryIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, false);
galleryIntent.addCategory(Intent.CATEGORY_OPENABLE);

This works well and you will get the size and temporary file path.

Consult these links.

https://github.com/ivpusic/react-native-image-crop-picker/blob/95b9ba77181b627c8dd1c27369b21a3c69dc4a3d/android/src/main/java/com/reactnative/ivpusic/imagepicker/PickerModule.java#L369

https://github.com/ivpusic/react-native-image-crop-picker/blob/master/android/src/main/java/com/reactnative/ivpusic/imagepicker/RealPathUtil.java

Finger crossed.

huangapple
  • 本文由 发表于 2020年5月4日 14:11:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/61586124.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定