IllegalArgumentException:无效的列纬度

Posted

技术标签:

【中文标题】IllegalArgumentException:无效的列纬度【英文标题】:IllegalArgumentException: Invalid column latitude 【发布时间】:2020-08-18 12:27:20 【问题描述】:

关注documentation 我尝试查询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();
            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();
            
        
    

然后我得到以下错误:

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)
        ...

崩溃指向Cursor cur = getContentResolver().query(uri, null, null, null, null);,但如您所见,我没有查询纬度列。事实上,在崩溃的时候,我还没有查询任何列。

我只能在运行 Android 10 的设备上从 Google 照片中选择文件时重现此问题。


我的问题:

为什么会发生这种情况,我该如何克服?


编辑:

我尝试通过列的投影。为了测试,我通过了以下内容:

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

但我仍然遇到同样的错误。

【问题讨论】:

尝试使用实际投影(String[] of "columns" 返回),而不是传入null @CommonsWare 我试过了,请看我的编辑。 嗯……这很奇怪。感觉就像 Google Photo 会自动将 latitude 添加到您的投影中,然后由于您在 Android 10 上无法拥有该列而崩溃。我怀疑您对此无能为力,除了查看是否有为 Google Photo 提交错误的地方。 同样的问题出现在 Api 29 模拟器中。不在我的带有 android 10 和 api 30 模拟器的小米设备上 我确实在 issuetracker 上打开了一个问题,这应该根据谷歌解决 - issuetracker.google.com/issues/155579897 【参考方案1】:

我在 Android 10+ 中遇到了同样的问题。此问题是由于 Android 10 中引入的范围存储造成的。

解决方案: 我对这个问题的解决方案是从 Uri 创建一个输入流。检查下面的代码sn-p。

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
    

【讨论】:

这不是解决方案,而是解决方法。您正在将文件写入您的应用程序目录,而不是查询从媒体存储返回的Uri【参考方案2】:

我找到了解决办法

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

手指交叉。

【讨论】:

以上是关于IllegalArgumentException:无效的列纬度的主要内容,如果未能解决你的问题,请参考以下文章

IllegalArgumentException:无效的列纬度

Retrofit-IllegalArgumentException:意外的 url

引起:java.lang.IllegalArgumentException:属性'driverClassName'不能为空

IllegalArgumentException:接收方未注册

IllegalArgumentException 介绍

java.lang.IllegalArgumentException:基本 URI 不能为空