【问题标题】:Android getAbsolutePath(data.getData()) always returns nullAndroid getAbsolutePath(data.getData()) 总是返回 null
【发布时间】:2015-07-06 11:50:30
【问题描述】:

我正在尝试编写一个应用程序来显示用户选择的图像的 EXIF 数据(放学了,我很无聊) 在寻找如何允许用户选择图像时,网上普遍的共识似乎是,要么编写自己的文件浏览器,要么使用意图启动另一个可以查看文件的应用程序,并收集它返回的数据。

我找到了以下代码-`public class ListFileActivity extends ActionBarActivity {

private String selectedImagePath = "";
final private int PICK_IMAGE = 1;
final private int CAPTURE_IMAGE = 2;
ImageView imgView;
private String imgPath;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_list_file);

}

public void cameraClick(View view) {
    final Intent intent = new Intent(
            MediaStore.ACTION_IMAGE_CAPTURE);
    intent.putExtra(MediaStore.EXTRA_OUTPUT,
            setImageUri());
    startActivityForResult(intent, CAPTURE_IMAGE);
}
public void galleryClick(View view) {
    Intent intent = new Intent();
    intent.setType("image/*");
    intent.setAction(Intent.ACTION_GET_CONTENT);
    startActivityForResult(
            Intent.createChooser(intent, ""),
            PICK_IMAGE);
}

public Uri setImageUri() {
    // Store image in dcim
    File file = new File(Environment.getExternalStorageDirectory()
            + "/DCIM/", "image" + new Date().getTime() + ".png");
    Uri imgUri = Uri.fromFile(file);
    this.imgPath = file.getAbsolutePath();
    return imgUri;
}

public String getImagePath() {
    return imgPath;
}

@Override
protected void onActivityResult(int requestCode, int resultCode,
                                Intent data) {
    if (resultCode != Activity.RESULT_CANCELED) {
        if (requestCode == PICK_IMAGE) {
            selectedImagePath = getAbsolutePath(data.getData());
            String TAG = "Showing image";
            Log.v(TAG, "Showing the image with a path of " + selectedImagePath);
            //The path returns null, piece of crap

            //imgView.setImageBitmap(decodeFile(selectedImagePath));
        } else if (requestCode == CAPTURE_IMAGE) {
            selectedImagePath = getImagePath();
            imgView.setImageBitmap(decodeFile(selectedImagePath));
        } else {
            super.onActivityResult(requestCode, resultCode,
                    data);
        }
    }

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {

    // Inflate the menu; this adds items to the action bar if it is
    // present.
    getMenuInflater().inflate(R.menu.menu_main, menu); //Was originally R.menu.main
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}

public Bitmap decodeFile(String path) {
    try {
        // Decode image size
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(path, o);
        // The new size we want to scale to
        final int REQUIRED_SIZE = 70;

        // Find the correct scale value. It should be the power of
        // 2.
        int scale = 1;
        while (o.outWidth / scale / 2 >= REQUIRED_SIZE
                && o.outHeight / scale / 2 >= REQUIRED_SIZE)
            scale *= 2;

        // Decode with inSampleSize
        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize = scale;
        return BitmapFactory.decodeFile(path, o2);
    } catch (Throwable e) {
        e.printStackTrace();
    }
    return null;

}

public String getAbsolutePath(Uri uri) {
    String[] projection = { MediaColumns.DATA };
    @SuppressWarnings("deprecation")
    Cursor cursor = managedQuery(uri, projection, null, null, null);
    if (cursor != null) {
        int column_index = cursor
                .getColumnIndexOrThrow(MediaColumns.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    } else
        return null;
}


}`

此代码有许多不同的变体,所有变体几乎相同,我找到了这个,因为它允许使用相机。

问题是,无论我尝试哪种代码 sn-p,在选择或拍摄图像后返回的目录始终为空。这发生在模拟器和我的手机上,跨越各种目录。

该应用具有所需的权限-

<uses-permission android:name="ANDROID.PERMISSION.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="ANDROID.PERMISSION.WRITE_EXTERNAL_STORAGE"/>

由于返回null,所以getAbsolutePath(Uri uri)中的光标必须为null,因为这是返回null的时候,但我不明白为什么。

感谢所有帮助

编辑-我一直在添加更多日志标签,光标似乎正在通过if(cursor != null) {}return cursor.getString(column_index) 返回 null

编辑 2- 整数 column_index,即 cursor.getColumnIndexOrThrow(MediaColumns.DATA) 返回 0

【问题讨论】:

    标签: java android io uri


    【解决方案1】:

    试试这个方法可能对你有帮助

    /**
     * @param contentURI
     * @return Return the selected ImagePath
     */
    private String getRealPathFromURI(Uri contentURI) {
        String result;
        Cursor cursor = yourContext.getContentResolver().query(contentURI,
                null, null, null, null);
        if (cursor == null) {
            result = contentURI.getPath();
        } else {
            cursor.moveToFirst();
            int idx = cursor
                    .getColumnIndex(MediaStore.Images.ImageColumns.DATA);
            result = cursor.getString(idx);
            cursor.close();
        }
        return result;
    }
    

    【讨论】:

    • 使用此方法会导致 idx 值为 -1,当传递给 cursor.getString() 时也会返回 null。无论如何感谢您的帮助。
    • 实际上,代码中的其他内容确实有效。 contentURI.getPath() 返回文档中的路径,而不是从 /document/ 开始的完整路径,但仍然是一些东西
    猜你喜欢
    • 1970-01-01
    • 2020-01-11
    • 1970-01-01
    • 1970-01-01
    • 2014-12-31
    • 2018-01-16
    • 2012-12-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多