Android Framework 常见解决方案(17)Broadcast调起输入法界面并实现文本传输的方法

112 篇文章 83 订阅

1 原理

  • 首先,我们要知道 如果想直接调出输入法的弹窗并显示内容,一定是通过三方输入法来操作,但是三方的输入法代码我们是无法改变的,因此要调用他们的父类中的公共接口。
  • 其次,所有的输入法应用都是要继承 InputMethodService来写,所有的三方输入法都是可以用InputMethodService方法中的getCurrentInputConnection().commitText(text,0) 方法来提交文本。
  • 最后,我们的思路就是 使用广播给InputMethodService发消息,InputMethodService收到消息后调用getCurrentInputConnection().commitText(text,0) 方法来提交并显示文本内容。

修改方案(Android Q)

发广播,在android上层使用以下方法实现广播的发送,关键代码如下所示:

//...
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class AGSManager {
	private static final String TAG = "AGSManager";
	public static int MSG_INPUT_TEXT = 1104;
	private Context mContext;
	private static final String BROADCAST_ACTION = "ags.input.text";
	//...
	public String parseInputMetodData(String val){
		//...
		//关键代码部分
		JSONObject jsonObject = new JSONObject(val);
		int id = jsonObject.getInt("event");
		if(id == MSG_INPUT_TEXT){
			JSONObject dataJsonObj = jsonObject.optJSONObject("data");
			String text = dataJsonObj.getString("text");
			Intent intent = new Intent(BROADCAST_ACTION);
			intent.putExtra("text",text);
			mContext.sendBroadcast(intent);
			return text;
		}
		//...
	}
	//...
}

收广播,在android framework层需要修改InputMethodService.java,文件对应的具体路径为:$AOSP/frameworks/base/core/java/android/inputmethodservice/InputMethodService.java。其中的修改内容如下所示:

package android.inputmethodservice;

//...
//添加广播需要的包
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;

public class InputMethodService extends AbstractInputMethodService {
    static final String TAG = "InputMethodService";
    static final boolean DEBUG = false;
	//...
    int mBackDisposition;
    private static final String BROADCAST_ACTION = "ags.input.text";
    IntentFilter mIntentFilter = null;
	//添加一个广播接受者
    private BroadcastReceiver mSeedlandTextReceiver = new BroadcastReceiver() {
    	@Override
		public void onReceive(Context context, Intent intent) {
			String action = intent.getAction();
			if(BROADCAST_ACTION.equals(action)){
				String text = intent.getStringExtra("text");
                //提交字符串给到输入法上层显示框。
				getCurrentInputConnection().commitText(text,0);
			}
		}
    };
	//...
    @Override public void onCreate() {
        mTheme = Resources.selectSystemTheme(mTheme,
                getApplicationInfo().targetSdkVersion,
                android.R.style.Theme_InputMethod,
                android.R.style.Theme_Holo_InputMethod,
                android.R.style.Theme_DeviceDefault_InputMethod,
                android.R.style.Theme_DeviceDefault_InputMethod);
        super.setTheme(mTheme);
        super.onCreate();
        mImm = (InputMethodManager)getSystemService(INPUT_METHOD_SERVICE);
        mSettingsObserver = SettingsObserver.createAndRegister(this);
        // If the previous IME has occupied non-empty inset in the screen, we need to decide whether
        // we continue to use the same size of the inset or update it
        mShouldClearInsetOfPreviousIme = (mImm.getInputMethodWindowVisibleHeight() > 0);
        mInflater = (LayoutInflater)getSystemService(
                Context.LAYOUT_INFLATER_SERVICE);
        mWindow = new SoftInputWindow(this, "InputMethod", mTheme, null, null, mDispatcherState,
                WindowManager.LayoutParams.TYPE_INPUT_METHOD, Gravity.BOTTOM, false);
        initViews();
        mWindow.getWindow().setLayout(MATCH_PARENT, WRAP_CONTENT);
		//添加 注册广播
		if(mIntentFilter == null){
			mIntentFilter = new IntentFilter();
			mIntentFilter.addAction(BROADCAST_ACTION);
			mIntentFilter.setPriority(Integer.MAX_VALUE);
			registerReceiver(mSeedlandTextReceiver,mIntentFilter);
		}
    }
	//...
    @Override public void onDestroy() {
        super.onDestroy();
        mRootView.getViewTreeObserver().removeOnComputeInternalInsetsListener(
                mInsetsComputer);
        doFinishInput();
        if (mWindowAdded) {
            mWindow.getWindow().setWindowAnimations(0);
            mWindow.dismiss();
        }
        if (mSettingsObserver != null) {
            mSettingsObserver.unregister();
            mSettingsObserver = null;
        }
		//添加 注销广播
		if(mIntentFilter !=null){
			unregisterReceiver(mSeedlandTextReceiver);
		}
    }
	//...
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

图王大胜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值