• QQ
  • nahooten@sina.com
  • 常州市九洲新世界花苑15-2

Android

Android微信抢红包插件说明和开辟实现

原创内容,转载请注明原文网址:http://homeqin.cn/a/wenzhangboke/jishutiandi/Android/2019/0925/659.html

 
一、媒介
 
自从常州微信小程序开发昨年中微信增加抢红包的功效,微信的电商之旅算是正式首先正式火爆起来。但是作为Android开辟者来说,咱们在抢红包的同时认识到了许多题目,即是手动去抢红包的速率慢了,固然这些有许多缘故导致了。大概是网络的缘故,而且这个也是非常大的缘故。但是其余的不可纰漏的成分也是要思量到进入的,好比在手机充电锁屏的时分,咱们并不晓得有人曾经首先发红包了,辣么这时分也是让咱们丧失了一大量红包的缘故。辣么关于网络的题目,咱们开辟者大概用相关手艺无法办理(固然在Google和Facebook看来的话,他们的理想是能够在职何处所都能连接互联网,固然在偏僻的屯子也是,但是咱们等候他们有一天能够遍及开来。到时分才是真确互联网)。扯得有点远了。咱们回来到正题,今天咱们来看看使用手艺来办理其余非网络题目。在充电锁屏的时分也能够自动帮咱们抢红包。而且你要晓得,机械抢红包的精确率是100%的,这个也能够即是人和机械的差别。辣么保证抢得精确率是100%的话,那就依附于咱们常州网站开发建设高效精确的算法实现了。底下就来看看道理实现。
 
 
当昨年我看到抢红包辣么火爆的时分,其时作为一个开辟者内心是何等渴慕开辟一个插件出来,但是其时咱们能想到的即是使用:
adb shell monkey
 
号令去模仿点击屏幕,但是那种方法有一个题目即是是无脉络的盲目点击,以是险些会发现晚点,点击胜利率极端低下。以是其时就没有想到其余方法了,由于近来做了有关辅助功效相关的事情的时分,辣么就发现这个功效能够用于抢红包。
 
 
实在现在咱们能够去各大市场搜刮一下看到,有许多抢红包的插件了。固然咱们并不是用于商业化,这里只是来说明一下道理。咱们会发现那些插件都有一个配合的特色是:第一步都是引导用户去开启辅助功效。
 
 
两道理说明
 
关于辅助功效(AccessibilityService),要是又不打听的同窗能够去Google一下,这个功效实在很有用的,但是他的发现的出发点是给那些肢体上有停滞的人使用的,好比手指不健全的用户,怎么才气滑动屏幕,然后翻开一个运用呢?辣么辅助功效即是干这些事,他的功效实在即是能够概括两句话:
 
 
 
第一、寻找到咱们想要的View节点
 
 
 
第两然后模仿点击,实现特定功效
 
 
 
咱们晓得Android中的View体系是一个树形布局,辣么每一个View即是一个节点。以是咱们能够查找到指定的节点,辣么咱们该若何查找到咱们想要的节点呢?这里咱们先看一下辅助功效(AccessibilityService)的用法
 
 
 
第一步、咱们游戏开发运营需求集成AccessibilityService类
 
咱们需求自定一个Service然后秉承AccessibilityService,固然还需求在AndroidManifest.xml中申明这个服无:
 
 
 
 
 
 
 
 
 
 
 
第二步、申明权限和配置
 
这个服无需求说明一个权限:
 
 
 
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
 
固然还要一个meta-data的申明,这个申明是对这个AccessibilityService的配置。咱们看一下配置文件内容:
 
 
 
<?xml version="1.0" encoding="utf-8"?>
 
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
 
    android:accessibilityEventTypes="typeNotificationStateChanged|typeWindowStateChanged"
 
    android:accessibilityFeedbackType="feedbackGeneric"
 
    android:accessibilityFlags="flagDefault"
 
    android:canRetrieveWindowContent="true"
 
    android:description="@string/desc"
 
    android:notificationTimeout="100"
 
    android:packageNames="com.tencent.mm" />
 
这里咱们看到有许多选项,咱们看一下常用的几个属性:
 
 
 
1、android:accessibilityEventTypes="typeAllMask"
 
