Gboard:在EditText上启用GIF插入

时间:2018-01-05 07:15:34

标签: android android-edittext gboard

我在我的应用中使用Google的 Gboard ,当我从键盘应用输入 GIF 到我的EditText时,它会显示吐司< / p>

&#34;文本字段不支持从键盘插入GIF&#34;

我已经搜索过这一千次并且无法找到结果

任何帮助都将不胜感激。

3 个答案:

答案 0 :(得分:12)

图像键盘支持

Users often want to communicate with emojis, stickers, and other kinds of rich
content. In previous versions of Android, soft keyboards (also known as input
method editors or IMEs) could send only unicode emoji to apps. For rich
content, apps had to either build app-specific APIs that couldn't be used in
other apps or use workaround like sending images through Easy Share Action or the
clipboard.

如何运作

  

键盘图像插入需要IME和   该应用程序。以下序列描述了图像中的每个步骤   插入过程:

     

当用户点击EditText时,编辑器会发送MIME列表   它在EditorInfo.contentMimeTypes中接受的内容类型。

     

IME读取支持的类型列表并显示内容   编辑器可以接受的软键盘。

     

当用户选择图像时,IME调用commitContent()和   将InputContentInfo发送给编辑器。 commitContent()调用是   类似于commitText()调用,但是对于丰富的内容。   InputContentInfo包含一个标识a中内容的URI   内容提供商。然后,您的应用可以请求权限并阅读   来自URI的内容。

To accept rich content from IMEs, apps must tell IMEs what content types it 
accepts and specify a callbackup method that is executed when content is
received. The following example demonstrates how to create an EditText that
accept PNG images:
EditText editText = new EditText(this) {
    @Override
    public InputConnection onCreateInputConnection(EditorInfo editorInfo) {
        final InputConnection ic = super.onCreateInputConnection(editorInfo);
        EditorInfoCompat.setContentMimeTypes(editorInfo,
                new String [] {"image/png"});

        final InputConnectionCompat.OnCommitContentListener callback =
            new InputConnectionCompat.OnCommitContentListener() {
                @Override
                public boolean onCommitContent(InputContentInfoCompat inputContentInfo,
                        int flags, Bundle opts) {
                    // 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
                        }
                    }

                    // read and display inputContentInfo asynchronously.
                    // call inputContentInfo.releasePermission() as needed.

                    return true;  // return true if succeeded
                }
            };
        return InputConnectionCompat.createWrapper(ic, editorInfo, callback);
    }
};

以下是完整文档参考

https://developer.android.com/guide/topics/text/image-keyboard.html#how_it_works

向IME添加图像支持

  

想要向应用程序发送丰富内容的IME必须实现   提交内容API,如下所示:

     

覆盖onStartInput()onStartInputView()并阅读列表   目标编辑器支持的内容类型。以下代码   代码段显示了如何检查目标编辑器是否接受GIF   图像。

@Override
public void onStartInputView(EditorInfo info, boolean restarting) {
    String[] mimeTypes = EditorInfoCompat.getContentMimeTypes(editorInfo);

    boolean gifSupported = false;
    for (String mimeType : mimeTypes) {
        if (ClipDescription.compareMimeTypes(mimeType, "image/gif")) {
            gifSupported = true;
        }
    }

    if (gifSupported) {
        // the target editor supports GIFs. enable corresponding content
    } else {
        // the target editor does not support GIFs. disable corresponding content
    }
}
  

用户选择图片时向应用提交内容。避免   在有任何撰写文本时调用commitContent()因为它   可能会导致编辑失去焦点。以下代码段显示   如何提交GIF图像。

/**
 * Commits a GIF image
 *
 * @param contentUri Content URI of the GIF image to be sent
 * @param imageDescription Description of the GIF image to be sent
 */
public static void commitGifImage(Uri contentUri, String imageDescription) {
    InputContentInfoCompat inputContentInfo = new InputContentInfoCompat(
            contentUri,
            new ClipDescription(imageDescription, new String[]{"image/gif"}));
    InputConnection inputConnection = getCurrentInputConnection();
    EditorInfo editorInfo = getCurrentInputEditorInfo();
    Int flags = 0;
    if (android.os.Build.VERSION.SDK_INT >= 25) {
        flags |= InputConnectionCompat.INPUT_CONTENT_GRANT_READ_URI_PERMISSION;
    }
    InputConnectionCompat.commitContent(
            inputConnection, editorInfo, inputContentInfo, flags, opts);
}

以下是完整文档

https://developer.android.com/guide/topics/text/image-keyboard.html#adding_image_support_to_imes

答案 1 :(得分:5)

我从某个地方找到了解决方案。希望它能帮助每个人。

