为什么Android版微信微店在哪里进入能自动进入各个手机厂商的白名单

1878被浏览165499分享邀请回答60985 条评论分享收藏感谢收起9210 条评论分享收藏感谢收起查看更多回答Android微信自动回复功能 - 简书
Android微信自动回复功能
Android微信自动回复功能
本文原创,转载请经过本人准许。
写在前面:
最近接到老大的一个需求,要求在手机端拦截微信的通知(Notification),从而获得联系人和内容。之后将联系人和内容发送到我们的硬件产品上,展示出来之后,再将我们想回复内容传给微信,并且发送给相应联系人。
老大还提示我需要用AccessibilityService去实现它,当然在此之前我并不知道AccessibilityService是什么鬼,不过没关系,
just do IT !
AccessibilityService
上面这个链接是AccessibilityService的官方文档,可以翻墙点进去了解下,我再给大家总结一下:
AccessibilityService是Android系统框架提供给安装在设备上应用的一个可选的导航反馈特性。AccessibilityService 可以替代应用与用户交流反馈,比如将文本转化为语音提示,或是用户的手指悬停在屏幕上一个较重要的区域时的触摸反馈等。
如果感觉上面的描述比较抽象,没关系,也许你见过下面这张图:
辅助功能中的服务
打开你手机的设置--辅助功能中,有很多APP提供的服务,他们都是基于AccessibilityService编写的,AccessibilityService可以侦听你的点击,长按,手势,通知栏的变化等。并且你可以通过很多种方式找到窗体中的EditText,Button等组件,去填充他们,去点击他们来帮你实现自动化的功能。
像360助手的自动安装功能,它就是侦听着系统安装的APP,然后找到“安装”按钮,实现了自动点击。微信自动抢红包功能,实现方式都是如此。
配置AccessibilityService
首先我们在res文件夹下创建xml文件夹,然后创建一个名为auto_reply_service_config的文件,一会我们会在清单文件中引用它。
AccessibilityService配置文件
&accessibility-service
xmlns:android="/apk/res/android"
android:accessibilityEventTypes="typeNotificationStateChanged|typeWindowStateChanged"
android:accessibilityFeedbackType="feedbackGeneric"
android:accessibilityFlags="flagDefault"
android:canRetrieveWindowContent="true"
android:description="@string/accessibility_description"
android:notificationTimeout="100"
android:packageNames="com.tencent.mm" /&
这个文件表示我们对AccessibilityService服务未来侦听的行为做了一些配置,比如 typeNotificationStateChanged 和 typeWindowStateChanged 表示我们需要侦听通知栏的状态变化和窗体状态改变。android:packageNames="com.tencent.mm" 这是微信的包名,表示我们只关心微信这一个应用。
代码不打算带着大家一行一行看了,如果有不明白的,去看看文档,或者下面回复我,我给大家解答~
创建AccessibilityService
下面贴出AccessibilityService类的全部代码,注释还算详尽,如有疑问,下方回复。
package com.ileja.
import android.accessibilityservice.AccessibilityS
import android.annotation.SuppressL
import android.app.ActivityM
import android.app.KeyguardM
import android.app.N
import android.app.PendingI
import android.content.ClipD
import android.content.ClipboardM
import ponentN
import android.content.C
import android.content.I
import android.os.B
import android.os.H
import android.os.PowerM
import android.text.TextU
import android.view.KeyE
import android.view.accessibility.AccessibilityE
import android.view.accessibility.AccessibilityNodeI
import java.io.IOE
import java.util.L
public class AutoReplyService extends AccessibilityService {
private final static String MM_PNAME = "com.tencent.mm";
boolean hasAction =
boolean locked =
boolean background =
AccessibilityNodeInfo itemN
private KeyguardManager.KeyguardL
private Handler handler = new Handler();
* 必须重写的方法,响应各种事件。
* @param event
public void onAccessibilityEvent(final AccessibilityEvent event) {
int eventType = event.getEventType();
android.util.Log.d("maptrix", "get event = " + eventType);
switch (eventType) {
case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED:// 通知栏事件
android.util.Log.d("maptrix", "get notification event");
List&CharSequence& texts = event.getText();
if (!texts.isEmpty()) {
for (CharSequence text : texts) {
String content = text.toString();
if (!TextUtils.isEmpty(content)) {
if (isScreenLocked()) {
wakeAndUnlock();
android.util.Log.d("maptrix", "the screen is locked");
if (isAppForeground(MM_PNAME)) {
background =
android.util.Log.d("maptrix", "is mm in foreground");
sendNotifacationReply(event);
handler.postDelayed(new Runnable() {
public void run() {
sendNotifacationReply(event);
if (fill()) {
background =
android.util.Log.d("maptrix", "is mm in background");
sendNotifacationReply(event);
android.util.Log.d("maptrix", "the screen is unlocked");
// 监听到微信红包的notification,打开通知
if (isAppForeground(MM_PNAME)) {
background =
android.util.Log.d("maptrix", "is mm in foreground");
sendNotifacationReply(event);
handler.postDelayed(new Runnable() {
public void run() {
if (fill()) {
background =
android.util.Log.d("maptrix", "is mm in background");
sendNotifacationReply(event);
case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
android.util.Log.d("maptrix", "get type window down event");
if (!hasAction)
itemNodeinfo =
String className = event.getClassName().toString();
if (className.equals("com.tencent.mm.ui.LauncherUI")) {
if (fill()) {
if(itemNodeinfo != null){
itemNodeinfo.performAction(AccessibilityNodeInfo.ACTION_CLICK);
handler.postDelayed(new Runnable() {
public void run() {
if (fill()) {
back2Home();
release();
hasAction =
//bring2Front();
back2Home();
release();
hasAction =
* 寻找窗体中的“发送”按钮,并且点击。
@SuppressLint("NewApi")
private void send() {
AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();
if (nodeInfo != null) {
List&AccessibilityNodeInfo& list = nodeInfo
.findAccessibilityNodeInfosByText("发送");
if (list != null && list.size() & 0) {
for (AccessibilityNodeInfo n : list) {
if(n.getClassName().equals("android.widget.Button") && n.isEnabled())
n.performAction(AccessibilityNodeInfo.ACTION_CLICK);}
List&AccessibilityNodeInfo& liste = nodeInfo
.findAccessibilityNodeInfosByText("Send");
if (liste != null && liste.size() & 0) {
for (AccessibilityNodeInfo n : liste) {
if(n.getClassName().equals("android.widget.Button") && n.isEnabled())
n.performAction(AccessibilityNodeInfo.ACTION_CLICK);}
pressBackButton();
* 模拟back按键
private void pressBackButton(){
Runtime runtime = Runtime.getRuntime();
runtime.exec("input keyevent " + KeyEvent.KEYCODE_BACK);
} catch (IOException e) {
e.printStackTrace();
* @param event
private void sendNotifacationReply(AccessibilityEvent event) {
hasAction =
if (event.getParcelableData() != null
&& event.getParcelableData() instanceof Notification) {
Notification notification = (Notification) event
.getParcelableData();
String content = notification.tickerText.toString();
String[] cc = content.split(":");
name = cc[0].trim();
scontent = cc[1].trim();
android.util.Log.i("maptrix", "sender name =" + name);
android.util.Log.i("maptrix", "sender content =" + scontent);
PendingIntent pendingIntent = notification.contentI
pendingIntent.send();
} catch (PendingIntent.CanceledException e) {
e.printStackTrace();
@SuppressLint("NewApi")
private boolean fill() {
AccessibilityNodeInfo rootNode = getRootInActiveWindow();
if (rootNode != null) {
return findEditText(rootNode, "正在忙,稍后回复你");
private boolean findEditText(AccessibilityNodeInfo rootNode, String content) {
int count = rootNode.getChildCount();
android.util.Log.d("maptrix", "root class=" + rootNode.getClassName() + ","+ rootNode.getText()+","+count);
for (int i = 0; i & i++) {
AccessibilityNodeInfo nodeInfo = rootNode.getChild(i);
if (nodeInfo == null) {
android.util.Log.d("maptrix", "nodeinfo = null");
android.util.Log.d("maptrix", "class=" + nodeInfo.getClassName());
android.util.Log.e("maptrix", "ds=" + nodeInfo.getContentDescription());
if(nodeInfo.getContentDescription() != null){
int nindex = nodeInfo.getContentDescription().toString().indexOf(name);
int cindex = nodeInfo.getContentDescription().toString().indexOf(scontent);
android.util.Log.e("maptrix", "nindex=" + nindex + " cindex=" +cindex);
if(nindex != -1){
itemNodeinfo = nodeI
android.util.Log.i("maptrix", "find node info");
if ("android.widget.EditText".equals(nodeInfo.getClassName())) {
android.util.Log.i("maptrix", "==================");
Bundle arguments = new Bundle();
arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
arguments.putBoolean(AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN,
nodeInfo.performAction(AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY,
arguments);
nodeInfo.performAction(AccessibilityNodeInfo.ACTION_FOCUS);
ClipData clip = ClipData.newPlainText("label", content);
ClipboardManager clipboardManager = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
clipboardManager.setPrimaryClip(clip);
nodeInfo.performAction(AccessibilityNodeInfo.ACTION_PASTE);
if (findEditText(nodeInfo, content)) {
public void onInterrupt() {
* 判断指定的应用是否在前台运行
* @param packageName
private boolean isAppForeground(String packageName) {
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
ComponentName cn = am.getRunningTasks(1).get(0).topA
String currentPackageName = cn.getPackageName();
if (!TextUtils.isEmpty(currentPackageName) && currentPackageName.equals(packageName)) {
* 将当前应用运行到前台
private void bring2Front() {
ActivityManager activtyManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
List&ActivityManager.RunningTaskInfo& runningTaskInfos = activtyManager.getRunningTasks(3);
for (ActivityManager.RunningTaskInfo runningTaskInfo : runningTaskInfos) {
if (this.getPackageName().equals(runningTaskInfo.topActivity.getPackageName())) {
activtyManager.moveTaskToFront(runningTaskInfo.id, ActivityManager.MOVE_TASK_WITH_HOME);
* 回到系统桌面
private void back2Home() {
Intent home = new Intent(Intent.ACTION_MAIN);
home.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
home.addCategory(Intent.CATEGORY_HOME);
startActivity(home);
* 系统是否在锁屏状态
private boolean isScreenLocked() {
KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
return keyguardManager.inKeyguardRestrictedInputMode();
private void wakeAndUnlock() {
//获取电源管理器对象
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
//获取PowerManager.WakeLock对象,后面的参数|表示同时传入两个值,最后的是调试用的Tag
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "bright");
//点亮屏幕
wl.acquire(1000);
//得到键盘锁管理器对象
KeyguardManager km = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
kl = km.newKeyguardLock("unLock");
kl.disableKeyguard();
private void release() {
if (locked && kl != null) {
android.util.Log.d("maptrix", "release the lock");
//得到键盘锁管理器对象
kl.reenableKeyguard();
接着配置清单文件,权限和service的配置比较重要。
&?xml version="1.0" encoding="utf-8"?&
&manifest xmlns:android="/apk/res/android"
package="com.ileja.autoreply"&
&uses-permission android:name="android.permission.DISABLE_KEYGUARD" /&
&uses-permission android:name="android.permission.INTERNET" /&
&uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /&
&uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /&
&uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE" /&
&uses-permission android:name="android.permission.GET_TASKS" /&
&uses-permission android:name="android.permission.REORDER_TASKS" /&
&uses-permission android:name="android.permission.WAKE_LOCK" /&
&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&
android:name=".AutoReplyService"
android:enabled="true"
android:exported="true"
android:label="@string/app_name"
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/auto_reply_service_config"/&
&/service&
&/application&
&/manifest&
为了使用某些必要的API,最低API level应该是18
运行程序,打开服务,看看效果如何把~
打开辅助服务
接着用其他手机试着发送给我几条微信
自动回复微信
可以看到,自动回复功能就实现了。
写在后面:
代码没有给大家详细讲解,不过看注释应该可以看懂个大概。当微信程序切换到后台,或者锁屏(无锁屏密码)时,只要有通知出现,都可以实现自动回复。
关于AccessibilityService可以监控的行为非常多,所以我觉得可以实现各种各样炫酷的功能,不过我并不建议你打开某些流氓软件的AccessibilityService服务,因为很有可能造成一些安全问题,所以,自己动手写就安全多了嘛。
github项目地址:
Github:/itsMelo 欢迎 follow ~
itsCoder 主页: 欢迎加入 ~
看星星零颗一颗两颗三颗连成线~原创框架:、、
微信团队原创分享:Android版微信后台保活实战分享(进程保活篇)
在线时长累积100天(即100 * 8 = 800小时)。
精华主题数超过100个。
为论区做出突出贡献的开发者、版主等。
个人信息完善的会员。完成“完善资料拿勋章”新手任务后获得:http://www.52im.net/home.php?mod=task
商务/合作:
投稿/报道:
手机访问本站
微信公众号new后使用快捷导航没有帐号?
只需一步,快速开始
查看: 15771|回复: 15
在线时间0 小时经验值58 最后登录注册时间帖子阅读权限30UID
初中生, 积分 58, 距离下一级还需 42 积分
TA的每日心情郁闷 21:55签到天数: 6 天[LV.2]偶尔看看I
G币10 最后登录注册时间
马上注册,结交更多机友,下载更多应用,让你轻松玩转手机。
已有帐号?   下载游戏和软件,请【】进入机锋市场!
本帖最后由 jun857 于
16:15 编辑
手机自带的清除近期任务会清除微信,设置里选了保持唤醒状态也没用,360里设置了白名单也不行
在线时间515 小时经验值1139 最后登录注册时间帖子阅读权限80UID4589264
研究生, 积分 1139, 距离下一级还需 561 积分
TA的每日心情怒 12:02签到天数: 8 天[LV.3]偶尔看看II
G币13 最后登录注册时间
你用360的清理就行了,系统的设不了
我无为,却想无所不为
在线时间1051 小时经验值2827 最后登录注册时间帖子阅读权限100UID4492815
博士, 积分 2827, 距离下一级还需 673 积分
TA的每日心情开心 19:26签到天数: 3 天[LV.2]偶尔看看I
G币327 最后登录注册时间
有用绿色守护么
在线时间0 小时经验值352 最后登录注册时间帖子阅读权限50UID
大学专科, 积分 352, 距离下一级还需 48 积分
TA的每日心情奋斗 09:34签到天数: 78 天[LV.6]常住居民II
G币217 最后登录注册时间
我的也是呢,看书的,切换别的,切回来。就像重开软件一样。
在线时间397 小时经验值650 最后登录注册时间帖子阅读权限60UID2192555
大学本科, 积分 650, 距离下一级还需 50 积分
该用户从未签到
G币75 最后登录注册时间
微信太费电了,每天都60%,不知道在后台干嘛
在线时间17 小时经验值2837 最后登录注册时间帖子阅读权限153UID8346214
TA的每日心情开心 00:16签到天数: 6 天[LV.2]偶尔看看I
G币634397 最后登录注册时间
自带的好像不行,我都用第三方的清理
在线时间44 小时经验值5038 最后登录注册时间帖子阅读权限153UID8042625
TA的每日心情慵懒 18:45签到天数: 806 天[LV.10]以坛为家III
G币5269 最后登录注册时间
把你想常驻内存的软件,转换成系统程序,在加入软件的白名单试试,我就把V4A音效加入系统程序和白名单,再也没被清理过了
在线时间73 小时经验值268 最后登录注册时间帖子阅读权限50UID3375375
大学专科, 积分 268, 距离下一级还需 132 积分
该用户从未签到
G币2 最后登录注册时间
mee too, the same problem, help~~
在线时间0 小时经验值58 最后登录注册时间帖子阅读权限30UID
初中生, 积分 58, 距离下一级还需 42 积分
TA的每日心情郁闷 21:55签到天数: 6 天[LV.2]偶尔看看I
G币10 最后登录注册时间
メ'_怀|_℡ 发表于
把你想常驻内存的软件,转换成系统程序,在加入软件的白名单试试,我就把V4A音效加入系统程序和白名单,再 ...
怎么转换为系统程序?
在线时间0 小时经验值58 最后登录注册时间帖子阅读权限30UID
初中生, 积分 58, 距离下一级还需 42 积分
TA的每日心情郁闷 21:55签到天数: 6 天[LV.2]偶尔看看I
G币10 最后登录注册时间
メ'_怀|_℡ 发表于
把你想常驻内存的软件,转换成系统程序,在加入软件的白名单试试,我就把V4A音效加入系统程序和白名单,再 ...
怎么转换为系统程序?
Powered by帖子很冷清,卤煮很失落!求安慰
手机签到经验翻倍!快来扫一扫!
太实用了!安卓版微信的13个隐藏功能代码
536浏览 / 2回复
以下代码仅适用于Android版微信;//switchtabpos:让微信tab更贴合Android Design如果你并不喜欢微信Android版和iOS端同用一套UI,现在有一个小方法可以实现Tab的转移:在微信任意聊天窗口输入//switchtabpos并按发送,Tab就会从转移到屏幕顶端,Android范十足。如果想再调整回来,再输入一遍并发送就好了。//multiwebview:将微信聊天页和文章页拆分为两个任务卡片在任意聊天窗口输入//multiwebview并发送,聊天和文章页面就可以被拆分为两个任务,并能同时出现在多任务切换页面中。如果在看文章过程中来了微信消息,回复消息后再跳转回文章就方便多了。当然,该功能还需系统的支持,目前只适用于Android 5.0及以上版本的系统。//switchnotificationstatus:让微信也支持浮动通知在微信任意聊天窗口输入//switchnotificationstatus并发送,即可让微信也支持浮动通知。不过该功能仅支持Android 5.x +和微信6.2测试版,如要升级到微信6.2测试版,请用微信扫一扫下面最后一张图中的二维码。//sightinfo:查看小视频参数//sightinfo可以让小视频的左上角显示小视频的一些参数,比如帧率、分辨率、时长、大小等。输入//sightinfo并发送后,参数不会立即显示,需先退出微信再重新进入。如要取消显示参数,只需重复输入//sightinfo并发送,退出微信再重新进入就好了。//traceroute:调出「诊断网络」功能在微信任意聊天窗口输入//traceroute并发送,可以调出「诊断网络」功能。不过,当你真遇上无法连接到服务器的情况,这页面应该会自动弹出来吧。//opentrace在微信任意聊天窗口输入//opentrace并发送,可以调出一个悬浮的类似音乐播放器中的播放/停止按钮。点击一下是开始,再点击一下是结束。尚不清楚这是什么功能,希望能得到高人指点。//getfpkey输入//getfpkey并发送,可以看到关于手机的一些信息,包括制造商、型号、ROM的版本。然而用处不大,这些信息在设置-关于手机里都可以找到。//testwaitsms输入//testwaitsms并发送后会要求验证手机号码,在进度条走完之前你可以点返回键取消操作。不知道验证手机号码为哪般,关键这手机号码还不是我的,所以无法得知下一步要做什么。//setshakecarddata输入//setshakecarddata并发送后,摇一摇功能中会多出一个「礼券」选项。然而并不能摇出什么礼券,只有一句「活动已结束,多陪陪家人」的温馨提示。该功能的取消方法与前面所述的不大一样,需要输入//clearshakecarddata并发送。//checkcount:查看当前聊天窗口消息数量输入//checkcount并发送,可以查看当前聊天窗口总共有多少条消息。//pickpoi:定位当前位置输入//pickpoi并发送,可以定位自己当前的位置,这与微信中的「发送位置」的功能是相同的。//fullexit:退出微信//fullexit相当于退出功能,输入并发送后,微信会自动退出。再次进入微信时,需要输入登录密码。//testsetpageowner输入//testsetpageowner并发送,会跳转到一个Weixin JS API Demos页面,不过该页面仅支持公司内网访问,对咱来说没什么用。
涨姿势了 & & &
谢谢分享。。。。
可能感兴趣的板块:
用户名/注册邮箱/注册手机号
其他第三方号登录

我要回帖

更多关于 微信商城怎么进入 的文章

 

随机推荐