全屏浏览
缩小浏览
回到页首

android基础---->AccessibilityService的简单使用(一)

  AccessibilityService类可以帮助我们实现监听手机上别的应用,以下做一个简单的总结。我总是勇敢的离开一个人 却不懂如何巧妙的靠近一个人。

 

AccessibilityService的使用案例

我们的项目是监听basetest1里面的toast弹出的内容。如果是弹出的字符串是hello,那么触发basetest1里面字符为print测试按钮的点击事件。项目结构如下:

一、AndroidManifest.xml文件的内容:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.basetest2">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service
            android:name=".service.RobService"
            android:enabled="true"
            android:exported="true"
            android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
            <intent-filter>
                <action android:name="android.accessibilityservice.AccessibilityService" />
            </intent-filter>
            <meta-data
                android:name="android.accessibilityservice"
                android:resource="@xml/accessibility" />
        </service>
    </application>

</manifest>

MainActivity类的内容如下:

package com.example.basetest2;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

import com.example.basetest2.service.RobService;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

 

二、RobService的文件内容如下:

package com.example.basetest2.service;

import android.accessibilityservice.AccessibilityService;
import android.util.Log;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.Toast;

import java.util.List;

/**
 * User: huhx
 * Date: 2017/2/7
 */

public class RobService extends AccessibilityService {
    private final static String DEBUG_NAME = RobService.class.getName();

    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        int eventType = event.getEventType();
        switch (eventType) {
            case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED:
                handleNotification(event);
                break;
        }
    }

    // 处理通知的事件
    private void handleNotification(AccessibilityEvent event) {
        List<CharSequence> texts = event.getText();
        for (CharSequence charSequence : texts) {
            Log.i(DEBUG_NAME, "notification context: " + charSequence);
            if (charSequence.equals("hello")) {
                AccessibilityNodeInfo nodeInfo = null;
                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
                    nodeInfo = getRootInActiveWindow();
                }
                if (nodeInfo != null) {
                    List<AccessibilityNodeInfo> infos = null;
                    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) {
                        infos = nodeInfo.findAccessibilityNodeInfosByViewId("com.example.huhx.basetest1:id/bt_print_photo");
                    }
                    nodeInfo.recycle();
                    for (AccessibilityNodeInfo item : infos) {
                        Toast.makeText(this, "Hello World", Toast.LENGTH_SHORT).show();
                        Log.i(DEBUG_NAME, item.isClickable() + "");
                        item.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                    }
                }
            }
            Toast.makeText(this, "hello world", Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onInterrupt() {
        Log.i(DEBUG_NAME, "rob service interrupt");
    }
}

在res里面创建xml文件夹,创建accessibility.xml文件

<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:accessibilityEventTypes="typeNotificationStateChanged|typeWindowStateChanged|typeWindowContentChanged"
    android:accessibilityFeedbackType="feedbackGeneric"
    android:accessibilityFlags="flagDefault"
    android:canRetrieveWindowContent="true"
    android:notificationTimeout="100"
    android:packageNames="com.example.huhx.basetest1" />

accessibilityEventTypes配置的是监听事件的类型,完整的事件类型。参见官方文档: https://developer.android.google.cn/reference/android/view/accessibility/AccessibilityEvent.html。packageNames是监听的包名,这里我们监听的是baseTest1项目。

 

三、通过Android Device Monitor我们可以得到应用的布局。(通过截屏的机制,所以相应的页面需要运行打开)

我们得到触发点击按钮的resourceid及其它信息:

 

四、运行的效果如下:

安装好basetest2之后,在手机中的无障碍里面,打开辅助服务。截图如下:我们这里用的是模拟器

打开辅助服务之后 ,当basetest1应用里面的toast弹出hello字符时,效果如下:

 

 

五、为也方便理解,我贴出basetest1的一些重要代码:

  • xml文件的一些布局内容:上述的两个重要按钮
<Button
    android:id="@+id/bt_send"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/bt_send" />

<Button
    android:id="@+id/bt_print_photo"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/print" />
  • MainActivity中处理上述按钮事件的代码:
bt_send.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Log.i(DEBUG_INFO, getString(R.string.warn_info));
        Toast.makeText(MainActivity.this, editText.getText().toString(), Toast.LENGTH_SHORT).show();
    }
});

bt_print.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(getResources(), R.drawable.idnexcontentbg, options);
        int imageHeight = options.outHeight;
        int imageWidth = options.outWidth;
        String imageType = options.outMimeType;
        options.inSampleSize = 4;
        options.inJustDecodeBounds = false;
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.idnexcontentbg, options);
        iv_photo.setImageBitmap(bitmap);
    }
});

 

友情链接

 

posted @ 2017-05-18 11:28  huhx  阅读(2201)  评论(0编辑  收藏  举报