Android微信自动回复及锁屏控制界面
2016-05-31 19:43
537 查看
本文内容:
AccessibilityService与微信自动回复
锁屏显示界面及activity切换动画
自定义样式与圆角矩形按钮
电量信息获取
来去电通话状态监听
ViewFlipper与页面切换动画
一、实现自动回复再次用到了Android的辅助功能AccessibilityService(参考微信抢红包辅助),通过自动进入微信聊天界面查找到文本编辑框(android.widget.EditText)并获取焦点后将回复内容粘贴进去,之后再查找到发送按钮模拟点击。
AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();
AccessibilityNodeInfo targetNode = null;
AccessibilityNodeInfo editText = null;
//通过组件名递归查找编辑框
private void findNodeInfosByName(AccessibilityNodeInfo nodeInfo, String name) {
if(name.equals(nodeInfo.getClassName())) {
editText = nodeInfo;
return;
}
for(int i = 0; i < nodeInfo.getChildCount(); i++) {
findNodeInfosByName(nodeInfo.getChild(i), name);
}
}
查找编辑框
粘贴回复信息
查找发送按钮
点击发送按钮
二、锁屏显示界面及activity切换动画
构造锁屏显示界面,用两个Flag:WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD 和 WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED即可使Activity显示在锁屏界面之上
在AndroidManifest.xml中配置锁屏显示界面,使其独占一个新的活动栈且只有一个实例且不在任务历史中显示
Activity的消失动画效果,在滑动锁或无锁屏状态下有效果,其他如九宫格锁好像无效
其中activity_close:
其中activity_start:
创建与启动锁屏显示界面,在接收到屏幕状态变化(亮屏或黑屏)广播后创建启动Activity,需要添加Flag:Intent.FLAG_ACTIVITY_NEW_TASK。若是来电唤醒或在通话时的屏幕状态变化则不启动activity,不然需先关闭activity才能接听电话,同理当需要自动回复时也不显示锁屏activity
三、自定义样式与圆角矩形按钮
自定义样式button.xml
使用样式
四、电量信息获取
五、来去电通话状态监听
相关定义
相关使用
六、ViewFlipper与页面切换动画
布局
使用
效果如图:
七、详细源码请看这里:GitHub
AccessibilityService与微信自动回复
锁屏显示界面及activity切换动画
自定义样式与圆角矩形按钮
电量信息获取
来去电通话状态监听
ViewFlipper与页面切换动画
一、实现自动回复再次用到了Android的辅助功能AccessibilityService(参考微信抢红包辅助),通过自动进入微信聊天界面查找到文本编辑框(android.widget.EditText)并获取焦点后将回复内容粘贴进去,之后再查找到发送按钮模拟点击。
AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();
AccessibilityNodeInfo targetNode = null;
AccessibilityNodeInfo editText = null;
//通过组件名递归查找编辑框
private void findNodeInfosByName(AccessibilityNodeInfo nodeInfo, String name) {
if(name.equals(nodeInfo.getClassName())) {
editText = nodeInfo;
return;
}
for(int i = 0; i < nodeInfo.getChildCount(); i++) {
findNodeInfosByName(nodeInfo.getChild(i), name);
}
}
查找编辑框
if(editText == null) { //第一种查找方法 List<AccessibilityNodeInfo> list1 = nodeInfo.findAccessibilityNodeInfosByViewId(StaticData.editId); if( !list1.isEmpty() ) editText = list1.get(0); //第二种查找方法 if(editText == null) findNodeInfosByName(nodeInfo, "android.widget.EditText"); } targetNode = editText;
粘贴回复信息
if(targetNode != null) { //android >= 21=5.0时可以用ACTION_SET_TEXT //android >= 18=4.3时可以通过复制粘贴的方法,先确定焦点,再粘贴ACTION_PASTE //使用剪切板 ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); ClipData clip = ClipData.newPlainText("message", StaticData.message); //设置粘贴板 clipboard.setPrimaryClip(clip); //获取焦点 targetNode.performAction(AccessibilityNodeInfo.ACTION_FOCUS); //粘贴内容 targetNode.performAction(AccessibilityNodeInfo.ACTION_PASTE); }
查找发送按钮
if(targetNode != null) { targetNode = null; List<AccessibilityNodeInfo> list2 = nodeInfo.findAccessibilityNodeInfosByViewId(StaticData.sendId); if( !list2.isEmpty() ) targetNode = list2.get(0); //第二种查找方法 if(targetNode == null) targetNode = findNodeInfosByText(nodeInfo, "发送"); }
点击发送按钮
if(targetNode != null) { final AccessibilityNodeInfo n = targetNode; performClick(n); }
二、锁屏显示界面及activity切换动画
构造锁屏显示界面,用两个Flag:WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD 和 WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED即可使Activity显示在锁屏界面之上
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); setContentView(R.layout.activity_screen); }
在AndroidManifest.xml中配置锁屏显示界面,使其独占一个新的活动栈且只有一个实例且不在任务历史中显示
<activity android:excludeFromRecents="true" android:exported="false" android:launchMode="singleInstance" android:name="com.example.autoreply.LockScreenActivity" android:screenOrientation="portrait" android:taskAffinity="com.example.autoreply.lockscreen" android:noHistory="true" android:theme="@android:style/Theme.NoTitleBar.Fullscreen" > </activity>
Activity的消失动画效果,在滑动锁或无锁屏状态下有效果,其他如九宫格锁好像无效
@Override public void finish() { super.finish(); //overridePendingTransition(android.R.anim.slide_in_left,android.R.anim.slide_out_right);//系统自带动画 overridePendingTransition(R.drawable.activity_close, R.drawable.activity_start);//自定义动画 }
其中activity_close:
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" > <translate android:duration="500" android:fromYDelta="100%p" android:toYDelta="0" /> </set>
其中activity_start:
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" > <translate android:duration="500" android:fromYDelta="0" android:toYDelta="-100%p" /> </set>
创建与启动锁屏显示界面,在接收到屏幕状态变化(亮屏或黑屏)广播后创建启动Activity,需要添加Flag:Intent.FLAG_ACTIVITY_NEW_TASK。若是来电唤醒或在通话时的屏幕状态变化则不启动activity,不然需先关闭activity才能接听电话,同理当需要自动回复时也不显示锁屏activity
class ScreenOffReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { //若在通话则不显示锁屏界面 if(StaticData.iscalling) return; String action = intent.getAction(); if (action.equals(Intent.ACTION_SCREEN_OFF)) { Log.i("demo", "screen off"); Intent lockscreen = new Intent(AutoReplyService.this, LockScreenActivity.class); lockscreen.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(lockscreen); } else if (action.equals(Intent.ACTION_SCREEN_ON)) { Log.i("demo", "screen on"); //若需要自动回复也不显示,否则需解锁两次而导致自动回复失败 if(canGet) return; Intent lockscreen = new Intent(AutoReplyService.this, LockScreenActivity.class); lockscreen.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(lockscreen); } } }
三、自定义样式与圆角矩形按钮
自定义样式button.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="false"> <shape android:shape="rectangle"> <solid android:color="#BCCCCC"/> <!-- 设置按钮的四个角为弧形 --> <corners android:radius="20dip"/> <!-- 按钮里面的文字与边界的间隔 --> <padding android:bottom="10dp" android:left="13dp" android:right="13dp" android:top="10dp" /> </shape> </item> <item android:state_pressed="true"> <shape android:shape="rectangle"> <solid android:color="#95AEAE"/> <corners android:radius="20dip"/> </shape> </item> </selector>
使用样式
<Button android:id="@+id/startbtn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/button" android:text="start" android:textColor="#5F656D" />
四、电量信息获取
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { //获取当前电量,如未获取具体数值,则默认为0 batteryLevel=intent.getIntExtra(BatteryManager.EXTRA_LEVEL,0); //获取最大电量,如未获取到具体数值,则默认为100 batteryScale=intent.getIntExtra(BatteryManager.EXTRA_SCALE,100); //显示电量 Levelbtn.setText((batteryLevel*100/batteryScale)+"%"); } };
五、来去电通话状态监听
相关定义
private TelephonyManager tm; private PhoneReceiver preceiver; //通话状态变化广播接收器,通话期间不弹出锁屏活动 public class PhoneReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if(intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) { StaticData.iscalling = true; Log.i("demo", "去电"); } else { StaticData.iscalling = true; Log.i("demo", "来电"); } } } //通话状态变化广播接收器,通话期间不弹出锁屏活动 private PhoneStateListener listener = new PhoneStateListener() { @Override public void onCallStateChanged(int state, String incomingNumber) { super.onCallStateChanged(state, incomingNumber); switch(state) { case TelephonyManager.CALL_STATE_IDLE: StaticData.iscalling = false; Log.i("demo", "挂断"); break; case TelephonyManager.CALL_STATE_OFFHOOK: StaticData.iscalling = true; Log.i("demo", "接听"); break; case TelephonyManager.CALL_STATE_RINGING: StaticData.iscalling = true; Log.i("demo", "来电"); break; } } };
相关使用
//注册广播接收器 preceiver = new PhoneReceiver(); filter = new IntentFilter(); filter.addAction(Intent.ACTION_NEW_OUTGOING_CALL); registerReceiver(preceiver, filter); tm = (TelephonyManager)getSystemService(Service.TELEPHONY_SERVICE); //设置监听器 tm.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
六、ViewFlipper与页面切换动画
布局
<ViewFlipper ......> <!-- 第一个页面 --> <LinearLayout ...... </LinearLayout> <!-- 第二个页面 --> <LinearLayout ...... </LinearLayout> </ViewFlipper>
使用
//设置切换动画 viewFlipper.setInAnimation(this, android.R.anim.slide_in_left); viewFlipper.setOutAnimation(this, android.R.anim.slide_out_right); //切换页面 viewFlipper.showNext();
效果如图:
七、详细源码请看这里:GitHub
相关文章推荐
- 微信开发__入门
- 微信公众号开发--接入
- 微信公众号支付dome注意事项,及get、post无法传参解决办法
- 微信公众号发送文本消息时如何在文本消息中包含超链接
- 微信公众号第三方开发之七提交全网发布
- 微信浏览器的页面在PC端访问
- 微信开发常用文档及参考资料
- 微信开发常用文档及参考资料
- 微信开发常用文档及参考资料
- 如何在不接入微信API的情况下自定义分享内容(图片、链接、标题)
- 微信线下门店二维码扫码支付和退款
- 仿微信图片选择器
- 微信开发——1、编辑模式学习总结
- Android应用加入微信分享
- 微信
- 高仿微信图片选择
- 微信支付之HTML5页面WAP端接入
- iOS:判断设备上是否安装微信或qq 集成微信SDK的时候判断是否安装微信 基于ShareSDK
- 花生壳动态域名软件3重大版本:客户端支持微信远程管理
- 利用 Makefile 写的小程序