【问题标题】:Android setImageUri not working with asset UriAndroid setImageUri 不适用于资产 Uri
【发布时间】:2011-09-23 16:18:58
【问题描述】:

我正在使用以下代码设置资产文件夹中的图像。

Uri numBgUri = Uri.parse("file:///android_asset/background_numbers.png");
numBgImage.setImageURI(numBgUri);

background_numbers.png 文件肯定存在于 assets 根目录中。我在日志中收到 FileNotFoundException:-

09-23 17:05:23.803: WARN/ImageView(23713): Unable to open content: file:///android_asset/background_numbers.png

有什么想法我可能做错了吗?

谢谢!

【问题讨论】:

    标签: android image uri


    【解决方案1】:

    我设法使用我自己的自定义 ContentProvider 找到了可行的解决方法(这比您想象的要容易!)。感谢skink on Google Groups 的提示

    此代码应该可以工作,您只需要设置一个提供者 URL 并将其注册为清单文件中的提供者

    package sirocco.widgets;
    
    import java.io.FileNotFoundException;
    import java.io.IOException;
    
    import android.content.ContentProvider;
    import android.content.ContentValues;
    import android.content.res.AssetFileDescriptor;
    import android.content.res.AssetManager;
    import android.database.Cursor;
    import android.net.Uri;
    
    public class AssetContentProvider extends ContentProvider {
    
        private AssetManager mAssetManager;
        public static final Uri CONTENT_URI = 
                Uri.parse("content://your.provider.name");
    
        @Override
        public int delete(Uri arg0, String arg1, String[] arg2) {
            return 0;
        }
    
        @Override
        public String getType(Uri uri) {
            return null;
        }
    
        @Override
        public Uri insert(Uri uri, ContentValues values) {
            return null;
        }
    
        @Override
        public boolean onCreate() {
            mAssetManager = getContext().getAssets();
            return true;
        }
    
        @Override
        public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
            return null;
        }
    
        @Override
        public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
            return 0;
        }
    
        @Override
        public AssetFileDescriptor openAssetFile(Uri uri, String mode) throws FileNotFoundException {
            String path = uri.getPath().substring(1);
            try {
                AssetFileDescriptor afd = mAssetManager.openFd(path);
                return afd;
            } catch (IOException e) {
                throw new FileNotFoundException("No asset found: " + uri);
            }
        }
    
    }
    

    我希望这可以帮助任何有同样问题的谷歌员工!

    【讨论】:

    • 是的,非常感谢!直到第二次仔细查看时,我才意识到我可以简单地将“content:///”之类的 Uri 与您的解决方案结合使用。 IMO 不应该存在的问题的直接解决方案。 :-|
    【解决方案2】:

    您需要将所有图像放在资源目录中。例如:

    /root/res/drawable/background_numbers.png
    

    您可以通过以下方式访问它:

    numBgImage.setImageResource(R.drawable.background_numbers);
    

    【讨论】:

    • 是的,我知道这是可能的,但也应该可以将它们放在资产目录中。发布新版本时,资源 ID 不会更改。
    • 重新编译应用程序时,所有资源 id 都会更改,这是正常现象。您可以使用 R 类引用特定的 id,这样即使值发生变化也不会影响任何事情。
    • 是的,我知道它是如何工作的。如果您添加或删除资源,它只会更改值。我是数据驱动我的小部件的许多皮肤。我正在使用 URI,因此资源的 uri 不是“永久的”,但资产应该是。我将 uri 存储在每个小部件的 sharedprefs 中
    【解决方案3】:

    我建议您仔细检查:

    • 出现在您的 logcat 中的 ImageView 活动与您的代码属于同一个 apk。资产文件只能从您的应用程序中读取。

    • assets 文件夹在项目目录根目录下。

    编辑

    似乎无法直接从资产资源中提供ImageView。有关说明,请参见 this question。 作为一种解决方法,您应该尝试从您的资产文件创建一个可绘制对象,然后使用 ImageView.setImageDrawable 将其与您的图像视图相关联:

    Drawable d = Drawable.createFromStream(getAssets().open("background_numbers.png"), null);
    if (null != d) numBgImage.setImageDrawable(d);
    

    这段代码的第一行改编自@IgorKhomenko 的this answer

    【讨论】:

    • 谢谢。我检查了日志,这绝对是我的应用程序的错误。我解压缩了我的 APK 以仔细检查它是否在正确的位置,但 /assets/background_numbers.png 在那里。我成功地从资产中加载了字体和一些属性文件,这只是 URI 的东西由于某种原因无法正常工作。
    • @Ash McConnell,您能否详细说明 numBgImage 类型并提供其他代码?
    • numBgImage 是一个 ImageView。这是我得到它的方法: - ImageView numBgImage = (ImageView) layout.findViewById(R.id.numBackground);
    • 呵呵,你引用了这个问题;)。不幸的是我不能这样做,因为它是一个小部件,使用 Drawables / Bitmaps 有问题(如果有很多)
    • @AshMcConnell 哦,它现在是一个小部件?我投降了 :) 我认为您应该编辑您的问题以使其完整,以帮助未来的帮助者帮助您。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多