2

我在 Android 中创建了一个 AccessibilityService,我想在关注页面上的 EditText 后显示一个 AlertDialog(注意:EditText 可能来自另一个应用程序,例如登录屏幕,所以我并不总是知道 ID)。当您单击 AlertDialog 中的“确认”按钮时,它会使用文本填充该 EditText。

除了最后一部分之外,我已经完成了所有步骤......我无法弄清楚如何用文本填充 EditText。我猜有一种方法可以在某处投射 findViewByID() 方法,但我不知道如何找到 EditText 的 ID(见上文,EditText 可能来自另一个应用程序)。请参阅下面的代码,我走得远吗?下面的代码总是错误地告诉我有关密封实例的问题(无法在未密封的实例上执行此操作。)。

public void onAccessibilityEvent(final AccessibilityEvent event) {
    final AccessibilityNodeInfo source = event.getSource();

    if ((event.getEventType() == AccessibilityEvent.TYPE_VIEW_CLICKED || event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED) && CLASS_NAME_EDIT_TEXT.equals(event.getClassName())) {

        AlertDialog.Builder mSuspendDialog = new AlertDialog.Builder(getApplicationContext())
                .setTitle(R.string.str_have_password_question)
                .setPositiveButton(R.string.str_decision_use_password, new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        if (event.getSource() != null & event.getClassName().equals("android.widget.EditView")) {
                            Bundle arguments = new Bundle();
                            arguments.putCharSequence(AccessibilityNodeInfo
                                    .ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, "newtexttopopulateedittext");
                            event.getSource().performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments);
                        }
                    }
                })
                .setNegativeButton(R.string.str_decision_close, new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        // User cancelled the dialog
                    }
                });

        AlertDialog alert11 = mSuspendDialog.create();

        // Ensure we can show the dialog from this service.
        alert11.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
        alert11.show();  
4

1 回答 1

3

1)当任何活动开始时,在屏幕上创建一个List(或其他)所有的 ID 。EditText

2)在创建列表(或稍后)时,再次遍历列表并检查 SQLite 数据库中该视图是否有可用的值。

3) 如果值可用,则使用 ACTION_PASTE 在该 EditText 中注入文本。

ArrayList<AccessibilityNodeInfo> inputViewsList = new ArrayList<AccessibilityNodeInfo>();
AccessibilityNodeInfo rootNode = getRootInActiveWindow();
refreshChildViewsList(rootNode);
for(AccessibilityNodeInfo mNode : inputViewsList){
    String viewId = mNode.getViewIdResourceName();
    Cursor cr = db.rawQuery(-----your database parameters----);
    if(cr.moveToFirst()){
        //this means you have a value for that ET
        ClipboardManager clipboardManager = (ClipboardManager)getSystemService(CLIPBOARD_SERVICE);
        ClipData clipData =ClipData.newPlainText("MyAppName", cr.getString(--Your column number--));
        clipboardManager.setPrimaryClip(clipData);
        mNode.performAction(AccessibilityNodeInfo.ACTION_PASTE);
    }
}

必须使用数据库,以便您可以永久记住这些值。我在上面得到的 ID 是具有应用程序包名称和视图 ID 的完全限定 ID。因此,它在系统范围内仍然是独一无二的。

现在关于refreshChildViews()方法:

private void refreshChildViews(AccessibilityNodeInfo rootNode){
    int childCount = rootNode.getChildCount();
    for(int i=0; i<childCount ; i++){
        AccessibilityNodeInfo tmpNode = rootNode.getChildAt(i);
        int subChildCount = tmpNode.getChildCount();
        if(subChildCount==0){
            if(tmpNode.getClassName().toString().contentEquals("android.widget.EditText"){
                inputViewsList.add(tmpNode);
            }
            return;
        }
        if(subChildCount>0){
            refreshChildViews(tmpNode);
        }
    }
}

不要忘记清除inputViewsListonTYPE_WINDOW_STATE_CHANGED事件!

需要帮助请叫我。

于 2015-10-20T10:55:41.820 回答