赞
踩
Android10以上实现获取设备唯一标识,目前只支持华为和荣耀设备。实现原理:通过无障碍服务读取序列号界面。
- public class DeviceHelper implements Application.ActivityLifecycleCallbacks {
-
- static final String TAG = "WADQ_DeviceHelper";
-
- static final String ACTION_ACQUIRE_SERIAL_SUCCESS = "zwxuf.intent.action.ACQUIRE_SERIAL_SUCCESS";
-
- private static Handler mHandler = new Handler(Looper.getMainLooper());
- private boolean isMsgReceiverEnabled;
- private OnAcquireSerialListener mOnAcquireSerialListener;
-
- private Activity mActivity;
- private Application mApplication;
-
- public DeviceHelper(Activity mActivity) {
- this.mActivity = mActivity;
- mApplication = mActivity.getApplication();
- mApplication.registerActivityLifecycleCallbacks(this);
- }
-
- public void acquireSerial(OnAcquireSerialListener listener) {
- mOnAcquireSerialListener = listener;
- if (!isMsgReceiverEnabled) initMsgReceiver();
- AcquireSerialService.isSerialFound = false;
- AcquireSerialService.isStatusInfoFound = false;
- Intent intent = new Intent(Settings.ACTION_DEVICE_INFO_SETTINGS);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- mActivity.startActivity(intent);
- }
-
- private void releaseAcquireSerial() {
- List<Service> services = getServices();
- for (Service service : services) {
- if (service instanceof AcquireSerialService) {
- ((AcquireSerialService) service).release();
- break;
- }
- }
- }
-
- private void initMsgReceiver() {
- IntentFilter filter = new IntentFilter(ACTION_ACQUIRE_SERIAL_SUCCESS);
- mActivity.registerReceiver(mMsgReceiver, filter);
- isMsgReceiverEnabled = true;
- }
-
- private BroadcastReceiver mMsgReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String serial = intent.getStringExtra("serial");
- if (mOnAcquireSerialListener != null) {
- mOnAcquireSerialListener.onAcquireSerial(serial);
- }
- releaseMsgReciever();
- }
- };
-
- private void releaseMsgReciever() {
- if (isMsgReceiverEnabled) {
- mActivity.unregisterReceiver(mMsgReceiver);
- isMsgReceiverEnabled = false;
- }
- }
-
- public void release() {
- releaseMsgReciever();
- mApplication.unregisterActivityLifecycleCallbacks(this);
- releaseAcquireSerial();
- }
-
- public boolean canAcquireSerial() {
- return isServiceEnabled(mActivity, AcquireSerialService.class);
- }
-
- public void openAcquireSerialSettings(final int requestCode) {
- Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- try {
- mActivity.startActivityForResult(intent, requestCode);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- private static boolean isServiceEnabled(Context context, Class<? extends AccessibilityService> serviceClass) {
- if (serviceClass == null) {
- return false;
- }
- String serviceName = context.getPackageName() + "/" + serviceClass.getName();
- try {
- int enabled = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.ACCESSIBILITY_ENABLED);
- if (enabled == 1) {
- String service = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
- Log.i(TAG, service);
- return service != null && service.contains(serviceName);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- return false;
- }
-
-
- static Handler getHandler() {
- return mHandler;
- }
-
-
- @Override
- public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
-
- }
-
- @Override
- public void onActivityStarted(Activity activity) {
-
- }
-
- @Override
- public void onActivityResumed(Activity activity) {
-
- }
-
- @Override
- public void onActivityPaused(Activity activity) {
-
- }
-
- @Override
- public void onActivityStopped(Activity activity) {
-
- }
-
- @Override
- public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
-
- }
-
- @Override
- public void onActivityDestroyed(Activity activity) {
- if (activity == mActivity) {
- release();
- }
- }
-
- private static List<Service> getServices() {
- List<Service> services = new ArrayList<>();
- Object mActivityThread = getActivityThread();
- try {
- Class mActivityThreadClass = mActivityThread.getClass();
- Field mServicesField = mActivityThreadClass.getDeclaredField("mServices");
- mServicesField.setAccessible(true);
- Object mServices = mServicesField.get(mActivityThread);
- if (mServices instanceof Map) {
- Map<IBinder, Service> arrayMap = (Map) mServices;
- for (Map.Entry<IBinder, Service> entry : arrayMap.entrySet()) {
- Service service = entry.getValue();
- if (service != null) {
- services.add(service);
- }
- }
- }
- } catch (Throwable e) {
- e.printStackTrace();
- }
- return services;
- }
-
- private static Object getActivityThread() {
- try {
- Class ActivityThread = Class.forName("android.app.ActivityThread");
- Method currentActivityThread = ActivityThread.getMethod("currentActivityThread");
- currentActivityThread.setAccessible(true);
- return currentActivityThread.invoke(null);
- } catch (Throwable e) {
- e.printStackTrace();
- }
- return null;
- }
-
- }
- public class AcquireSerialService extends AccessibilityService {
-
-
- static boolean isStatusInfoFound;
- static boolean isSerialFound;
-
-
- @Override
- public void onAccessibilityEvent(AccessibilityEvent event) {
-
- if (event.getPackageName() == null || event.getClassName() == null) {
- return;
- }
-
- String packageName = event.getPackageName().toString();
- String className = event.getClassName().toString();
-
- final AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();
- if (nodeInfo != null) {
- if (!packageName.equals(getApplicationContext().getPackageName())) {
- enumChildNodeInfo(packageName, nodeInfo, 0);
- }
- }
- }
-
- @Override
- public void onInterrupt() {
-
- }
-
- private Runnable mScrollRunnalbe;
-
- private void enumChildNodeInfo(String packageName, AccessibilityNodeInfo nodeInfo, int level) {
- int count = nodeInfo.getChildCount();
- if (count > 0) {
- for (int i = 0; i < count; i++) {
- final AccessibilityNodeInfo childNodeInfo = nodeInfo.getChild(i);
- if (childNodeInfo == null) continue;
- if (childNodeInfo.isScrollable()) {
- childNodeInfo.performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
- }
- if (!isSerialFound) {
- String serial = getSerialByNodeInfo(packageName, childNodeInfo);
- if (serial != null && !serial.isEmpty()) {
- //获取到sn
- Log.i(DeviceHelper.TAG, serial);
- Intent intent = new Intent(DeviceHelper.ACTION_ACQUIRE_SERIAL_SUCCESS);
- intent.putExtra("serial", serial);
- sendBroadcast(intent);
- performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK);
- DeviceHelper.getHandler().postDelayed(new Runnable() {
- @Override
- public void run() {
- performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK);
- release();
- }
- }, 200);
- return;
- }
- enumChildNodeInfo(packageName, childNodeInfo, level + 1);
- }
- }
- }
- nodeInfo.recycle();
- }
-
-
- private String getSerialByNodeInfo(String packageName, AccessibilityNodeInfo nodeInfo) {
- if (nodeInfo.getText() == null) {
- return null;
- }
- String text = nodeInfo.getText().toString();
- if (text.equals("序列号")) {
- isStatusInfoFound = true;
- isSerialFound = true;
- if (mScrollRunnalbe != null) {
- DeviceHelper.getHandler().removeCallbacks(mScrollRunnalbe);
- mScrollRunnalbe = null;
- }
- return getValue(nodeInfo);
- } else if (packageName.equals("com.android.settings") && (text.equals("状态信息") || text.equals("状态消息")) && !isStatusInfoFound) {
- isStatusInfoFound = true;
- AccessibilityNodeInfo statusInfoParent = nodeInfo.getParent();
- while (statusInfoParent != null && !statusInfoParent.isClickable()) {
- statusInfoParent = statusInfoParent.getParent();
- }
- if (statusInfoParent != null) {
- final AccessibilityNodeInfo finalStatusInfoParent = statusInfoParent;
- DeviceHelper.getHandler().postDelayed(new Runnable() {
- @Override
- public void run() {
- finalStatusInfoParent.performAction(AccessibilityNodeInfo.ACTION_CLICK);
- }
- }, 200);
- }
- }
- return null;
- }
-
- private String getValue(AccessibilityNodeInfo nodeInfo) {
- AccessibilityNodeInfo snLayout = nodeInfo.getParent();
- if (snLayout != null) {
- while (true) {
- List<AccessibilityNodeInfo> snSummaryList = snLayout.findAccessibilityNodeInfosByViewId("android:id/summary");
- if (snSummaryList != null && !snSummaryList.isEmpty()) {
- AccessibilityNodeInfo snSummary = snSummaryList.get(0);
- if (snSummary != null && snSummary.getText() != null) {
- return snSummary.getText().toString();
- }
- }
- snLayout = snLayout.getParent();
- if (snLayout == null) {
- break;
- }
- }
- }
- return null;
- }
-
-
- private String getNodeText(AccessibilityNodeInfo nodeInfo) {
- if (nodeInfo != null && nodeInfo.getText() != null) {
- return nodeInfo.getText().toString();
- } else {
- return null;
- }
- }
-
-
- public void release() {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
- disableSelf();
- }
- }
- }
- public class MainActivity extends AppCompatActivity implements View.OnClickListener {
-
- private DeviceHelper mDeviceHelper;
- private TextView tv_serial, tv_phone;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
- tv_serial = findViewById(R.id.tv_serial);
-
- mDeviceHelper = new DeviceHelper(this);
- }
-
- @Override
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.bn_get_serial:
- getSerial();
- break;
- }
- }
-
- private void getSerial() {
- if (!mDeviceHelper.canAcquireSerial()) {
- new AlertDialog.Builder(this)
- .setMessage("没有开启无障碍服务")
- .setPositiveButton("去开启", new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- mDeviceHelper.openAcquireSerialSettings(1000);
- }
- })
- .setNegativeButton("取消", null)
- .create()
- .show();
- return;
- }
- mDeviceHelper.acquireSerial(new OnAcquireSerialListener() {
- @Override
- public void onAcquireSerial(String serial) {
- //Toast.makeText(MainActivity.this, serial, Toast.LENGTH_SHORT).show();
- tv_serial.setText("sn:" + serial);
- }
- });
- }
-
-
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。