看属性名也差未几能够清晰,这个是用来配置相应事件的范例,typeAllMask固然即是相应全部范例的事件了。固然另有单击、长按、滑动等。
 
 
 
2、android:accessibilityFeedbackType="feedbackSpoken"
 
配置回馈给用户的方法,有语音播出和振动。能够配置少许TTS引擎,让它实现发音。
 
 
 
3、android:notificationTimeout="100"
 
相应光阴的配置就不消多说了
 
 
 
4、android:packageNames="com.example.android.apis"
 
能够指定相应某个运用的事件,这里由于要相应全部运用的事件,以是不填,默认即是相应全部运用的事件。好比咱们写一个微信抢红包的辅助程序,就能够在这里填写微信的包名,便能够监听微信产生的事件了。
 
 
 
 
 
 
 
留意:
 
 
 
1、咱们这些配置信息除了在xml中定义,同样也能够在代码中定义,咱们普通都是在onServiceConnected()方法里进行
 
 
 
 
 
@Override
 
protected void onServiceConnected() {
 
AccessibilityServiceInfo info = getServiceInfo();
 
info.eventTypes = AccessibilityEvent.TYPES_ALL_MASK;
 
info.feedbackType = AccessibilityServiceInfo.FEEDBACK_SPOKEN;  
 
info.notificationTimeout = 100;  
 
setServiceInfo(info); 
 
info.packageNames = new String[]{"xxx.xxx.xxx", "yyy.yyy.yyy","...."};
 
setServiceInfo(info);
 
super.onServiceConnected();
 
}
 
 
 
2、这里咱们常州手游开发普通都会在这里写上咱们需求监听的运用的包名,但是偶然候咱们需求监听多个运用,辣么这时分咱们该怎么办呢?
 
 
 
这时分咱们能够这么做:
 
 
 
第一种:咱们在代码中注册多个运用的包名,从而能够监听多个运用
 
 
 
@Override
 
protected void onServiceConnected() {
 
AccessibilityServiceInfo info = getServiceInfo();
 
//这里能够配置多个包名,监听多个运用
 
info.packageNames = new String[]{"xxx.xxx.xxx", "yyy.yyy.yyy","...."};
 
setServiceInfo(info);
 
super.onServiceConnected();
 
}
 
 
 
第二种:咱们在onAccessibilityEvent事件监听的方法中做包名的过滤(这种方法非常常用)
 
 
 
@Override
 
public void onAccessibilityEvent(AccessibilityEvent event) {
 
String pkgName = event.getPackageName().toString();
 
if("xxx.xxx.xxx".equals(pkgName)){
 
 
 
}else if("yyy.yyy.yyy".equals(pkgName)){
 
 
 
}else if("....".equals(pkgName)){
 
 
 
}
 
}
 
 
 
 
 
第三步、在onAccessibilityEvent方法中监听指定的事件
 
好比咱们需求监听有关照栏消息的事件:
 
 
 
@Override
 
public void onAccessibilityEvent(AccessibilityEvent event) {
 
int eventType = event.getEventType();
 
switch (eventType) {
 
case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED:
 
//.......
 
}
 
}
 
这个事件范例许多的,咱们能够查看AccessibilityEvent类的源码:
 
@Deprecated
 
public static final int MAX_TEXT_LENGTH = 500;
 
 
 
/**
 
 * Represents the event of clicking on a {@link android.view.View} like
 
 * {@link android.widget.Button}, {@link android.widget.CompoundButton}, etc.
 
 */
 
public static final int TYPE_VIEW_CLICKED = 0x00000001;
 
 
 
/**
 
 * Represents the event of long clicking on a {@link android.view.View} like
 
 * {@link android.widget.Button}, {@link android.widget.CompoundButton}, etc.
 
 */
 
public static final int TYPE_VIEW_LONG_CLICKED = 0x00000002;
 
 
 
/**
 
 * Represents the event of selecting an item usually in the context of an
 
 * {@link android.widget.AdapterView}.
 
 */
 
public static final int TYPE_VIEW_SELECTED = 0x00000004;
 
 
 
/**
 
 * Represents the event of setting input focus of a {@link android.view.View}.
 
 */
 
public static final int TYPE_VIEW_FOCUSED = 0x00000008;
 
 
 
