在2018年从Android上的图库中选择图像的方式是什么?

时间:2018-01-10 19:28:24

标签: android image android-library

我想了解社区对于在Android上从常见来源获取图片以在我们的应用中使用的问题。 我知道2010年有关于堆栈溢出的问题,但是我发现这个简单任务的答案有点太多。

也许有人知道一些轻量级库来从图库(或其他常见来源)获取图像,因此代码可以保持简单和可读

可能是这样的:

            Bitmap image;

            SomeCoolLib.
            .performImageSelect()
            .asBitmap()  
            .listener(new RequestListener<String, Bitmap>() {
                @Override
                public boolean onException(Exception e) {
                    e.printStackTrace();
                    return false;
                }

                @Override
                public boolean onCancel() {
                    return false;
                }
            }).into(image);

让用户:

so we can see this

2 个答案:

答案 0 :(得分:2)

最好的方法是使用Android存储访问框架(https://developer.android.com/guide/topics/providers/document-provider.html)。

例如,在您的活动中,您可以请求设备和文档类型(如果您想按文档类型进行过滤,请注意 intent.setType 方法)。

此代码将打开android文档选择器并让用户选择一个图像:

public class MainActivity extends AppCompatActivity {

    private static final int OPEN_DOCUMENT_CODE = 2;

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

        findViewById(R.id.floatingActionButton).setOnClickListener(view ->    {
            Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
            intent.addCategory(Intent.CATEGORY_OPENABLE);
            intent.setType("image/*");
            startActivityForResult(intent, OPEN_DOCUMENT_CODE);
        });

    }
}

然后,只需在同一活动中实施 onActivityResult ,即可接收所选图片:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
    if (requestCode == OPEN_DOCUMENT_CODE && resultCode == RESULT_OK) {
        if (resultData != null) {
            // this is the image selected by the user
            Uri imageUri = resultData.getData();
        }
    }
}

答案 1 :(得分:1)

1,选择一张图片

如果您使用此(旧样式):

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");

或者这个(官方推荐):

Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");

这些代码将在Android 8中打开FileManager,这很难使用。

如果您要在用户设备中打开相册应用并选择照片,则应使用此功能(我推荐):

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

之前所有的方式都会在onActivityResult(int, int, Intent)中获得一个Uri。

2,处理Uri

有时候我们需要图像的真实路径,您应该使用以下代码:

@Nullable
public static String getImagePathFromUri(@Nullable Uri aUri) {
    String imagePath = null;
    if (aUri == null) {
        return imagePath;
    }
    if (DocumentsContract.isDocumentUri(ApplicationContext.get(), aUri)) {
        String documentId = DocumentsContract.getDocumentId(aUri);
        if ("com.android.providers.media.documents".equals(aUri.getAuthority())) {
            String id = documentId.split(":")[1];
            String selection = MediaStore.Images.Media._ID + "=" + id;
            imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection);
        } else if ("com.android.providers.downloads.documents".equals(aUri.getAuthority())) {
            Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"),
                    Long.valueOf(documentId));
            imagePath = getImagePath(contentUri, null);
        }
    } else if ("content".equalsIgnoreCase(aUri.getScheme())) {
        imagePath = MediaUtils.getImagePath(aUri, null);
    } else if ("file".equalsIgnoreCase(aUri.getScheme())) {
        imagePath = aUri.getPath();
    }
    return imagePath;
}

private static String getImagePath(Uri aUri, String aSelection) {
    String path = null;
    Cursor cursor = ApplicationContext.get()
            .getContentResolver()
            .query(aUri, null, aSelection, null, null);
    if (cursor != null) {
        if (cursor.moveToFirst()) {
            path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
        }
        cursor.close();
    }
    return path;
}