通过Android上的ContentProvider在应用程序的数据目录中共享图像

我试图通过ContentProvider公开位于我的应用程序的/ data目录中的.png文件,但是没有到达openFile方法,而是调用query 。 现在我只有一个我需要公开以便与其他应用程序共享的图像,如何设置我的Intent来转到openFile而不是query

 Intent shareImageIntent = new Intent(Intent.ACTION_SEND); shareImageIntent.setType("image/*"); shareImageIntent.putExtra(Intent.EXTRA_STREAM, imageUri); startActivity(Intent.createChooser(shareImageIntent, "Share image")); 

Uri的样子

 content://my.package.contentprovider/fileName 

或者我是否需要为此创建数据库并返回游标?

UPDATE

所以这似乎是在除了SMS应用程序之外的所有事情(这是我决定首先测试的)我想支持共享。

这是相关的堆栈跟踪:

引起:java.lang.IllegalArgumentException:对内容的查询:// mypackage.myprovider/someImage.png返回null结果。 at com.android.mms.ui.UriImage.initFromContentUri(UriImage.java:104)at com.android.mms.ui.UriImage。(UriImage.java:63)at com.android.mms.model.ImageModel.initModelFromUri( ImageModel.java:83)位于com.android.mms的com.android.mms.data.WorkingMessage.changeMedia(WorkingMessage.java:481)的com.android.mms.model.ImageModel。(ImageModel.java:65)。 data.WorkingMessage.setAttachment(WorkingMessage.java:375)…

因此,短信应用正在执行查询,而不是直接从openFile中读取,而我的手机上的其他应用似乎都是这样(包括其他Google应用)

有谁知道我需要返回这里以适当地填充查询? 我现在要去AOSP挖掘了。

在深入了解SMS(MMS really)应用程序的源代码之后,这就是我想出来的。

UriImage.initFromContentUri ,应用程序生成查询代码并假设Cursor有2个返回的列

  } else { filePath = c.getString(c.getColumnIndexOrThrow(Images.Media.DATA)); mContentType = c.getString(c.getColumnIndexOrThrow(Images.Media.MIME_TYPE)); } 

因此,为了使您的ContentProvider能够使用MMS应用程序,您需要在query中返回一个Cursor ,该Cursor只有一行和两列(Images.Media.DATA&Images.Media.MIME_TYPE)和相应的数据。 然后,MMS将调用openFile来实际检索图像。

共享图像资源的一种更简单的方法是将其保存到外部存储(SD卡),然后执行以下操作:

 Uri imageUri = Uri.fromFile(pathToFile); 

更新:

尝试使用

 Uri imageUri = Uri.parse("android.resource://com.package.yourapp/" +imageResID); 

UPDATE2

尝试将文件保存到Media Store,然后发送:

 String url = Media.insertImage(context.getContentResolver(), imageFile.getAbsolutePath(), imageFile.getName(), imageFile.getName()); Uri imageUri = Uri.parse(url); 

使用ContentProviderCursor 最终更新

您的ContentProvider必须实现query(..)方法,并且必须返回Cursor 。 查看UrlImage.initFromContentUri(..)的源代码UrlImage.initFromContentUri(..) MMS应用程序内部使用),以查看如何调用游标。 如果符合账单,请查看MatrixCursor

如果您的内容提供商已在使用,您可以通过内容提供商中的openFileDescriptor方法访问ParcelFileDescriptor。

一个快速而肮脏的例子:

 ParcelFileDescriptor descriptor = mContext.getContentResolver().openFileDescriptor(IMGURI, "r"); Bitmap bmp = BitmapFactory.decodeFileDescriptor(descriptor.getFileDescriptor()); 

干杯!