【问题标题】:ContentProvider openOutputStream - how to create fileContentProvider openOutputStream - 如何创建文件
【发布时间】:2014-07-15 03:59:32
【问题描述】:

我想用我的 ContentProvider 保存/加载二进制数据。为了节省,我写了这段代码:

        long id = database.insert(TABLE_NAME, null, values);

        Uri uri = ContentUris.withAppendedId(
                LocationContentProvider.CONTENT_URI, id);

        OutputStream outStream;
        try {
            Bitmap bmp = ...

            if (bmp != null) {
                outStream = cr.openOutputStream(uri);
                ImageUtils.saveToStream(bmp, outStream,
                        Bitmap.CompressFormat.PNG);
                outStream.close();
                bmp.recycle();
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
            Log.d(TAG, "Could not save logo to " + uri.toString());
        } catch (IOException e) {
            e.printStackTrace();
            Log.d(TAG, "Could not save logo to " + uri.toString());
        }

当然,最初该文件并不存在。所以我得到了 FileNotFoundException。我的问题是,如果 ContentProvider 尚不存在,如何强制创建文件?我需要实现 ContentProvider.openFile 吗?

@Override
public ParcelFileDescriptor openFile(Uri uri, String mode)
        throws FileNotFoundException {
    // TODO Auto-generated method stub
    return super.openFile(uri, mode);
}

【问题讨论】:

    标签: android android-contentprovider


    【解决方案1】:

    我终于发现你必须重写 ContentProvider.openFile。有关详细信息,请参阅this post。我在 ContentProvider 中的方法如下所示:

    public ParcelFileDescriptor openFile(Uri uri, String mode)
            throws FileNotFoundException {
    
        ContextWrapper cw = new ContextWrapper(getContext());
    
        // path to /data/data/yourapp/app_data/dir
        File directory = cw.getDir(BASE_PATH, Context.MODE_WORLD_WRITEABLE);
        directory.mkdirs();
    
        long id = ContentUris.parseId(uri);
        File path = new File(directory, String.valueOf(id));
    
        int imode = 0;
        if (mode.contains("w")) {
            imode |= ParcelFileDescriptor.MODE_WRITE_ONLY;
            if (!path.exists()) {
                try {
                    path.createNewFile();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
        if (mode.contains("r"))
            imode |= ParcelFileDescriptor.MODE_READ_ONLY;
        if (mode.contains("+"))
            imode |= ParcelFileDescriptor.MODE_APPEND;
    
        return ParcelFileDescriptor.open(path, imode);
    }
    

    【讨论】:

    • 那么你做cr.openOutputStream(uri)的时候需要调用这个方法还是被系统调用?
    • 您需要将内容提供者绑定到 UI 元素。一旦 UI 加载特定内容。一旦您被要求将单个内容的数据绑定到 UI(例如 ListView 中的一行),那么您将需要使用您的内容提供程序来加载数据,如此处所述。希望能帮助到你。 grokkingandroid.com/handling-binary-data-with-contentproviders
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-14
    • 2013-08-23
    • 1970-01-01
    • 2018-07-29
    相关资源
    最近更新 更多