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

发布于 2024-12-01 08:11:48 字数 1388 浏览 1 评论 0原文

我试图通过 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

还是我需要为此创建一个数据库并返回游标?

更新

因此,这似乎适用于除短信应用程序(这是我决定首先测试的)之外的所有内容,但我想支持共享到它。

这是相关的堆栈跟踪:

由以下原因引起:java.lang.IllegalArgumentException:查询 content://mypackage.myprovider/someImage.png 返回 null 结果。在 com.android.mms.ui.UriImage.initFromContentUri(UriImage.java:104) 在 com.android.mms.ui.UriImage.(UriImage.java:63) 在 com.android.mms.model.ImageModel.initModelFromUri(ImageModel.java:83) 在 com.android.mms.model.ImageModel.(ImageModel.java:65) 在 com.android.mms.data.WorkingMessage.changeMedia(WorkingMessage.java:481) 在 com.android.mms.data.WorkingMessage.setAttachment(WorkingMessage.java:375) ...

所以 SMS 应用程序正在执行查询,而不是直接从 openFile 读取,我手机上的每个其他应用程序似乎都会这样做(包括其他 Google 应用程序)

有谁知道我需要在这里返回什么正确地完成查询?我现在要去 AOSP 挖。

I'm trying to expose a .png file located in my application's /data directory through a ContentProvider but instead of reaching the openFile method query is being called. Now I only ever have a single image which I need to expose for sharing to other applications, how can I setup my Intent to goto openFile instead of query?

Intent shareImageIntent = new Intent(Intent.ACTION_SEND);

            shareImageIntent.setType("image/*");

            shareImageIntent.putExtra(Intent.EXTRA_STREAM, imageUri);
            startActivity(Intent.createChooser(shareImageIntent, "Share image"));

Where the Uri looks like

content://my.package.contentprovider/fileName

Or alternatively do I need to create a database for this and return a cursor?

UPDATE

So this appears to be working on everything except the SMS app (which is what I decided to test first) I would like to support sharing to it however.

Here's the relevant stack trace:

Caused by: java.lang.IllegalArgumentException: Query on
content://mypackage.myprovider/someImage.png returns null result. 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)
at com.android.mms.model.ImageModel.(ImageModel.java:65) at
com.android.mms.data.WorkingMessage.changeMedia(WorkingMessage.java:481)
at
com.android.mms.data.WorkingMessage.setAttachment(WorkingMessage.java:375)
...

So the SMS app is performing a query instead of reading directly from openFile, which every other app on my phone seems to do (including other Google apps)

Does anyone know what I need to return here to fullfil the query appropriately? I'm going to go AOSP digging now.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

蓝颜夕 2024-12-08 08:11:48

在深入研究短信(实际上是彩信)应用程序的源代码后,这就是我想到的。

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(Images.Media.DATA 和 Images.Media.MIME_TYPE),其中合适的 数据。然后,MMS 将调用 openFile 以实际检索图像。

After digging through the source code of the SMS (MMS really) app this is what I came up with.

Inside UriImage.initFromContentUri the application makes the query code and assumes there are 2 returned columns in the Cursor

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

So inorder for your ContentProvider to work with the MMS app, you need to return a Cursor in query that only has one row and the two columns (Images.Media.DATA & Images.Media.MIME_TYPE) with the appropriate data. The MMS will then make the call to openFile to actually retrieve the image.

木緿 2024-12-08 08:11:48

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

Uri imageUri = Uri.fromFile(pathToFile);

更新:

尝试使用

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

Update2

尝试将文件保存到媒体存储并 发送它:

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

Uri imageUri = Uri.parse(url);

然后使用 ContentProviderCursor

最终更新:您的 ContentProvider 必须实现 query(.. ) 方法,它必须返回一个光标。请参阅源代码UrlImage.initFromContentUri(..) 的代码(彩信应用内部使用)来查看光标是如何调用的。看看 MatrixCursor 是否有符合要求。

An easier way to share a image resource is to save it to external storage (SD-card) and then do:

Uri imageUri = Uri.fromFile(pathToFile);

Update:

Try using

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

Update2

Try saving file to Media Store and then sending it:

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

Uri imageUri = Uri.parse(url);

Final Update using ContentProvider and Cursor:

Your ContentProvider must implement query(..) method and it must return a Cursor. See the source code of UrlImage.initFromContentUri(..) (which is internally used by MMS app) to see how cursor is called. Take a look at the MatrixCursor if it fits the bill.

勿忘心安 2024-12-08 08:11:48

如果您的内容提供程序已经正常工作,您可以通过方法 openFileDescriptor 在内容提供者中。

一个快速而肮脏的例子:

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

干杯!

If your content provider is already working you can access to a ParcelFileDescriptor via the method openFileDescriptor in the content provider.

A quick, and dirty, example for this:

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

Cheers!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文