/**
 
 * Represents the event of changing the text of an {@link android.widget.EditText}.
 
 */
 
public static final int TYPE_VIEW_TEXT_CHANGED = 0x00000010;
 
 
 
/**
 
 * Represents the event of opening a {@link android.widget.PopupWindow},
 
 * {@link android.view.Menu}, {@link android.app.Dialog}, etc.
 
 */
 
public static final int TYPE_WINDOW_STATE_CHANGED = 0x00000020;
 
 
 
/**
 
 * Represents the event showing a {@link android.app.Notification}.
 
 */
 
public static final int TYPE_NOTIFICATION_STATE_CHANGED = 0x00000040;
 
 
 
/**
 
 * Represents the event of a hover enter over a {@link android.view.View}.
 
 */
 
public static final int TYPE_VIEW_HOVER_ENTER = 0x00000080;
 
 
 
/**
 
 * Represents the event of a hover exit over a {@link android.view.View}.
 
 */
 
public static final int TYPE_VIEW_HOVER_EXIT = 0x00000100;
 
 
 
/**
 
 * Represents the event of starting a touch exploration gesture.
 
 */
 
public static final int TYPE_TOUCH_EXPLORATION_GESTURE_START = 0x00000200;
 
 
 
/**
 
 * Represents the event of ending a touch exploration gesture.
 
 */
 
public static final int TYPE_TOUCH_EXPLORATION_GESTURE_END = 0x00000400;
 
 
 
/**
 
 * Represents the event of changing the content of a window and more
 
 * specifically the sub-tree rooted at the event's source.
 
 */
 
public static final int TYPE_WINDOW_CONTENT_CHANGED = 0x00000800;
 
 
 
/**
 
 * Represents the event of scrolling a view.
 
 */
 
public static final int TYPE_VIEW_SCROLLED = 0x00001000;
 
 
 
/**
 
 * Represents the event of changing the selection in an {@link android.widget.EditText}.
 
 */
 
public static final int TYPE_VIEW_TEXT_SELECTION_CHANGED = 0x00002000;
 
 
 
/**
 
 * Represents the event of an application making an announcement.
 
 */
 
public static final int TYPE_ANNOUNCEMENT = 0x00004000;
 
 
 
/**
 
 * Represents the event of gaining accessibility focus.
 
 */
 
public static final int TYPE_VIEW_ACCESSIBILITY_FOCUSED = 0x00008000;
 
 
 
/**
 
 * Represents the event of clearing accessibility focus.
 
 */
 
public static final int TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED = 0x00010000;
 
 
 
/**
 
 * Represents the event of traversing the text of a view at a given movement granularity.
 
 */
 
public static final int TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY = 0x00020000;
 
 
 
/**
 
 * Represents the event of beginning gesture detection.
 
 */
 
public static final int TYPE_GESTURE_DETECTION_START = 0x00040000;
 
 
 
/**
 
 * Represents the event of ending gesture detection.
 
 */
 
public static final int TYPE_GESTURE_DETECTION_END = 0x00080000;
 
 
 
/**
 
 * Represents the event of the user starting to touch the screen.
 
 */
 
public static final int TYPE_TOUCH_INTERACTION_START = 0x00100000;
 
 
 
/**
 
 * Represents the event of the user ending to touch the screen.
 
 */
 
public static final int TYPE_TOUCH_INTERACTION_END = 0x00200000;
 
 
 
/**
 
 * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event:
 
 * The type of change is not defined.
 
 */
 
public static final int CONTENT_CHANGE_TYPE_UNDEFINED = 0x00000000;
 
 
 
/**
 
 * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event:
 
 * A node in the subtree rooted at the source node was added or removed.
 
 */
 
public static final int CONTENT_CHANGE_TYPE_SUBTREE = 0x00000001;
 
 
 
/**
 
 * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event:
 
 * The node's text changed.
 
 */
 
public static final int CONTENT_CHANGE_TYPE_TEXT = 0x00000002;
 
 
 
/**
 
 * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event:
 
 * The node's content description changed.
 
 */
 
public static final int CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION = 0x00000004;
 
