【问题标题】:Failure delivering result ResultInfo when pick file is from file manager选择文件来自文件管理器时,无法传递结果 ResultInfo
【发布时间】:2017-03-05 17:40:49
【问题描述】:

有意图音频文件选择器它工作正常且正确,但是当我从文件管理器应用程序崩溃中选择 mp3 文件并给我以下日志时:

E/AndroidRuntime: FATAL EXCEPTION: main
                  java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=Intent { dat=file:///mnt/sdcard/Download/g.p.mp3 }} to activity {com.example.er.part2/com.example.er.part2.Main2Activity}: java.lang.NullPointerException
                      at android.app.ActivityThread.deliverResults(ActivityThread.java:3141)
                      at android.app.ActivityThread.handleSendResult(ActivityThread.java:3184)
                      at android.app.ActivityThread.access$1100(ActivityThread.java:130)
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1243)
                      at android.os.Handler.dispatchMessage(Handler.java:99)
                      at android.os.Looper.loop(Looper.java:137)
                      at android.app.ActivityThread.main(ActivityThread.java:4745)
                      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:786)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
                      at dalvik.system.NativeStart.main(Native Method)
                   Caused by: java.lang.NullPointerException
                      at com.example.er.part2.Main2Activity.getRealPathFromURI(Main2Activity.java:128)
                      at com.example.er.part2.Main2Activity.onActivityResult(Main2Activity.java:98)
                      at android.app.Activity.dispatchActivityResult(Activity.java:5192)
                      at android.app.ActivityThread.deliverResults(ActivityThread.java:3137)
                      at android.app.ActivityThread.handleSendResult(ActivityThread.java:3184) 
                      at android.app.ActivityThread.access$1100(ActivityThread.java:130) 
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1243) 
                      at android.os.Handler.dispatchMessage(Handler.java:99) 
                      at android.os.Looper.loop(Looper.java:137) 
                      at android.app.ActivityThread.main(ActivityThread.java:4745) 
                      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:786) 
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 
                      at dalvik.system.NativeStart.main(Native Method)  

这是我的代码:

 Button button=(Button)findViewById(R.id.select);
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            Intent intent_upload = new Intent();
            intent_upload.setType("audio/*");
            intent_upload.setAction(Intent.ACTION_GET_CONTENT);
            startActivityForResult(intent_upload,1);

        }
    });
 public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);


        if (requestCode == 1 && resultCode == Activity.RESULT_OK){
            if ((data != null) && (data.getData() != null)){
                audioFileUri = data.getData();
                // Now you can use that Uri to get the file path, or upload it, ...
               filePath = getRealPathFromURI(getApplicationContext(),audioFileUri);
    }
}
  public String getRealPathFromURI(Context context, Uri contentUri) {
        Cursor cursor = null;
        try {
            String[] proj = { MediaStore.Audio.Media.DATA };
            cursor = context.getContentResolver().query(contentUri,  proj, null, null, null);
            int column_index = cursor.getColumnIndex(MediaStore.Audio.Media.DATA);
            cursor.moveToFirst();
            return cursor.getString(column_index);
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
    }

正如我所说,从媒体播放器中选择时它工作正常,但从文件管理器中选择时它发生了!以及日志中的以下部分

Caused by: java.lang.NullPointerException at com.example.er.part2.Main2Activity.getRealPathFromURI(Main2Activity.java:128)

指向这条线:

int column_index = cursor.getColumnIndex(MediaStore.Audio.Media.DATA);

【问题讨论】:

    标签: java android android-intent android-cursor mediastore


    【解决方案1】:

    从媒体播放器中选择时效果很好

    它只适用于某些设备和某些情况。

    摆脱getRealPathFromURI()。使用ContentResolver 和openInputStream() 访问由Uri 标识的内容。

    【讨论】:

    • @Erf:使用来自ACTION_GET_CONTENT 或ACTION_OPEN_DOCUMENT 的Uri 涵盖在the documentation 和my book 等地方。我也在this blog post 进入这个主题。
    • 先生,我对此进行了搜索并尝试了一些方法,但仍然无法正常工作!你能告诉我必须在哪里更改代码吗?我真的需要帮助
    • 似乎所有关于 MediaStore 的答案,正如您根据您的文档所建议的那样,这不是好方法!我认为我的问题来自那里!并尝试一下您的答案,但没有奏效。我完成了,所以很困惑,请帮助
    【解决方案2】:

    经过一番研究,我发现了这种方法并解决了问题

    @SuppressLint("NewApi")
    public static String getFilePath(Context context, Uri uri) throws URISyntaxException {
        String selection = null;
        String[] selectionArgs = null;
        // Uri is different in versions after KITKAT (Android 4.4), we need to
        if (Build.VERSION.SDK_INT >= 19 && DocumentsContract.isDocumentUri(context.getApplicationContext(), uri)) {
            if (isExternalStorageDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                return Environment.getExternalStorageDirectory() + "/" + split[1];
            } else if (isDownloadsDocument(uri)) {
                final String id = DocumentsContract.getDocumentId(uri);
                uri = ContentUris.withAppendedId(
                        Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
            } else if (isMediaDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];
               if ("audio".equals(type)) {
                    uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                }
                selection = "_id=?";
                selectionArgs = new String[]{
                        split[1]
                };
            }
        }
        if ("content".equalsIgnoreCase(uri.getScheme())) {
            String[] projection = {
                    MediaStore.Audio.Media.DATA
            };
            Cursor cursor = null;
            try {
                cursor = context.getContentResolver()
                        .query(uri, projection, selection, selectionArgs, null);
                int column_index = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);
                if (cursor.moveToFirst()) {
                    return cursor.getString(column_index);
                }
            } catch (Exception e) {
            }
        } else if ("file".equalsIgnoreCase(uri.getScheme())) {
            return uri.getPath();
        }
        return null;
    }
    
    public static boolean isExternalStorageDocument(Uri uri) {
        return "com.android.externalstorage.documents".equals(uri.getAuthority());
    }
    
    public static boolean isDownloadsDocument(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }
    
    public static boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }
    

    【讨论】:

    • 这适用于 ACTION_PICK 但它不允许选择多个文件
    猜你喜欢
    • 2017-03-21
    • 2014-01-13
    • 2021-06-18
    • 2012-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多