【问题标题】:Using CursorLoader with LoaderManager to retrieve images from android apps使用带有 LoaderManager 的 CursorLoader 从 android 应用程序中检索图像
【发布时间】:2013-01-03 16:19:50
【问题描述】:

目前我正在使用 getContentResolver().query()/managedQuery() 来获取光标以从图库应用中检索图像。因为我使用的 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 从图库应用程序或文件管理器中加载图像?我找不到任何解决方案。

【问题讨论】:

    标签: android android-cursoradapter android-cursor android-loadermanager android-cursorloader


    【解决方案1】:

    是否可以将 CursorLoader 与 LoaderManager 一起使用来从图库应用或文件管理器中加载图像?

    仅当他们发布、记录和支持ContentProvider

    【讨论】:

    • 感谢您的回答,CommonsWare。现在我不得不接受没有更好的解决方案。我会努力寻找更好的解决方案。
    • 终于找到了解决办法。请参阅下面的答案。
    【解决方案2】:

    在需要时通过调用 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;
    }
    

    当光标加载器完成后,它会使用检索到的数据来更新 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();
    }
    

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

    【讨论】:

    • 您可以在这里与我分享您的整个代码吗?我非常需要做同样的事情(但使用 MediaStore Audio),无论我做什么,都不会调用 OnLoadFinished。我提前感谢您的慷慨。
    • 在公共 Loader onCreateLoader(int id, Bundle args) 中将返回类型更改为 CursorLoader 是老生常谈。请帮帮我。
    • @dariusiv:你必须通过getLoaderManager().initLoader(&lt;id&gt;, &lt;args&gt;, &lt;callback&gt;)来启动加载器,通常是getLoaderManager().initLoader(0, null, this)
    【解决方案3】:

    你可能想替换这个

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

    有了这个

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

    【讨论】:

      猜你喜欢
      • 2011-09-16
      • 1970-01-01
      • 2012-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-16
      相关资源
      最近更新 更多