与Android应用程序中的内容提供商共享图像 [英] Share an image with a content provider in Android app

查看:64
本文介绍了与Android应用程序中的内容提供商共享图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个Android应用程序,该应用程序是一个图像库,其中图像是从互联网下载的,并显示在smathphone的屏幕上.图像一次显示一次,应用程序有一个按钮可以共享显示的图像.

I'm developing an Android app that is a gallery of images in which the images are downloaded from internet for display on the screen of smathphone. Images are displayed one at a time and the application has a button to share the image that is displayed.

按照我在某些StackOverflow帖子中找到的指示(指示共享图像的正确方法是使用ContentProvider)的指示,我实现了以下代码,可用于共享某些应用程序(例如Twitter,Gmail等)的图像. ),但不适用于其他人(Facebook,Yahoo,MMS ...).

Following the directions I've found in some StackOverflow post which indicated that the right way to share an image was using a ContentProvider I have implemented the following code that works to share the images of certain applications (eg Twitter, Gmail ...) but does not work for others (Facebook, Yahoo, MMS ...).

然后,我展示了所使用的代码,希望您可以帮助我获得正确的实现,以在所有应用程序中共享图像.

Then I show the code used hoping you can help me get the correct implementation to share images in all applications.

最初,我捕获了要共享的按钮:

Initially I capture the button press to share:

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    if (item.getItemId() == R.id.menu_share) {

        // I get the image being displayed on the screen
        View root = getView();
        ImageView imageView = (ImageView) root.findViewById(R.id.image);
        Drawable imageToShareDrawable = imageView.getDrawable();

        if (imageToShareDrawable instanceof BitmapDrawable) {

            // I convert the image to Bitmap
            Bitmap imageToShare = ((BitmapDrawable) imageToShareDrawable).getBitmap();

            // Name of de image extracted from a bean property
            String fileName = quote.getImage(); 

            // I keep the image in the folder "files" of internal storage application
            TempInternalStorage.createCachedFile(fileName, imageToShare, getActivity().getApplicationContext());

            // I start the Activity to select the application to share the image after the intent Built with the method "getDefaultShareIntent"
            startActivity(getDefaultShareIntent(fileName));
        } else {
            Toast.makeText(getActivity().getApplicationContext(), "Please wait, the quote is being downloaded", Toast.LENGTH_SHORT).show();
        }
    } 

    return true;
}

将图像保存到应用程序内部存储器的方法如下:

The method for saving the image to the internal storage of the application is as follows:

public static void createCachedFile(String fileName, Bitmap image, Context context) {

    try {
        File file = new File(context.getFilesDir(), fileName);

        if (!file.exists()) {
            FileOutputStream fos = new FileOutputStream(file);
            image.compress(Bitmap.CompressFormat.JPEG, 100, fos);
            fos.flush();
            fos.close();
        } 
    } catch (Exception e) {
        Log.e("saveTempFile()", "**** Error");
    }
}

构造意图以共享它的方法:

The method that constructs the Intent to share it:

private Intent getDefaultShareIntent(String fileName) {
    final Intent shareIntent = new Intent();
    shareIntent.setAction(Intent.ACTION_SEND);
    shareIntent.setType("image/jpeg");
    shareIntent.putExtra(Intent.EXTRA_TEXT, "Test text");
    shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://" + CachedFileProvider.AUTHORITY + File.separator + "img" + File.separator + fileName));
    shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

    return shareIntent;
}

最后,ContentProvider代码如下:

Finally ContentProvider code is as follows:

public class CachedFileProvider extends ContentProvider {

private static final String CLASS_NAME = "CachedFileProvider";

public static final String AUTHORITY = "com.example.appname.cachefileprovider";

private UriMatcher uriMatcher;

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

    uriMatcher.addURI(AUTHORITY, "img/*", 1);

    return true;
}

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

    String LOG_TAG = CLASS_NAME + " - openFile";

    Log.i(LOG_TAG, "Called with uri: '" + uri + "'." + uri.getLastPathSegment());

    switch (uriMatcher.match(uri)) {

    case 1:

        String fileLocation = getContext().getFilesDir() + File.separator + uri.getLastPathSegment();

        ParcelFileDescriptor image = ParcelFileDescriptor.open(new File(fileLocation), ParcelFileDescriptor.MODE_READ_ONLY);

        return image;

    default:
        Log.i(LOG_TAG, "Unsupported uri: '" + uri + "'.");
        throw new FileNotFoundException("Unsupported uri: " + uri.toString());
    }
}

@Override
public int update(Uri uri, ContentValues contentvalues, String s, String[] as) {
    return 0;
}

@Override
public int delete(Uri uri, String s, String[] as) {
    return 0;
}

@Override
public Uri insert(Uri uri, ContentValues contentvalues) {
    return null;
}

@Override
public String getType(Uri uri) {
    return null;
}

@Override
public Cursor query(Uri uri, String[] projection, String s, String[] as1, String s1) {

    MatrixCursor c = null;

    Log.i(">>>> projection", java.util.Arrays.toString(projection));

    String fileLocation = getContext().getFilesDir() + File.separator + uri.getLastPathSegment();

    File file = new File(fileLocation);

    long time = System.currentTimeMillis();

    c = new MatrixCursor(new String[] { "_id", "_data", "orientation", "mime_type", "datetaken", "_display_name" });

    c.addRow(new Object[] { 0,  file, 0, "image/jpeg", time, uri.getLastPathSegment() });

    return c;
}

@Override
public String[] getStreamTypes(Uri uri, String mimeTypeFilter) {
    return null;
}

}

我发现,当共享图像时,某些应用程序仅调用方法"query"(在这些地方代码不起作用,我无法共享图像),而有些其他应用程序也将方法称为"query"也将方法称为"openFile",它们可以正常工作,并且我可以共享图像.

I have found that when the image is sharing some applications only call the method "query" (these are where the code does not work and I can not share the image) while there are others that also call the method "query" also call the method "openFile" and these do work and I can share the image.

希望您能帮助我,非常感谢.

I hope you can help me, thank you very much in advance.

推荐答案

正如@Sun Ning-s的注释所指出的那样,某些共享目标应用程序"可以处理以"content://.."开头的URI-s.

As @Sun Ning-s comment noted some "share target apps" can handle URI-s starting with "content://.." which you have implemented.

其他应用处理以"file://...."开头的文件uri-s,因此您必须实现第二个共享菜单共享为文件"

Other apps handle file uri-s starting with "file://...." so you have to implement a 2nd share menue "share as file"

private Intent getFileShareIntent(String fullPathTofile) {
    final Intent shareIntent = new Intent();
    shareIntent.setAction(Intent.ACTION_SEND);
    shareIntent.setType("image/jpeg");
    shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + fullPathTofile));
    shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

    return shareIntent;
}

您可以使用 Android应用程序intentintercept 来查找其他共享源应用"所提供的内容.

You can use the android app intentintercept to find out what other "share source apps" provide.

这篇关于与Android应用程序中的内容提供商共享图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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