com.ucmap.dingdinghelper.services.TimingService.java Source code

Java tutorial

Introduction

Here is the source code for com.ucmap.dingdinghelper.services.TimingService.java

Source

/*
 * Copyright (C)  Justson(https://github.com/Justson/DingDingHelper)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.ucmap.dingdinghelper.services;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Process;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;
import android.text.TextUtils;
import android.util.Log;

import com.ucmap.dingdinghelper.ITimerListener;
import com.ucmap.dingdinghelper.ITimingAidlInterface;
import com.ucmap.dingdinghelper.R;
import com.ucmap.dingdinghelper.entity.AccountEntity;
import com.ucmap.dingdinghelper.sphelper.SPUtils;
import com.ucmap.dingdinghelper.ui.MainActivity;
import com.ucmap.dingdinghelper.utils.Constants;
import com.ucmap.dingdinghelper.utils.DateUtils;
import com.ucmap.dingdinghelper.utils.JsonUtils;
import com.ucmap.dingdinghelper.utils.ShellUtils;

import java.util.List;

import static com.ucmap.dingdinghelper.utils.DateUtils.getHourAndMin;

public class TimingService extends Service {
    /**
     * ID
     */
    private static final int NOTIFICATION_ID = 0x0033888;

    @Override
    public void onCreate() {
        super.onCreate();
        init();
        increasePriority();
    }

    private List<AccountEntity> mAccountEntities = null;
    private AccountEntity mAccountEntity = null;

    private int hour = 8;
    private int min = 45;

    private NotifyThread mNotifyThread;

    /*0?1?*/
    private static int STATE = 0;

    private void init() {
        String jsonAccountList = (String) SPUtils.getString(Constants.ACCOUNT_LIST, "-1");
        mAccountEntities = JsonUtils.listJson(jsonAccountList, AccountEntity.class);
        if (mAccountEntities == null || mAccountEntities.isEmpty()) {
            return;
        }
        this.mAccountEntity = mAccountEntities.get(0);

        /*try {
        *//* ? kill ? *//*
                                                                                                  Daemon.run(this, TimingService.class, Daemon.INTERVAL_ONE_MINUTE);
                                                                                                  } catch (Exception e) {
                                                                                                  e.printStackTrace();
                                                                                                  }*/

        initCheckInTime(null);
        if (mNotifyThread == null || !mNotifyThread.isAlive()) {
            mNotifyThread = new NotifyThread();
            runing_monitor = true;
            mNotifyThread.setPriority(Thread.MAX_PRIORITY);
            /*?*/
            mNotifyThread.start();
        }
    }

    private void initCheckInTime(String remoteTime) {
        String current = DateUtils.getHourAndMin(System.currentTimeMillis());
        int hour = Integer.parseInt(current.split(":")[0]);
        int min = Integer.parseInt(current.split(":")[1]);
        if (TextUtils.isEmpty(remoteTime)) {
            String time = "";
            if (hour < 12) {
                STATE = 0;
                time = (String) SPUtils.getString(Constants.MORNING_CHECK_IN_TIME, "8:45");
            } else {
                STATE = 1;
                time = (String) SPUtils.getString(Constants.AFTERNOON_CHECK_IN_TIME, "20:45");
            }

            if (time.length() >= 4) {
                String[] hourAndMin = time.split(":");
                this.hour = Integer.parseInt(hourAndMin[0]);
                this.min = Integer.parseInt(hourAndMin[1]);
            }
        } else {

            String hm[] = remoteTime.split(":");

            int tempH = Integer.parseInt(hm[0]);
            int tempM = Integer.parseInt(hm[1]);
            if (hour < 12 && ((tempH > hour) || (tempH == hour && tempM > min))) {

                STATE = 0;
                this.hour = tempH;
                this.min = tempM;

            } else if (hour >= 12 && ((tempH > hour) || (tempH == hour && tempM > min))) {

                STATE = 1;
                this.hour = tempH;
                this.min = tempM;
            } else {
                initCheckInTime(null);
            }
            String t = (String) SPUtils.getString(Constants.AFTERNOON_CHECK_IN_TIME, "8:45");

        }

    }

    private RemoteCallbackList<ITimerListener> mITimerListenerRemoteCallbackList = new RemoteCallbackList<>();

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return new ITimingAidlInterface.Stub() {

            @Override
            public void registerTimerListener(ITimerListener timerListener) throws RemoteException {
                mITimerListenerRemoteCallbackList.register(timerListener);
            }

            @Override
            public void unRegisterTimerListener(ITimerListener timerListener) throws RemoteException {
                mITimerListenerRemoteCallbackList.unregister(timerListener);
            }

            @Override
            public void reInitCheckInTime(String time) throws RemoteException {
                initCheckInTime(time);
            }
        };
    }

    /*???service */
    private void increasePriority() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
            Notification.Builder mBuilder = new Notification.Builder(this);
            mBuilder.setSmallIcon(R.mipmap.app_logo);
            startForeground(NOTIFICATION_ID, mBuilder.build());
            InnerService.startInnerService(this);
        } else {
            startForeground(NOTIFICATION_ID, new Notification());
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        runing_monitor = false;
        if (mNotifyThread != null && mNotifyThread.isAlive()) {

            /*Thread ? ???*/
            if (!mNotifyThread.isInterrupted()) {
                mNotifyThread.interrupt();
            }
        }

        NotificationManager mNotificationManager = (NotificationManager) this
                .getSystemService(NOTIFICATION_SERVICE);
        mNotificationManager.cancel(NOTIFICATION_ID_PROGRESS_ID);
        mNotificationManager.cancel(NOTIFICATION_ID);
    }

    public static class InnerService extends Service {
        private static final void startInnerService(Context context) {
            context.startService(new Intent(context, InnerService.class));
        }

        @Override
        public void onCreate() {
            super.onCreate();
            Notification.Builder mBuilder = new Notification.Builder(this);
            mBuilder.setSmallIcon(R.mipmap.app_logo);
            startForeground(NOTIFICATION_ID, mBuilder.build());

            new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
                @Override
                public void run() {
                    stopForeground(true);
                    NotificationManager mNotificationManager = (NotificationManager) InnerService.this
                            .getSystemService(NOTIFICATION_SERVICE);
                    mNotificationManager.cancel(NOTIFICATION_ID);
                    stopSelf();
                }
            }, 250);
        }

        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }

        @Override
        public void onDestroy() {
            super.onDestroy();
            stopForeground(true);
        }
    }

    private static final int NOTIFICATION_ID_PROGRESS_ID = 0x100100;

    private int[] parseTime(String time) {
        if (TextUtils.isEmpty(time))
            return null;
        String[] hm = time.split(":");
        int[] times = new int[hm.length];
        for (int i = 0; i < hm.length; i++) {
            times[i] = Integer.parseInt(hm[i]);
        }
        return times;
    }

    private void setTargetTimeForLockIn() {
        String time = "";
        time = (String) SPUtils.getString(Constants.MORNING_CHECK_IN_TIME, "6:45");
        int[] hm = parseTime(time);
        this.hour = hm[0];
        this.min = hm[1];
    }

    private void toCheckIn() {
        if (Constants.IS_NOTITY_TYPE_CHECK_IN_TAG) {
            ShellUtils.execCmd("am broadcast -a com.ucmap.dingdinghelper.clock", true);
        } else {
            Log.i("Info", "  AlarmManager ");
        }
    }

    private void sendNotification(int hour, int min) {

        if ((STATE == 0) && (this.hour < hour || (this.hour == hour && this.min <= min))) {
            if ((this.hour == hour && this.min <= min))
                toCheckIn();
            String time = "";
            time = (String) SPUtils.getString(Constants.AFTERNOON_CHECK_IN_TIME, "20:45");
            STATE = 1;

            String[] hm = time.split(":");
            this.hour = Integer.parseInt(hm[0]);
            this.min = Integer.parseInt(hm[1]);

            /*?*/
            sendNotification(hour, min);
            return;
        } else if (STATE == 1 && (this.hour < hour || (this.hour == hour && this.min <= min))) {
            if ((this.hour == hour && this.min <= min))
                toCheckIn();
            setTargetTimeForLockIn();
            STATE = 2;
            sendNotification(hour, min);

            return;
        } else if (STATE == 2) {
            if (hour < 23 && hour >= 12) {
                setTargetTimeForLockIn();
            } else
                STATE = 0;
        }
        int lHour = 0;

        if (hour <= this.hour) {
            lHour = this.hour - hour;
        } else {
            lHour = 24 - hour + this.hour;
        }

        int lMin = 0;
        if (min <= this.min) {
            lMin = this.min - min;
        } else {
            if (this.hour != hour)
                lHour--;
            if (hour == this.hour) {
                lMin = this.min - min;
            } else
                lMin = 60 - min + this.min;
        }

        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
        mBuilder.setSmallIcon(R.mipmap.app_logo);
        notifyUpdateUi("?:" + this.hour + ":" + this.min + ", " + lHour + "? " + lMin + " ");
        mBuilder.setContentText("??: " + lHour + " ?" + lMin + " ")
                .setContentTitle("?");
        PendingIntent mPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class),
                PendingIntent.FLAG_UPDATE_CURRENT);
        mBuilder.setContentIntent(mPendingIntent);
        NotificationManager mNotificationManager = (NotificationManager) this
                .getSystemService(NOTIFICATION_SERVICE);
        mNotificationManager.notify(NOTIFICATION_ID_PROGRESS_ID, mBuilder.build());
    }

    /**/
    private volatile boolean runing_monitor = true;

    private void notifyUpdateUi(String time) {
        if (mITimerListenerRemoteCallbackList == null)
            return;
        int number = mITimerListenerRemoteCallbackList.beginBroadcast();

        for (int i = 0; i < number; i++) {

            ITimerListener mITimerListener = mITimerListenerRemoteCallbackList.getBroadcastItem(i);
            if (mITimerListener == null)
                continue;
            try {
                mITimerListener.toCallback(time);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
        mITimerListenerRemoteCallbackList.finishBroadcast();
    }

    /* */
    class NotifyThread extends Thread {
        @Override
        public void run() {

            /*??,???*/
            Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_AUDIO);
            while (runing_monitor) {

                String time = getHourAndMin(System.currentTimeMillis());
                if (TextUtils.isEmpty(time))
                    continue;
                String[] hourAndMin = time.split(":");
                if (hourAndMin == null || hourAndMin.length < 2)
                    continue;
                String hour = hourAndMin[0];
                int hourInt = Integer.parseInt(hour);
                int min = Integer.parseInt(hourAndMin[1]);
                sendNotification(hourInt, min);
                try {
                    /*----?15s*/
                    sleep(1000 * 10);
                } catch (InterruptedException e) {
                    //                    e.printStackTrace();
                    return;
                }

            }
        }
    }
}