简体   繁体   English

Android:通过短信,G +,Twitter,Facebook可靠地分享资产中的图像?

[英]Android: Reliably share an image from assets via messaging, G+, twitter, facebook?

I am trying to create a button in my android app that allows the user to share an image using their choice of social media network. 我正在尝试在我的Android应用程序中创建一个按钮,允许用户使用他们选择的社交媒体网络共享图像。 The image file is stored in the assets folder of the app. 图像文件存储在应用程序的assets文件夹中。

My plan is to implement a custom ContentProvider to give external access to the image, then send a TYPE_SEND intent specifying the uri of the image within my content provider. 我的计划是实现自定义ContentProvider以提供对图像的外部访问,然后发送TYPE_SEND意图,指定我的内容提供者中的图像的uri。

I have done this and it works for Google+ and GMail, but for other services it fails. 我这样做了,它适用于Google+和GMail,但对于其他服务,它失败了。 The hardest part has been finding information on what I'm supposed to return from the query() method of my ContentProvider. 最困难的部分是找到我应该从ContentProvider的query()方法返回的信息。 Some apps specify a projection (eg Google+ asks for _id and _data), while some apps pass null as the projection. 某些应用会指定投影(例如,Google +要求_id和_data),而某些应用会将null作为投影传递。 Even where the projection is specified, I've no idea what actual data (types) are expected in the columns. 即使指定了投影,我也不知道列中预期的实际数据(类型)。 I can find no documentation on this. 我找不到这方面的文件。

I have also implemented the openAssetFile method of the ContentProvider and this gets called (twice by Google+!) but then inevitably the query method get called as well. 我还实现了ContentProvider的openAssetFile方法,这个方法被调用(两次由Google+!),但后来不可避免地也会调用查询方法。 Only the result of the query method seems to count. 只有查询方法的结果才算数。

Any ideas where I'm going wrong? 我出错的任何想法? What should I be returning from my query method? 我应该从查询方法返回什么?

Code below: 代码如下:

// my intent

Intent i = new Intent(android.content.Intent.ACTION_SEND);
i.setType("image/jpeg");
Uri uri = Uri.parse("content://com.me.provider/ic_launcher.jpg");
i.putExtra(Intent.EXTRA_STREAM, uri);       
i.putExtra(android.content.Intent.EXTRA_TEXT, text);
startActivity(Intent.createChooser(i, "Share via"));

// my custom content provider

public class ImageProvider extends ContentProvider
{
private AssetManager _assetManager;

public static final Uri CONTENT_URI = Uri.parse("content://com.me.provider");

// not called
@Override
public int delete(Uri arg0, String arg1, String[] arg2) 
{
    return 0;
}

// not called
@Override
public String getType(Uri uri) 
{
    return "image/jpeg";
}

// not called
@Override
public Uri insert(Uri uri, ContentValues values) 
{
    return null;
}

@Override
public boolean onCreate() 
{
    _assetManager = getContext().getAssets();
    return true;
}

@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) 
{
    MatrixCursor c = new MatrixCursor(new String[] { "_id", "_data" });

    try
    {
                    // just a guess!! works for g+ :/
        c.addRow(new Object[] { "ic_launcher.jpg",  _assetManager.openFd("ic_launcher.jpg") });
    } catch (IOException e)
    {
        e.printStackTrace();
        return null;
    }

    return c;
}

// not called
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) 
{
    return 0;
}

// not called  
@Override
public String[] getStreamTypes(Uri uri, String mimeTypeFilter)
{

    return new String[] { "image/jpeg" };
}

// called by most apps
@Override
public AssetFileDescriptor openAssetFile(Uri uri, String mode) throws FileNotFoundException 
{

    try 
    {
        AssetFileDescriptor afd = _assetManager.openFd("ic_launcher.jpg");
        return afd;
    } catch (IOException e) 
    {
        throw new FileNotFoundException("No asset found: " + uri);
    }
}

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

    return super.openFile(uri, mode);
}

} }

Thanks, your question solved mine ;) I was having the exactly inverse problem of yours: every service would work except g+. 谢谢,你的问题解决了我的问题;)我遇到了与你完全相反的问题:每个服务都可以工作,除了g +。 I was returning null in the query method, that made g+ crash. 我在查询方法中返回null,这使得g +崩溃。

The only thing to actually expose my images was to implement openFile() . 实际暴露我的图像的唯一方法是实现openFile() I have my images stored on the filesystem, not in the assets, but I suppose you could get a ParcelFileDescriptor from your AssetFileDescriptor and return it. 我将我的图像存储在文件系统上,而不是存储在资源中,但我想您可以从AssetFileDescriptor获取ParcelFileDescriptor并将其返回。 My openFile() method looks like this: 我的openFile()方法如下所示:

@Override
public ParcelFileDescriptor openFile(Uri uri, String mode)
        throws FileNotFoundException {
    String path = uri.getLastPathSegment();
    if (path == null) {
        throw new IllegalArgumentException("Not a Path");
    }
    File f = new File(getContext().getFilesDir() + File.separator + "solved" + path + ".jpg");
    int iMode;
    if ("r".equals(mode)) {
        iMode = ParcelFileDescriptor.MODE_READ_ONLY;
    } else if ("rw".equals(mode)) {
        iMode = ParcelFileDescriptor.MODE_READ_WRITE;
    } else if ("rwt".equals(mode)) {
        iMode = ParcelFileDescriptor.MODE_READ_WRITE | ParcelFileDescriptor.MODE_TRUNCATE;
    } else {
        throw new IllegalArgumentException("Invalid mode");
    }       
    return ParcelFileDescriptor.open(f, iMode); 
}

This works for every service I have installed with the ACTION_SEND intents except g+. 这适用于我使用ACTION_SEND意图安装的每个服务,除了g +。 Using your query method makes it work for google plus, too. 使用您的查询方法也可以使用google plus。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM