Ok this might be long post as I have spent the last 3 days (18 hrs) on this. I created a custom keyboard ext for iOS and was tasked to do the same for Android. I have everything working like I want giving the user keyboards to use that are interchangeable between letters and numbers/symbols. As well as a recycler view for custom emoji categories across the top of the keyboard. On selection of one of the categories (according to which was selected) a horizontal recycler view of the images is displayed. On selection of one of these images it should send the image to where the user wants.
This works for Facebook, Twitter, Hipchat, Google drive and keep, FB Messagener, however with mms and gmail I am given the error, unable to attach photo.
I have a custom content provider class using a ParcelFileDescriptor with a data pipe,
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];
}
There was a thread on here that stated that the MMS looks for a Cursor with the columns "Images.Media.DATA" and "Images.Media.MIME_TYPE" before calling the openFile of the content provider. I do not have a SQLite db created so I create a matrixCursor and return it here...I looked at the API for the media columns here and changed my cursor to match(along with values for the row to match but didn't include in this 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 );
}
except it causes the MMS application to force close.
My sharing intent code is here:
@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);
}
I have the provider tags in my manifest, with read permissions and exported set to true
Stack Trace for the MMS application crash:
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)
First, your MatrixCursor
is malformed. You claim to be supporting nine columns. Your only row has two columns, saying that DATE
is the last path segment and DATE_ADDED
. If your MatrixCursor
will only support two columns, only supply those two columns in the constructor, and make sure that they have the column names that you want.
Second, you're supposed to support the OpenableColumns
. You are not returning the size.
Third, your column names are wrong. Where possible, refer to constants in the SDK. For example, there is no DISPLAY_NAME
column. There is a column identified by OpenableColumns.DISPLAY_NAME
, but the actual string is _display_name
.
Finally, you throw away the MatrixCursor
, after having gone to the trouble of creating it. Uncomment your return
statement that returns the MatrixCursor
, and remove the super.query()
statement.
Those should help with compatibility.