exports.register = functions.https.onRequest((request, response) => {
    const db = admin.firestore();

    const user: string = request.body['username'];
    const phone: number = request.body['phone'];
    const password: string = request.body['password'];

    return db.collection('rejectedContacts').where('contact', '==', phone).get()
        .then(rejectedContactsSnapShot => {
            if (rejectedContactsSnapShot.size > 0) {
                return response.json(
                    {
                        status: 0,
                        message: `Contact, ${phone} is blocked, please try again with another number`,
                        result: null
                    }
                );
            } 
        }).then(notRejected=>{
            return db.collection('users').where('contacts.phone', '==', phone).get()
                    .then(contactsSnapShot => {
                        if (contactsSnapShot.size > 0) {
                            return response.json(
                                {
                                    status: 0,
                                    message: `Contact, ${phone} is already assigned with an account. Did you forgot your pasword?`,
                                    result: null
                                }
                            );
                        } 
                    });
        }).then(numberDoesNotExists=>{
            return db.collection('users').add(
                {
                    user: user,
                    password: password,
                    isBlocked: false,
                    joiningDate: Date.now(),
                    phoneVerified: false,
                    deleted: false,
                    contacts:
                        {
                            phone: phone
                        }

                }
            );
        }).then((writeResult) => {
            return response.json(
                {
                    result: `User with ID: ${writeResult.id} added.`
                }
            );
        });
});

答案 2 :(得分:1)

如果您想要内置具有此功能的EditText,请签出我的库RichContentEditText:https://github.com/GregoryConrad/RichContentEditText

它毫不费力地允许将丰富的内容(图像和其他文件)从IME传输到应用程序。这是一些示例代码:

XML

ffmpeg -i 1_a.opus -i 2_a.opus -i 1_v.mp4 -i 2_v_bars.mp4 -filter_complex "[1:a]adelay=15720|15720[a1]; [0:a][a1]amix; [3:v]trim=0:15.81,geq=0:128:128,fifo [silence]; [silence][3:v]concat,fifo [3_v_silence]; [3_v_silence][2:v]hstack,fifo" -vcodec libx264 -strict experimental -y out_fifo_h264_2.mp4

Java

ffmpeg version 4.0.2-static https://johnvansickle.com/ffmpeg/  Copyright (c) 2000-2018 the FFmpeg developers
  built with gcc 6.3.0 (Debian 6.3.0-18+deb9u1) 20170516
  configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio --disable-outdev=sndio --cc=gcc-6 --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gray --enable-libaom --enable-libfribidi --enable-libass --enable-libvmaf --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librubberband --enable-libsoxr --enable-libspeex --enable-libvorbis --enable-libopus --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzimg
  libavutil      56. 14.100 / 56. 14.100
  libavcodec     58. 18.100 / 58. 18.100
  libavformat    58. 12.100 / 58. 12.100
  libavdevice    58.  3.100 / 58.  3.100
  libavfilter     7. 16.100 /  7. 16.100
  libswscale      5.  1.100 /  5.  1.100
  libswresample   3.  1.100 /  3.  1.100
  libpostproc    55.  1.100 / 55.  1.100
Input #0, ogg, from '1_a.opus':
  Duration: 00:01:03.82, start: -0.020000, bitrate: 37 kb/s
    Stream #0:0: Audio: opus, 48000 Hz, stereo, fltp
Input #1, ogg, from '2_a.opus':
  Duration: 00:00:52.40, start: -0.020000, bitrate: 44 kb/s
    Stream #1:0: Audio: opus, 48000 Hz, stereo, fltp
Input #2, mov,mp4,m4a,3gp,3g2,mj2, from '1_v.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf56.40.101
  Duration: 00:01:03.83, start: 0.000000, bitrate: 2313 kb/s
    Stream #2:0(und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p, 640x480 [SAR 1:1 DAR 4:3], 2302 kb/s, 333 fps, 333 tbr, 10656 tbn, 666 tbc (default)
    Metadata:
      handler_name    : VideoHandler
Input #3, mov,mp4,m4a,3gp,3g2,mj2, from '2_v_bars.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf58.12.100
  Duration: 00:00:52.32, start: 0.000000, bitrate: 286 kb/s
    Stream #3:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 640x480 [SAR 1:1 DAR 4:3], 284 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc (default)
    Metadata:
      handler_name    : VideoHandler
Stream mapping:
  Stream #0:0 (opus) -> amix:input0
  Stream #1:0 (opus) -> adelay
  Stream #2:0 (h264) -> hstack:input1
  Stream #3:0 (h264) -> trim
  Stream #3:0 (h264) -> concat:in1:v0
  amix -> Stream #0:0 (aac)
  fifo -> Stream #0:1 (libx264)
Press [q] to stop, [?] for help
[libx264 @ 0x50722c0] using SAR=1/1
[libx264 @ 0x50722c0] using cpu capabilities: MMX2 SSE2Fast SSSE3 Cache64 SlowShuffle
[libx264 @ 0x50722c0] profile High, level 3.1
[libx264 @ 0x50722c0] 264 - core 155 r2901 7d0ff22 - H.264/MPEG-4 AVC codec - Copyleft 2003-2018 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=3 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
Output #0, mp4, to 'out_fifo_h264_2.mp4':
  Metadata:
    encoder         : Lavf58.12.100
    Stream #0:0: Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s (default)
    Metadata:
      encoder         : Lavc58.18.100 aac
    Stream #0:1: Video: h264 (libx264) (avc1 / 0x31637661), yuv420p, 1280x480 [SAR 1:1 DAR 8:3], q=-1--1, 25 fps, 12800 tbn, 25 tbc (default)
    Metadata:
      encoder         : Lavc58.18.100 libx264
    Side data:
      cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: -1