这里有许多事件,这些事件咱们经历名字就能够看出来有许多咱们大概都晓得,好比当窗口产生变更的时分,当某个View被点击了,被转动了等消息都是能够晓得的。辣么咱们有了这些事件咱们就能够做咱们的事情了,由于咱们晓得事件触发了。
 
 
 
 
 
 
 
第四步、查找到咱们想要处理的节点View
 
这里体系提供了两个方法让咱们来进行查找想要的节点View
 
 
 
第一种是经历节点View的Text内容来查找
 
 
 
findAccessibilityNodeInfosByText("查找内容")
 
 
 
这种方法查找,即是像TextView,Button等View有文本内容的,能够使用这种方法快速的找到。
 
 
 
第二种是经历节点View在xml布局中的id名称
 
 
 
findAccessibilityNodeInfosByViewId("@id/xxx")
 
 
 
这个普通很难晓得,但是咱们在查找体系控件的时分或是能够做的,由于体系的控件的id是能够晓得的,而且是同一的。
 
(关于这两个方法咱们在写网络爬虫程序的时分大概晓得,在html中经历tag/name/id等信息能够找到一个节点,道理都相似)
 
 
 
 
 
 
 
第五步、模仿点击指定事件
 
咱们找到咱们想要的View节点,调用方法模仿事件:
 
 
 
performAction(AccessibilityNodeInfo.ACTION_CLICK)
 
 
 
调用这个方法即可,固然这里的参数即是指定事件的名称,这个和AccessibilityEvent中监听的那些事件是逐一对应的,这里是模仿点击事件,咱们固然能够模仿View的转动事件,长按事件等。
 
 
 
 
 
 
 
三、实战案例:微信抢红包插件
 
上头咱们就说明了一个辅助功效开辟的详细步骤,辣么底下就经历一个简单的例子,来实战一下
 
 
 
例子:微信自动抢红包插件
 
 
 
 
 
 
 
首先咱们来看一下微信抢红包的流程:
 
 
 
第一步、咱们在关照栏会汲取到一个微信红包的消息
 
 
 
咱们监听关照栏事件:
 
 
 
AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED
 
 
 
然后查看关照栏的消息中是否有:[微信红包]  的文本内容
 
 
 
是的话,就走进来第二步
 
 
 
 
 
 
 
第二步、咱们模仿翻开关照栏
 
 
 
翻开微信以下图:
 
 
 
 
 
 
 
咱们查找包含有:领取红包 的文本内容的节点View,然后模仿点击,进来第三步:
 
 
 
 
 
 
 
第三步、咱们点击领取红包
 
 
 
以下图:
 
 
 
这里咱们常州游戏开发培训在查找包含有:拆红包 的文本内容的节点View,然后模仿点击
 
 
 
 
 
 
 
 
 
 
 
底下咱们来看一下代码中的详细实现:
 
 
 
package krelve.demo.rob;
 
 
 
import java.util.List;
 
 
 
import android.accessibilityservice.AccessibilityService;
 
import android.accessibilityservice.AccessibilityServiceInfo;
 
import android.annotation.SuppressLint;
 
import android.app.Notification;
 
import android.app.PendingIntent;
 
import android.app.PendingIntent.CanceledException;
 
import android.util.Log;
 
import android.view.accessibility.AccessibilityEvent;
 
import android.view.accessibility.AccessibilityNodeInfo;
 
 
 
