欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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() 上面设置的1325分的时间点毫秒值
        */
        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

相关标签: Input Android Basic