请求排查在ImageView设置贴纸/GIF时的输入法兼容性问题
输入法贴纸/GIF兼容性问题排查
我在ImageView上设置贴纸/GIF时,遇到特定输入法兼容性问题:Kika Keyboard、Emoji Keyboard、Emoji & Font Keyboard、Facemoji Keyboard Lite 无法正常工作,报错提示:"This textbox can't support gif/sticker.";但Gboard、Google AI Keyboard、Bitmoji Keyboard 可以正常运行。请帮忙排查代码问题。
MainActivity 代码
public class MainActivity extends AppCompatActivity { private ImageView stickerImageView; MyEditText myEditText; EditText et_text; Context mContext; @SuppressLint("MissingInflatedId") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mContext=getApplicationContext(); et_text = findViewById(R.id.et_text); stickerImageView = findViewById(R.id.stickerImageView); myEditText = findViewById(R.id.myEditText); myEditText.setKeyBoardInputCallbackListener(new MyEditText.KeyBoardInputCallbackListener() { @Override public void onCommitContent(InputContentInfoCompat inputContentInfo, int flags, Bundle opts) { ClipDescription clipDescription = inputContentInfo.getDescription(); String mimeType = clipDescription.getMimeType(0); Log.d("MyEditText", "mimeType: mimeType - " + mimeType); Log.d("MyEditText", "onCommitContent: Description - " + inputContentInfo.getDescription()); Log.d("MyEditText", "onCommitContent: LinkUri - " + inputContentInfo.getLinkUri()); // Retrieve the image/gif data from inputContentInfo Uri contentUri = inputContentInfo.getContentUri(); Log.d("MyEditText", "onCommitContent: contentUri - " + contentUri); try { // Check if the content is a GIF if (inputContentInfo.getDescription().hasMimeType("image/gif")) { InputStream inputStream = mContext.getContentResolver().openInputStream(contentUri); byte[] gifBytes = new byte[inputStream.available()]; inputStream.read(gifBytes); // Load the GIF bytes into an ImageView Glide.with(mContext).asGif().load(gifBytes).into(stickerImageView); } else { // Load the PNG into an ImageView Bitmap bitmap = BitmapFactory.decodeStream(mContext.getContentResolver().openInputStream(contentUri)); stickerImageView.setImageBitmap(bitmap); } } catch (FileNotFoundException e) { Log.e("MyEditText", "Failed to load image/gif", e); } catch (IOException e) { Log.e("MyEditText", "IOException", e); } } }); } }
MyEditText 代码
public class MyEditText extends androidx.appcompat.widget.AppCompatEditText { private String[] imgTypeString; private KeyBoardInputCallbackListener keyBoardInputCallbackListener; public MyEditText(Context context) { super(context); initView(); Log.d("MyEditText", "Context - " + context); } public MyEditText(Context context, AttributeSet attrs) { super(context, attrs); initView(); Log.d("MyEditText", "AttributeSet - " + attrs); } private void initView() { imgTypeString = new String[]{ "image/*", "image/png", "image/apng", "image/avif", "image/gif", "image/jpg", "image/jpe", "image/jpeg", "image/jfif", "image/jif", "image/pjpeg", "image/pjp", "image/webp", "image/svg", "image/bmp", "image/ico", "image/cur", "image/svg+xml", "image/x-icon", "image/tif", "image/tiff", "image/x-xcf", "image/x-ms-bmp", "image/vnd.wap.wbmp", "image/xbm", "image/xbitmap", }; } @Override public InputConnection onCreateInputConnection(EditorInfo outAttrs) { final InputConnection ic = super.onCreateInputConnection(outAttrs); EditorInfoCompat.setContentMimeTypes(outAttrs, imgTypeString); return InputConnectionCompat.createWrapper(ic, outAttrs, callback); } final InputConnectionCompat.OnCommitContentListener callback = new InputConnectionCompat.OnCommitContentListener() { @Override public boolean onCommitContent(InputContentInfoCompat inputContentInfo, int flags, Bundle opts) { if (inputContentInfo == null) { Log.d("MyEditText", "inputContentInfo is null"); return false; } // read and display inputContentInfo asynchronously if (BuildCompat.isAtLeastNMR1() && (flags & InputConnectionCompat.INPUT_CONTENT_GRANT_READ_URI_PERMISSION) != 0) { try { inputContentInfo.requestPermission(); } catch (Exception e) { return false; // return false if failed } } boolean supported = false; for (final String mimeType : imgTypeString) { if (inputContentInfo.getDescription().hasMimeType(mimeType)) { supported = true; break; } } if (!supported) { Log.d("MyEditText", "Unsupported content type"); return false; } if (keyBoardInputCallbackListener != null) { Log.d("MyEditText", "keyBoardInputCallbackListener - " + keyBoardInputCallbackListener); keyBoardInputCallbackListener.onCommitContent(inputContentInfo, flags, opts); } else { Log.d("MyEditText", "keyBoardInputCallbackListener - " + keyBoardInputCallbackListener); } return true; // return true if succeeded } }; public interface KeyBoardInputCallbackListener { void onCommitContent(InputContentInfoCompat inputContentInfo, int flags, Bundle opts); } public void setKeyBoardInputCallbackListener(KeyBoardInputCallbackListener keyBoardInputCallbackListener) { Log.d("MyEditText", "keyBoardInputCallbackListener - " + keyBoardInputCallbackListener); this.keyBoardInputCallbackListener = keyBoardInputCallbackListener; } public String[] getImgTypeString() { return imgTypeString; } public void setImgTypeString(String[] imgTypeString) { this.imgTypeString = imgTypeString; } }
Manifest 配置
<activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> <data android:mimeType="image/*" /> </intent-filter> </activity>
测试结果截图
Gboard(正常工作):

Emoji Keyboard(报错):

内容的提问来源于stack exchange,提问作者Gotya Gosavi
相关产品推荐
相关产品推荐