public class RobMoney extends AccessibilityService {
 
 
 
@Override
 
public void onAccessibilityEvent(AccessibilityEvent event) {
 
int eventType = event.getEventType();
 
switch (eventType) {
 
//第一步:监听关照栏消息
 
case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED:
 
List<CharSequence> texts = event.getText();
 
if (!texts.isEmpty()) {
 
for (CharSequence text : texts) {
 
String content = text.toString();
 
Log.i("demo", "text:"+content);
 
if (content.contains("[微信红包]")) {
 
//模仿翻开关照栏消息
 
if (event.getParcelableData() != null
 
&& 
 
event.getParcelableData() instanceof Notification) {
 
Notification notification = (Notification) event.getParcelableData();
 
PendingIntent pendingIntent = notification.contentIntent;
 
try {
 
pendingIntent.send();
 
} catch (CanceledException e) {
 
e.printStackTrace();
 
}
 
}
 
}
 
}
 
}
 
break;
 
//第二步:监听是否进来微信红包消息界面
 
case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
 
String className = event.getClassName().toString();
 
if (className.equals("com.tencent.mm.ui.LauncherUI")) {
 
//首先抢红包
 
getPacket();
 
} else if (className.equals("com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyReceiveUI")) {
 
//首先翻开红包
 
openPacket();
 
}
 
break;
 
}
 
}
 
 
 
/**
 
* 查找到
 
*/
 
@SuppressLint("NewApi")
 
private void openPacket() {
 
AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();
 
if (nodeInfo != null) {
 
List<AccessibilityNodeInfo> list = nodeInfo
 
.findAccessibilityNodeInfosByText("抢红包");
 
for (AccessibilityNodeInfo n : list) {
 
n.performAction(AccessibilityNodeInfo.ACTION_CLICK);
 
}
 
}
 
 
 
}
 
 
 
@SuppressLint("NewApi")
 
private void getPacket() {
 
AccessibilityNodeInfo rootNode = getRootInActiveWindow();
 
recycle(rootNode);
 
}
 
 
 
/**
 
* 打印一个节点的布局
 
* @param info
 
*/
 
@SuppressLint("NewApi")
 
public void recycle(AccessibilityNodeInfo info) {  
 
        if (info.getChildCount() == 0) { 
 
        if(info.getText() != null){
 
        if("领取红包".equals(info.getText().toString())){
 
        //这里有一个题目需求留意,即是需求找到一个能够点击的View
 
                Log.i("demo", "Click"+",isClick:"+info.isClickable());
 
                info.performAction(AccessibilityNodeInfo.ACTION_CLICK);
 
                AccessibilityNodeInfo parent = info.getParent();
 
                while(parent != null){
 
                Log.i("demo", "parent isClick:"+parent.isClickable());
 
                if(parent.isClickable()){
 
                parent.performAction(AccessibilityNodeInfo.ACTION_CLICK);
 
                break;
 
                }
 
                parent = parent.getParent();
 
                }
 
               
 
            }
 
        }
 
       
 
        } else {  
 
            for (int i = 0; i < info.getChildCount(); i++) {  
 
                if(info.getChild(i)!=null){  
 
                    recycle(info.getChild(i));  
 
                }  
 
            }  
 
        }  
 
    }  
 
 
 
@Override
 
public void onInterrupt() {
 
}
 
 
 
 
 
}
 
代码没什么好说的了,按照咱们以前说的三个步骤来就能够了,但是这里需求留意点细节上的题目:
 
1、咱们在监听到关照栏的消息的时分,调用以下代码来进行关照栏的消息点击
 
 
 
 
 
if (content.contains("[微信红包]")) {
 
//模仿翻开关照栏消息
 
if (event.getParcelableData() != null
 
&& 
 
event.getParcelableData() instanceof Notification) {
 
Notification notification = (Notification) event.getParcelableData();
 
PendingIntent pendingIntent = notification.contentIntent;
 
try {
 
pendingIntent.send();
 
} catch (CanceledException e) {
 
e.printStackTrace();
 
}
 
}
 
}
 
 
 
2、咱们在模仿点击关照栏消息以后,或是需求监听:AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED 这个事件,这个事件咱们以后会时常用到,这个事件即是在窗口产生改变的时分发出来的事件,很常用的,好比咱们能够经历这个事件来监听TopActivity,然后得到包名,这也是一个实现运用锁的一个道理。
 
 
 
 
 
3、咱们在查找领取红包的时分,模仿点击的时分做了一个事情,即是从“领取红包”文本的控件View网上查找,查找到一个能够点击的View出来,然后模仿点击
 
 
 
if(info.getText() != null){
 
if("领取红包".equals(info.getText().toString())){
 
//这里有一个题目需求留意,即是需求找到一个能够点击的View
 
Log.i("demo", "Click"+",isClick:"+info.isClickable());
 
info.performAction(AccessibilityNodeInfo.ACTION_CLICK);
 
AccessibilityNodeInfo parent = info.getParent();
 
while(parent != null){
 
Log.i("demo", "parent isClick:"+parent.isClickable());
 
if(parent.isClickable()){
 
parent.performAction(AccessibilityNodeInfo.ACTION_CLICK);
 
break;
 
}
 
parent = parent.getParent();
 
}
 
 
 
}
 
}
 