Past duration 0.924919 too large
[Parsed_concat_5 @ 0x52e2e00] Buffer queue overflow, dropping.trate= 415.7kbits/s dup=0 drop=3349 speed=0.955x    
    Last message repeated 11 times
[Parsed_concat_5 @ 0x52e2e00] Buffer queue overflow, dropping.trate= 394.0kbits/s dup=0 drop=3533 speed=0.962x    
    Last message repeated 11 times
[Parsed_concat_5 @ 0x52e2e00] Buffer queue overflow, dropping.trate= 376.7kbits/s dup=0 drop=3698 speed=0.963x    
    Last message repeated 11 times
[Parsed_concat_5 @ 0x52e2e00] Buffer queue overflow, dropping.trate= 362.1kbits/s dup=0 drop=3851 speed=0.96x    
    Last message repeated 12 times
[Parsed_concat_5 @ 0x52e2e00] Buffer queue overflow, dropping.trate= 345.6kbits/s dup=0 drop=4033 speed=0.965x    
    Last message repeated 13 times
[Parsed_concat_5 @ 0x52e2e00] Buffer queue overflow, dropping.trate= 331.0kbits/s dup=0 drop=4208 speed=0.969x    
    Last message repeated 12 times
[Parsed_concat_5 @ 0x52e2e00] Buffer queue overflow, dropping.trate= 318.2kbits/s dup=0 drop=4381 speed=0.971x    
    Last message repeated 12 times
[Parsed_concat_5 @ 0x52e2e00] Buffer queue overflow, dropping.trate= 305.8kbits/s dup=0 drop=4555 speed=0.974x    
    Last message repeated 12 times
[Parsed_concat_5 @ 0x52e2e00] Buffer queue overflow, dropping.trate= 294.4kbits/s dup=0 drop=4733 speed=0.977x    
    Last message repeated 13 times
[Parsed_concat_5 @ 0x52e2e00] Buffer queue overflow, dropping.trate= 283.7kbits/s dup=0 drop=4912 speed=0.98x    
    Last message repeated 12 times
[Parsed_concat_5 @ 0x52e2e00] Buffer queue overflow, dropping.trate= 410.2kbits/s dup=0 drop=5094 speed=0.984x    
    Last message repeated 10 times
frame= 1706 fps= 26 q=-1.0 Lsize=    4924kB time=00:01:08.16 bitrate= 591.8kbits/s dup=0 drop=21053 speed=1.02x    
video:3914kB audio:958kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 1.061062%
[aac @ 0x5040040] Qavg: 22388.959
[libx264 @ 0x50722c0] frame I:7     Avg QP:15.90  size: 26657
[libx264 @ 0x50722c0] frame P:502   Avg QP:19.36  size:  5413
[libx264 @ 0x50722c0] frame B:1197  Avg QP:23.11  size:   922
[libx264 @ 0x50722c0] consecutive B-frames:  5.2%  1.9%  5.5% 87.5%
[libx264 @ 0x50722c0] mb I  I16..4: 26.8% 56.4% 16.7%
[libx264 @ 0x50722c0] mb P  I16..4:  3.0%  2.8%  0.6%  P16..4: 21.6%  6.4%  3.2%  0.0%  0.0%    skip:62.3%
[libx264 @ 0x50722c0] mb B  I16..4:  0.2%  0.1%  0.0%  B16..8: 18.8%  0.9%  0.1%  direct: 0.4%  skip:79.5%  L0:49.1% L1:48.8% BI: 2.1%
[libx264 @ 0x50722c0] 8x8 transform intra:45.7% inter:70.7%
[libx264 @ 0x50722c0] coded y,uvDC,uvAC intra: 39.5% 57.5% 22.6% inter: 4.2% 6.4% 0.2%
[libx264 @ 0x50722c0] i16 v,h,dc,p: 22% 31% 19% 28%
[libx264 @ 0x50722c0] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 26% 23% 38%  2%  2%  2%  2%  3%  2%
[libx264 @ 0x50722c0] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 35% 29% 21%  2%  3%  4%  2%  3%  1%
[libx264 @ 0x50722c0] i8c dc,h,v,p: 55% 23% 18%  5%
[libx264 @ 0x50722c0] Weighted P-Frames: Y:0.0% UV:0.0%
[libx264 @ 0x50722c0] ref P L0: 65.6% 12.4% 16.1%  5.9%
[libx264 @ 0x50722c0] ref B L0: 85.0% 12.2%  2.7%
[libx264 @ 0x50722c0] ref B L1: 95.4%  4.6%
[libx264 @ 0x50722c0] kb/s:469.82