使用带LoaderManager的CursorLoader从android应用程序检索图像

使用带LoaderManager的CursorLoader从android应用程序检索图像,android,android-cursoradapter,android-cursor,android-loadermanager,android-cursorloader,Android,Android Cursoradapter,Android Cursor,Android Loadermanager,Android Cursorloader,目前,我正在使用getContentResolver().query()/managedQuery()获取一个光标,以便从gallery应用程序检索图像。因为我使用的API有一部分已被弃用,所以我想将CursorLoader与LoaderManager结合使用 /** * Creates a cursor to access the content defined by the image uri for API * version 11 and newer. * * @return

目前,我正在使用getContentResolver().query()/managedQuery()获取一个光标,以便从gallery应用程序检索图像。因为我使用的API有一部分已被弃用,所以我想将CursorLoader与LoaderManager结合使用

/**
 * Creates a cursor to access the content defined by the image uri for API
 * version 11 and newer.
 * 
 * @return The created cursor.
 */
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private Cursor createCursorHoneycomb() {
    String[] projection = {
            MediaStore.Images.Media.DATA
    };
    Cursor cursor = getContentResolver().query(imageUri, projection, null, null, null);

    return cursor;
}

/**
 * Creates a cursor to access the content defined by the image uri from API
 * version 8 to 10.
 * 
 * @return The created cursor.
 */
@SuppressWarnings("deprecation")
@TargetApi(Build.VERSION_CODES.FROYO)
private Cursor createCursorFroyo() {
    String[] projection = {
            MediaStore.Images.Media.DATA
    };
    Cursor cursor = managedQuery(imageUri, projection, null, null, null);

    return cursor;
}
因为我没有ListView,所以我不使用任何适配器。我只是为ImageView设置了一个图像位图

/**
 * Sets the image bitmap for the image view.
 */
private void setupImageView() {
    String imagePath = getImagePathFromUri(imageUri);
    Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
    ImageView imageView = (ImageView) findViewById(R.id.image_view);

    imageView.setImageBitmap(bitmap);
}

/**
 * Returns an image path created from the supplied image uri.
 * 
 * @param imageUri The supplied image uri.
 * @return Returns the created image path.
 */
@SuppressWarnings("deprecation")
private String getImagePathFromUri(Uri imageUri) {
    Cursor cursor = null;
    String imagePath = null;

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        cursor = createCursorHoneycomb();
    } else {
        cursor = createCursorFroyo();
    }

    // if image is loaded from gallery
    if (cursor != null) {
        startManagingCursor(cursor);

        int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);

        cursor.moveToFirst();
        imagePath = cursor.getString(columnIndex);
    }
    // if image is loaded from file manager
    else {
        imagePath = imageUri.getPath();
    }

    return imagePath;
}
是否可以使用带LoaderManager的CursorLoader从gallery应用程序或文件管理器加载图像?我找不到任何解决办法

是否可以使用带LoaderManager的CursorLoader从gallery应用程序或文件管理器加载图像


仅当它们发布、记录和支持
内容提供程序时

在需要时通过调用getSupportLoaderManager启动加载程序管理器

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_CODE) {
        if (resultCode == Activity.RESULT_OK) {
            imageUri = data.getData();
            getSupportLoaderManager().initLoader(0, null, this);
        } else if (resultCode == Activity.RESULT_CANCELED) {
            Toast.makeText(this, "Action canceled.", Toast.LENGTH_LONG).show();
        } else {
            Toast.makeText(this, "Action failed!", Toast.LENGTH_LONG).show();
        }
    }
}
然后创建一个用于检索图像路径的游标加载程序

@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
    String[] projection = {
            MediaStore.Images.Media.DATA
    };
    CursorLoader cursorLoader = new CursorLoader(this, imageUri, projection, null, null, null);

    return cursorLoader;
}
@覆盖
公共加载器onCreateLoader(int-id,Bundle-args){
字符串[]投影={
MediaStore.Images.Media.DATA
};
CursorLoader CursorLoader=新的CursorLoader(this,imageUri,projection,null,null);
返回游标装入器;
}
光标加载程序完成后,它将使用检索到的数据更新UI

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
    if (data != null) {
        int columnIndex = data.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);

        data.moveToFirst();
        imagePath = data.getString(columnIndex);
    } else {
        imagePath = imageUri.getPath();
    }

    setupImageView();
}
@覆盖
public void onLoadFinished(加载器、光标数据){
如果(数据!=null){
int columnIndex=data.getColumnIndexOrThrow(MediaStore.Images.Media.data);
data.moveToFirst();
imagePath=data.getString(columnIndex);
}否则{
imagePath=imageUri.getPath();
}
setupImageView();
}

这很容易做到。但是我必须了解如何使用onCreateLoader()和onLoadFinished()。

您可能需要替换此选项

Cursor Cursor=managedQuery(imageUri,projection,null,null,null)

用这个

CursorLoader cursorLoader = new CursorLoader(this, imageUri,
projection, null, null, null);
Cursor cursor = CursorLoader.loadInBackground();

谢谢你的回答,Commonware。现在我不得不承认没有更好的解决办法。我会努力找到更好的解决办法。最后我找到了一个解决办法。请看下面我的答案。您能在这里与我分享您的全部代码吗?我非常需要做同样的事情(但是使用MediaStore音频),无论我做什么,都不会调用OnLoadFinished。我提前感谢您的慷慨。在public Loader onCreateLoader(int-id,Bundle-args)中将返回类型更改为CursorLoader是一件值得纪念的事情。请帮助我。@dariusiv:您必须通过
getLoaderManager().initLoader(,)
启动加载程序,通常是
getLoaderManager().initLoader(0,null,this)