从 Android 自定义 IME 共享资产图像,适用于除 Gmail 和 MMS 之外的所有内容

Sharing Asset Image from Android custom IME, working for everything except Gmail and MMS

好的,这可能会很长 post,因为我在过去的 3 天(18 小时)中都花在了这上面。我为 iOS 创建了一个自定义键盘分机,并受命为 Android 做同样的事情。我让一切正常工作,就像我想让用户使用的键盘一样,这些键盘可以在字母和 numbers/symbols 之间互换。以及键盘顶部自定义表情符号类别的回收器视图。在选择其中一个类别(根据其选择)时,将显示图像的水平回收器视图。在选择这些图像之一时,它应该将图像发送到用户想要的位置。

这适用于 Facebook、Twitter、Hipchat、Google 驱动和保留、FB Messagener,但是使用 mms 和 gmail 时出现错误,无法附加照片。

我有一个自定义内容提供程序 class 使用带有数据管道的 ParcelFileDescriptor,

public class ***ContentProvider extends ContentProvider {

@Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
    ParcelFileDescriptor[] pipe = null;

    try {
        pipe = ParcelFileDescriptor.createPipe();
        AssetManager assests = getContext().getResources().getAssets();
        new TransferThread(assests.open(uri.getLastPathSegment()), new ParcelFileDescriptor.AutoCloseOutputStream(pipe[1])).start();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return pipe[0];
}

这里有一个线程指出 MMS 在调用内容提供者的 openFile 之前查找具有列 "Images.Media.DATA" 和 "Images.Media.MIME_TYPE" 的 Cursor。我没有创建 SQLite 数据库,所以我创建了一个 matrixCursor 并在此处 return 它...我查看了 API 的媒体列 here 并将光标更改为匹配(沿具有要匹配但未包含在此 post 中的行的值):

@Override
public Cursor query( Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder, CancellationSignal cancellationSignal )
{
    String[] columns = new String[] {"DATA", "DATE_ADDED", "DATE_MODIFIED", "DISPLAY_NAME", "HEIGHT",
            "MIME_TYPE", "SIZE", "TITLE", "WIDTH"};        
    MatrixCursor matrixCursor = new MatrixCursor(columns);

    matrixCursor.addRow(new Object[] {uri.getLastPathSegment(), "image/png"});

//        return matrixCursor;

    // TODO: Implement this method
    return super.query( uri, projection, selection, selectionArgs, sortOrder, cancellationSignal );
}

除非它导致 MMS 应用程序强制关闭。

我的分享意图代码在这里:

@Override
public void emojiSelection(String emojiID) {
    Uri theUri = Uri.parse("content://com.***.***.***/"+emojiID);

    //Sharing intent code
    Intent intent = new Intent(Intent.ACTION_SEND);
    intent.setType("image/png");
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

    //Add data to intent
    intent.putExtra(Intent.EXTRA_STREAM, theUri);
    Intent intent2 = Intent.createChooser(intent, "Share using...");
    intent2.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent2);
}

我的清单中有提供商标签,读取权限和导出设置为 true

MMS 应用程序崩溃的堆栈跟踪:

09-14 15:23:31.517 30287-30580/? E/AndroidRuntime: FATAL EXCEPTION: addAttachment
                                               Process: com.android.mms, PID: 30287
                                               java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.
                                                   at android.database.CursorWindow.nativeGetString(Native Method)
                                                   at android.database.CursorWindow.getString(CursorWindow.java:451)
                                                   at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51)
                                                   at android.database.CursorWrapper.getString(CursorWrapper.java:137)
                                                   at com.android.mms.util.bz.b(FileInfoUtils.java:275)
                                                   at com.android.mms.ui.to.a(MessageUtils.java:15213)
                                                   at com.android.mms.composer.mt.a(ComposerAttachController.java:128)
                                                   at com.android.mms.composer.SimpleEditorBottomPanel.a(SimpleEditorBottomPanel.java:76)
                                                   at com.android.mms.composer.dk.a(BottomPanel.java:307)
                                                   at com.android.mms.composer.dk.a(BottomPanel.java:296)
                                                   at com.android.mms.util.da.run(HandleComposerAttachment.java:3316)
                                                   at java.lang.Thread.run(Thread.java:818)

首先,您的 MatrixCursor 格式不正确。您声称支持九个专栏。您唯一的一行有两列,表示 DATE 是最后一个路径段,DATE_ADDED。如果您的 MatrixCursor 仅支持两列,则仅在构造函数中提供这两列,并确保它们具有您想要的列名。

其次,你应该支持the OpenableColumns。您没有返回尺寸。

第三,你的列名有误。如果可能,请参考 SDK 中的常量。例如,没有 DISPLAY_NAME 列。 一个由OpenableColumns.DISPLAY_NAME标识的列,但实际字符串是_display_name.

最后,您在创建 MatrixCursor 之后扔掉了它。取消注释 return 声明 returns MatrixCursor,并删除 super.query() 声明。

这些应该有助于兼容性。