共享存储在内存中的图像 [英] Sharing images that are stored on internal memory

查看:138
本文介绍了共享存储在内存中的图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在其中一个ImageView的设置,可单击库中的打开的应用程序。

I have an application in which an ImageView is set and can be clicked to be opened in the gallery.

在默认情况下,我用下面的code,从外部存储器获取文件目录来存储我的JPEG文件:

By default, I use the following code to get a file directory from the external storage to store my jpegs:

File picsDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"MyCameraApp");

不过!假设外部存储设备未安装或根本不存在(Galaxy Nexus的),这是行不通的。所以我写了一个if语句各地,并得到内部缓存目录作为一个回落。

But! Suppose the external storage is not mounted or simply does not exist (Galaxy Nexus), this doesn't work. So I wrote an if-statement around it and get the internal cache dir as a fall back.

String state = Environment.getExternalStorageState()
if(Environment.MEDIA_MOUNTED.equals(state)){ 
    File picsDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"MyCameraApp");    
}else{
    context.getCacheDir();
}

图像显示精细的ImageView的,但是当我的意图启动不来通过。

The images show up fine in the ImageView, but don't come through when my intent launches.

Intent intent = new Intent();             
intent.setAction(android.content.Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(imgFile), "image/jpeg");
startActivity(intent);

画廊被加载,但显示黑屏。 presumably因为画廊有文件没有访问我的应用程序的缓存目录。

The gallery gets loaded, but shows a black screen. Presumably because the gallery has no access to files in the cache dir of my app.

作为替代方案,我试图用一个使用媒体内容提供商 MediaStore.Images.Media.INTERNAL_CONTENT_URI ,但是这将导致一个错误尝试inser图像时:

As an alternative, I tried using the media content provider that uses MediaStore.Images.Media.INTERNAL_CONTENT_URI, but this leads to an error when trying to inser the image:

java.lang.UnsupportedOperationException: Writing to internal storage is not supported.

我应该怎么办?

What should I do?

推荐答案

我想这里的问题是,你正在尝试打开的库保存在内存中的私人空间的文件(getCacheDir路径相对于返回到您的应用程序,只有您的应用程序可以访问存储路径)

i suppose the problem here is that you are trying open with the gallery a file saved in a private space of memory (getCacheDir return a path relative to your application and only your application can access that memory path)

如果您不能保存在外部存储器中,你可以尝试保存在公共道路(但这样的媒体文件可以通过每一个应用程序进行操作,如果你卸载你的应用程序不会清除产生的媒体,你保存有)

If you can't save in external memory, you can try to save in a public path (but that way your media files can be manipulated by every app and if you uninstall your application it doesn't clean generated media that you saved there)

如果你想使用专用内存,你可以写你的ContentProvider

If you want to use private internal memory, you can write your ContentProvider

我编辑发布内容提供商我使用acomplish我说。 这是我的内容提供商(我刚刚发布你所需要的相关部分):

i edit to post a content provider i use to acomplish what i said. this is my content provider (i just posted the relevant part you need):

public class MediaContentProvider extends ContentProvider {
private static final String TAG = "MediaContentProvider";

// name for the provider class
public static final String AUTHORITY = "com.way.srl.HandyWay.contentproviders.media";

private MediaData _mediaData;

// UriMatcher used to match against incoming requests
private UriMatcher _uriMatcher;

@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
    // TODO Auto-generated method stub
    return 0;
}

@Override
public String getType(Uri uri) {
    // TODO Auto-generated method stub
    return null;
}

@Override
public Uri insert(Uri uri, ContentValues values) {
    // TODO Auto-generated method stub
    return null;
}

@Override
public boolean onCreate() {
    uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);

    // Add a URI to the matcher which will match against the form
    // 'content://com.stephendnicholas.gmailattach.provider/*'
    // and return 1 in the case that the incoming Uri matches this pattern
    _uriMatcher.addURI(AUTHORITY, "*", 1);

    return true;
}

@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
    // TODO Auto-generated method stub
    return null;
}

@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
    // TODO Auto-generated method stub
    return 0;
}

@Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {

    Log.v(TAG, "Called with uri: '" + uri + "'." + uri.getLastPathSegment());

    // Check incoming Uri against the matcher
    switch (_uriMatcher.match(uri)) {

    // If it returns 1 - then it matches the Uri defined in onCreate
        case 1:

            // The desired file name is specified by the last segment of the
            // path
            // E.g.
            // 'content://com.stephendnicholas.gmailattach.provider/Test.txt'
            // Take this and build the path to the file
            // String fileLocation = getContext().getCacheDir() + File.separator + uri.getLastPathSegment();
            Integer mediaID = Integer.valueOf(uri.getLastPathSegment());

            if (_mediaData == null) {
                _mediaData = new MediaData();
            }
            Media m = _mediaData.get(mediaID);

            // Create & return a ParcelFileDescriptor pointing to the file
            // Note: I don't care what mode they ask for - they're only getting
            // read only
            ParcelFileDescriptor pfd = ParcelFileDescriptor.open(new File(m.filePath), ParcelFileDescriptor.MODE_READ_ONLY);
            return pfd;

            // Otherwise unrecognised Uri
        default:
            Log.v(TAG, "Unsupported uri: '" + uri + "'.");
            throw new FileNotFoundException("Unsupported uri: " + uri.toString());
    }
}

那么你在清单中需要参考您的ContentProvider,在我的情况下,它是

then you need in the manifest the reference to your contentprovider, in my case it was

<provider
        android:name=".contentproviders.MediaContentProvider"
        android:authorities="com.way.srl.HandyWay.contentproviders.media" >
    </provider>

,然后使用它像这样

and then use it like this

Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse("content://" + MediaContentProvider.AUTHORITY + "/" + m.id), "image/jpg");

在我的情况下,m是存储指向一个SQLite数据库的ID的实体,我用的取数据再次填充物(与_mediaData)一类,你可以改变code,以适应您需要

in my case m is an entity that store an id that point to a sqlite db and i use a class that fetch data to populate again the object (with _mediaData), you can just change the code to fit your needs

这样,我在我的应用程序完全解决你的问题。

this way i solved exactly your problem in my application

这篇关于共享存储在内存中的图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