Android 定时启动dingding
程序员文章站
2022-06-24 20:34:39
...
请遵守自己公司打卡规则,本文章只用于探讨技术
1. 添加服务用于启动FirstClock
本人的android手机是aosp的google pixel,基于Android源码开发,因此权限特别高,不适用于三方app
adb shell am startservice -n com.chinatsp.dmsservice/.TDmsBootService //命令启动
package com.chinatsp.dmsservice;
import android.app.Service;
import android.content.Intent;
import android.content.Context;
import android.os.Build;
import android.os.IBinder;
import android.util.Log;
public class TDmsBootService extends Service {
private static final String TAG = "TDms.BootService";
private Context mContext;
public TDmsBootService() {
mContext = this;
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, " onDestroy");
}
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, " initBinder");
initBinder();
}
private void initBinder() {
Log.d(TAG, "initBinder enter");
DingClockTime.getInstance(this).startFirstClock();
}
}
2. 启动定时
第一次定时任务,只需要看是上班打卡,还是下班打卡
package com.chinatsp.dmsservice;
import android.os.RemoteException;
import android.util.Log;
import android.content.Context;
import android.app.PendingIntent;
import android.content.Intent;
import java.util.Date;
import java.util.Locale;
import android.app.AlarmManager;
import java.util.TimeZone;
import java.util.Calendar;
import java.util.Date;
import java.io.IOException;
import android.os.PowerManager;
import com.chinatsp.dmsservice.utils.PackageUtils;
public class DingClockTime {
private static final String TAG = "TDms.DingClockTime";
private Context mContext;
private static volatile DingClockTime mDingClockTime;
public static final String DINGDING_PKGNAME = "com.alibaba.android.rimet";
//上班时间
public static final int CLOCK_IN_HOUR = 9;
public static final int CLOCK_IN_MINUTE = 8;
//下班时间
public static final int CLOCK_OUT_HOUR = 18;
public static final int CLOCK_OUT_MINUTE = 23;
public static final int DAY_SAT = 7;
public static final int DAY_SUN = 1;
private DingClockTime(Context context) {
mContext = context;
}
public static DingClockTime getInstance(Context context) {
if (mDingClockTime == null) {
synchronized (DingClockTime.class) {
if (mDingClockTime == null) {
mDingClockTime = new DingClockTime(context);
}
}
}
return mDingClockTime;
}
public void startFirstClock() {
Date date = new Date();
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
int currentday = calendar.get(Calendar.DAY_OF_WEEK);
int currentHour = calendar.get(Calendar.HOUR_OF_DAY);
int currentmin = calendar.get(Calendar.MINUTE);
Log.d(TAG, "currentday: " + currentday + " currentHour: " + currentHour);
//不一致代表第一次启动此apk,小于那个设置时间就启动那个
if(currentHour > CLOCK_IN_HOUR && currentHour < CLOCK_OUT_HOUR) { //9 < x <18 证明下一次是18点
startRemind(CLOCK_OUT_HOUR, CLOCK_OUT_MINUTE);
Log.d(TAG, "333: ");
}else if (currentHour == CLOCK_IN_HOUR && currentmin > CLOCK_IN_MINUTE) { //比上班时间晚
startRemind(CLOCK_OUT_HOUR, CLOCK_OUT_MINUTE);
Log.d(TAG, "444: ");
}else if (currentHour == CLOCK_IN_HOUR && currentmin < CLOCK_IN_MINUTE) { //比上班时间zao
startRemind(CLOCK_IN_HOUR, CLOCK_IN_MINUTE);
Log.d(TAG, "777: ");
}else if (currentHour == CLOCK_OUT_HOUR && currentmin < CLOCK_OUT_MINUTE) {//比下班时间早
startRemind(CLOCK_OUT_HOUR, CLOCK_OUT_MINUTE);
Log.d(TAG, "555: ");
}else {
startRemind(CLOCK_IN_HOUR, CLOCK_IN_MINUTE);
Log.d(TAG, "666: ");
}
}
//时分秒开始Alarm任务,currentHour用于判断下一个闹钟类型
private void startRemind(){
Date date = new Date();
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
int currentday = calendar.get(Calendar.DAY_OF_WEEK);
int currentHour = calendar.get(Calendar.HOUR_OF_DAY);
int currentmin = calendar.get(Calendar.MINUTE);
Log.d(TAG, "currentday: " + currentday + " currentHour: " + currentHour);
if(currentHour == CLOCK_IN_HOUR) {
startRemind(CLOCK_OUT_HOUR, CLOCK_OUT_MINUTE);
Log.d(TAG, "111: ");
}else {
startRemind(CLOCK_IN_HOUR, CLOCK_IN_MINUTE);
Log.d(TAG, "222: ");
}
}
//时分秒开始Alarm任务
private void startRemind(int hour, int min){
Log.d(TAG,"startRemind hour : " + hour + " min: " + min);
//得到日历实例,主要是为了下面的获取时间
Calendar mCalendar = Calendar.getInstance();
mCalendar.setTimeInMillis(System.currentTimeMillis());
//获取当前毫秒值
long systemTime = System.currentTimeMillis();
//是设置日历的时间,主要是让日历的年月日和当前同步
mCalendar.setTimeInMillis(System.currentTimeMillis());
// 这里时区需要设置一下,不然可能个别手机会有8个小时的时间差
mCalendar.setTimeZone(TimeZone.getTimeZone("GMT+8"));
//设置在几点提醒 设置的为13点
mCalendar.set(Calendar.HOUR_OF_DAY, hour);
//设置在几分提醒 设置的为25分
mCalendar.set(Calendar.MINUTE, min);
//下面这两个看字面意思也知道
mCalendar.set(Calendar.SECOND, 0);
mCalendar.set(Calendar.MILLISECOND, 0);
//上面设置的就是13点25分的时间点
//获取上面设置的13点25分的毫秒值
long selectTime = mCalendar.getTimeInMillis();
// 如果当前时间大于设置的时间,那么就从第二天的设定时间开始
if(systemTime > selectTime) {
mCalendar.add(Calendar.DAY_OF_MONTH, 1);
}
//AlarmReceiver.class为广播接受者
Intent intent = new Intent(mContext, AlarmClockReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, intent, 0);
//得到AlarmManager实例
AlarmManager am = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
//**********注意!!下面的两个根据实际需求任选其一即可*********
/**
* 单次提醒
* mCalendar.getTimeInMillis() 上面设置的13点25分的时间点毫秒值
*/
am.set(AlarmManager.RTC_WAKEUP, mCalendar.getTimeInMillis(), pi);
}
/**
* 关闭提醒
*/
private void stopRemind(){
Intent intent = new Intent(mContext, AlarmClockReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, intent, 0);
//得到AlarmManager实例
AlarmManager am = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
//取消警报
am.cancel(pi);
}
public void handleBroadcast() {
Thread dmsFaceThread = new Thread(new Runnable() {
@Override
public void run() {
Log.d(TAG,"handleBroadcast: ..");
//当前是周末就不进行打卡
if(getCurrentDay() != DAY_SAT && getCurrentDay() != DAY_SUN) {
Log.d(TAG,"handleBroadcast: getCurrentDay() " + getCurrentDay());
//亮屏
doPowerCmd();
//发送滑动
doSwipeCmd();
PackageUtils.launchDingdingApk(mContext, DINGDING_PKGNAME);
}
Log.d(TAG,"startNextRemind : ..");
startNextRemind();
try {
Thread.sleep(60 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
doForceStop();
Log.d(TAG,"handleBroadcast end: ..");
}
});
dmsFaceThread.setName("DmsFaceThread");
dmsFaceThread.start();
}
public void startNextRemind() {
//停止上一次
stopRemind();
startRemind();
}
public int getCurrentDay() {
Date date = new Date();
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
int currentday = calendar.get(Calendar.DAY_OF_WEEK);
int currentHour = calendar.get(Calendar.HOUR_OF_DAY);
Log.d(TAG, "currentday: " + currentday + " currentHour: " + currentHour);
return currentday;
}
public void doPowerCmd() {
PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
//true为打开,false为关闭
boolean ifOpen = powerManager.isScreenOn();
if(ifOpen) {
return;
}
try {
Process process = Runtime.getRuntime().exec("input keyevent 26");
Thread.sleep(3000);
process.destroy();
}catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
public void doSwipeCmd() {
try {
Process process = Runtime.getRuntime().exec("input swipe 360 1000 360 400");
Thread.sleep(3000);
process.destroy();
}catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
public void doForceStop() {
try {
Process process = Runtime.getRuntime().exec("am force-stop " + DINGDING_PKGNAME);
Thread.sleep(3000);
process.destroy();
}catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
Androidmanifest.xml添加广播
<service
android:name="com.chinatsp.dmsservice.TDmsBootService"
android:exported="true" />
<receiver
android:name=".AlarmClockReceiver"
android:process=":remote"
/>
收到广播,启动下一个定时任务。广播收到消息慢,看service是否会更快,如果太慢,startRemind应该添加时间误差逻辑,而不是=
public class AlarmClockReceiver extends BroadcastReceiver {
private static final String TAG = "TDms.AlarmClockReceiver";
@Override
public void onReceive(Context context, Intent intent) {
//当系统到我们设定的时间点的时候会发送广播,执行这里
Log.d(TAG, "AlarmClockReceiver onReceive") ;
DingClockTime.getInstance(context).handleBroadcast();
}
}
3. 启动app
//pkgName DINGDING_PKGNAME = “com.alibaba.android.rimet”;
public static void launchDingdingApk(Context mContext, String pkgName ) {
PackageManager packageManager = mContext.getPackageManager();
Intent intent = packageManager.getLaunchIntentForPackage(pkgName);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
}
4. 唤醒和灭屏
userdebug版本,直接使用的input命令,也可以使用inputManager,还可以用powerManager申请唤醒锁
public void doPowerCmd() {
PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
//true为打开,false为关闭
boolean ifOpen = powerManager.isScreenOn();
if(ifOpen) {
return;
}
try {
Process process = Runtime.getRuntime().exec("input keyevent 26");
Thread.sleep(3000);
process.destroy();
}catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
5. 滑动解锁
这里用的input swipe滑动命令,也可以用sendevent命令,也可以用AccessibilityService
public void doSwipeCmd() {
try {
Process process = Runtime.getRuntime().exec("input swipe 360 1000 360 400");
Thread.sleep(3000);
process.destroy();
}catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
6. stop application
am force-stop停止应用
public void doForceStop() {
try {
Process process = Runtime.getRuntime().exec("am force-stop " + DINGDING_PKGNAME);
Thread.sleep(3000);
process.destroy();
}catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
代码网盘地址:
code/dingdingClock/dingdingClock.rar