这里为何这么做,实在道理很简单,由于咱们不晓得微信他的界面布局,也不晓得他对哪一个View进行了setOnClickListener。咱们能够写一个例子,performAction方法只对换用了setOnClickListener方法的View模仿点击才有用,实在看View的源码也是能够看出来的.这里就未几注释了。以是咱们就需求得到一个View节点以后,从下往上找,直到找到一个能够click的View为止。
 
 
 
手艺延展:
 
 
 
咱们实在还能够使用DDMS对象里的Dump View Hierarchy For UI Automator 去说明微信UI布局,这个方法也是我背面才发现的,比上头的代码更有用,以下图:
 
 
 
 
 
 
 
 
 
 
 
这里咱们能够看到View的详细布局,另有每个View的属性,另有很紧张的信息resource-id,这个即是咱们在xml中定义的id,这个id咱们也能够使用前方说到的findAccessibilityNodeInfosByViewId("@id/xxx")来查找控件了
 
 
 
这个也算是学习了,学会使用DDMS来说明View布局。
 
 
 
 
 
 
 
项目下载:http://download.csdn.net/detail/jiangwei0910410003/9156347
 
 
 
 
 
 
 
四、延展
 
关于微信抢红包的道理说明上头曾经做了说明了,但是要想做到极致,这里另有许多题目的,好比咱们还需求过滤少许曾经领取过的红包,这样的话服从也是很高的。这个都是算法精确的题目了,我想在这里说的是,咱们不但能够用辅助功效来实现抢红包,还能够实现许多功效,好比
 
 
 
1、缄默安置
 
 
 
关于缄默安置的实现,以前的做法是,拜见这篇文章:
 
 
 
http://blog.csdn.net/jiangwei0910410003/article/details/36427963
 
 
 
在这篇文章中我说明了许多方法来实现缄默安置,但是都是有一个限制,那即是root,大概是获得到systemId。但是对于这两个请求,咱们大概很可贵到,辣么现在要是有了辅助功效,咱们就好做了:
 
 
 
 
 
 
 
咱们能够监听体系的这个安置界面,然后得到安置节点View,然后模仿点击即可,卸载也是同样的道理
 
 
 
 
 
 
 
2、强迫休止运用
 
 
 
咱们晓得Android中休止运用有许多方法,kill进程,stopService,但是这些方法,有少许运用它们都是有对策的,辣么咱们以前用到的强迫休止的方法是获得root权限调用体系的forceStop的api来休止,但是条件或是有root。辣么现在要是咱们有了辅助功效的话,咱们能够这么做:
 
 
 
 
 
 
 
咱们能够监听体系的运用详情页面,然后找到:收场运转的节点View,然后模仿点击即可
 
 
 
 
 
 
 
固然上头我就说了两个简单的例子,另有许多辅助功效都是能够做的。他的作用即是不需求root权限。但是他也是需求用户授权的:
 
 
 
 
 
 
 
要是用户没有授权的话,辣么全部的事情都没办法首先了,以是说这个方法也不是万能的。固然说句题外话:有了辅助功效的话,他的凶险性比root以后的凶险性更大,好比咱们上头的抢红包插件,实在咱们稍作点窜,就能够获得微信通信录信息,微信支付的暗号。这些事都是能够做的,以是说,咱们在作为用户的时分,进行授权的时分或是需求三思而后行。
 
 
 
 
 
 
 
五、总结
 
关于手机App外包辅助功效,以前没有太多的打仗,是在一次事情顶用到了这个功效,就去学习了一下,作为本人的乐趣,就延展了学习了若何写一个微信抢红包的插件,同时能够思量了使用辅助功效能够做咱们以前需求root做的事情。固然辅助功效是谷歌对于肢体上有停滞的人开辟出来的一个功效,咱们开辟者大概使用这个功效,能够做一下产物的拓展功效,固然这些是谷歌没有想到的事情,但是这个起码是咱们开辟者在以后的开辟道路上的一个办理题目的一个办法和途径,服膺此功效!
 

上篇:上一篇:getSharedPreferences用法
下篇:下一篇:Android之Fragment--ListFragment的应用