package com.xuexispace.ai.alarm; import android.annotation.SuppressLint; import android.app.AlarmManager; import android.app.PendingIntent; import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.text.TextUtils; import android.util.Log; import com.arialyy.aria.core.Aria; import com.blankj.utilcode.util.FileUtils; import com.bumptech.glide.Glide; import com.xuexispace.ai.bean.AlarmClockData; import com.xuexispace.ai.service.main.MainService; import com.xuexispace.ai.utils.FileUtil; import com.xuexispace.ai.utils.Utils; import java.io.File; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.TimeZone; public class AlarmUtils { private static final String TAG = "AlarmUtils"; @SuppressLint("StaticFieldLeak") private static AlarmUtils sInstance; private Context mContext; private AlarmManager alarmManager; private SQLiteDatabase db; private AlarmOpenHelper mAlarmOpenHelper; public static final int ONE_DAY_TIME = 1000 * 60 * 60 * 24; private AlarmUtils(Context context) { this.mContext = context; // this.mAlarmOpenHelper = new AlarmOpenHelper(context, AlarmOpenHelper.DATABASE_NAME, null, AlarmOpenHelper.DATABASE_VERSION); this.mAlarmOpenHelper = new AlarmOpenHelper(context, AlarmOpenHelper.DATABASE_NAME, null, AlarmOpenHelper.DATABASE_VERSION); this.db = mAlarmOpenHelper.getWritableDatabase(); alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); } public static void init(Context context) { if (context == null) { throw new RuntimeException("context is NULL"); } if (sInstance == null) { sInstance = new AlarmUtils(context); } } public static AlarmUtils getInstance() { if (sInstance == null) { throw new IllegalStateException("You must be init AlarmUtils first"); } return sInstance; } private void open() { if (db == null || !db.isOpen()) { db = mAlarmOpenHelper.getWritableDatabase(); } } /** * 增加数据 * * @param alarmClockData * @return */ public boolean addAlarmClock(AlarmClockData alarmClockData) { open(); ContentValues values = new ContentValues(); values.put(AlarmOpenHelper.KEY_ID, alarmClockData.getId()); values.put(AlarmOpenHelper.KEY_TYPE, alarmClockData.getType()); values.put(AlarmOpenHelper.KEY_TIME, alarmClockData.getTime()); values.put(AlarmOpenHelper.KEY_TITLE, alarmClockData.getTitle()); values.put(AlarmOpenHelper.KEY_VOICE, alarmClockData.getVoice()); values.put(AlarmOpenHelper.KEY_VOICE_MD5, alarmClockData.getVoice_md5()); values.put(AlarmOpenHelper.KEY_FILE, alarmClockData.getFile()); values.put(AlarmOpenHelper.KEY_REMIND_TYPE, alarmClockData.getRemind_type()); values.put(AlarmOpenHelper.KEY_IS_ONOFF, alarmClockData.getIs_onoff()); long id = 0; db.beginTransaction(); try { id = db.insert(AlarmOpenHelper.TABLE_ALARM, null, values); } catch (Exception e) { db.setTransactionSuccessful(); } finally { db.endTransaction(); } db.close(); return id > 0; } /** * 更新数据 * * @param alarmClockData * @return */ public boolean updateAlarmClock(AlarmClockData alarmClockData) { open(); ContentValues values = new ContentValues(); values.put(AlarmOpenHelper.KEY_ID, alarmClockData.getId()); values.put(AlarmOpenHelper.KEY_TYPE, alarmClockData.getType()); values.put(AlarmOpenHelper.KEY_TIME, alarmClockData.getTime()); values.put(AlarmOpenHelper.KEY_TITLE, alarmClockData.getTitle()); values.put(AlarmOpenHelper.KEY_VOICE, alarmClockData.getVoice()); values.put(AlarmOpenHelper.KEY_VOICE_MD5, alarmClockData.getVoice_md5()); values.put(AlarmOpenHelper.KEY_FILE, alarmClockData.getFile()); values.put(AlarmOpenHelper.KEY_REMIND_TYPE, alarmClockData.getRemind_type()); values.put(AlarmOpenHelper.KEY_IS_ONOFF, alarmClockData.getIs_onoff()); long id = 0; db.beginTransaction(); try { id = db.insertWithOnConflict(AlarmOpenHelper.TABLE_ALARM, null, values, SQLiteDatabase.CONFLICT_REPLACE); db.setTransactionSuccessful(); } catch (Exception e) { Log.e(TAG, "updateAlarmClock: " + e.getMessage()); } finally { db.endTransaction(); } db.close(); return id > 0; } /** * 批量插入数据 * * @param list */ public void insertListValues(List list) { open(); List contentValuesList = new ArrayList<>(); for (AlarmClockData alarmClockData : list) { ContentValues values = new ContentValues(); values.put(AlarmOpenHelper.KEY_ID, alarmClockData.getId()); values.put(AlarmOpenHelper.KEY_TYPE, alarmClockData.getType()); values.put(AlarmOpenHelper.KEY_TIME, alarmClockData.getTime()); values.put(AlarmOpenHelper.KEY_TITLE, alarmClockData.getTitle()); values.put(AlarmOpenHelper.KEY_VOICE, alarmClockData.getVoice()); values.put(AlarmOpenHelper.KEY_VOICE_MD5, alarmClockData.getVoice_md5()); values.put(AlarmOpenHelper.KEY_FILE, alarmClockData.getFile()); values.put(AlarmOpenHelper.KEY_REMIND_TYPE, alarmClockData.getRemind_type()); values.put(AlarmOpenHelper.KEY_IS_ONOFF, alarmClockData.getIs_onoff()); values.put(AlarmOpenHelper.KEY_FINISHED, alarmClockData.isFinished()); contentValuesList.add(values); } db.beginTransaction(); try { for (ContentValues v : contentValuesList) { db.insertWithOnConflict(AlarmOpenHelper.TABLE_ALARM, null, v, SQLiteDatabase.CONFLICT_REPLACE); } db.setTransactionSuccessful(); } catch (Exception e) { Log.e(TAG, "insertListValues: " + e.getMessage()); } finally { db.endTransaction(); } db.close(); } /** * 删除数据 * * @param alarmClockData * @return */ public boolean deleteAlarmClock(AlarmClockData alarmClockData) { if (alarmClockData == null) { return false; } return deleteAlarmClock(alarmClockData.getId()); } public boolean deleteAlarmClock(int RowID) { open(); long id = 0; db.beginTransaction(); try { id = db.delete(AlarmOpenHelper.TABLE_ALARM, "id =" + RowID, null); db.setTransactionSuccessful(); } catch (Exception e) { Log.e(TAG, "deleteAlarmClock: " + e.getMessage()); } finally { db.endTransaction(); } db.close(); return id > 0; } public void deleteAllAlarmClock() { HashSet pendingIntents = getOldPendingIntents(); Iterator pendingIntentIterator = pendingIntents.iterator(); while (pendingIntentIterator.hasNext()) { PendingIntent pendingIntent = pendingIntentIterator.next(); alarmManager.cancel(pendingIntent); pendingIntentIterator.remove(); } List alarmClockData = getAllAlarms(); for (AlarmClockData data : alarmClockData) { deleteAlarmClock(data.getId()); } } /** * 获取所有Alarm * * @return */ public List getAllAlarms() { open(); List list = new ArrayList<>(); String selectQuery = "SELECT * FROM " + AlarmOpenHelper.TABLE_ALARM; open(); Cursor cursor = db.rawQuery(selectQuery, null); if (cursor.moveToFirst()) { do { AlarmClockData alarmClockData = new AlarmClockData(); alarmClockData.setId(Integer.parseInt(cursor.getString(0))); alarmClockData.setType(cursor.getInt(1)); alarmClockData.setTime(cursor.getString(2)); alarmClockData.setTitle(cursor.getString(3)); alarmClockData.setVoice(cursor.getString(4)); alarmClockData.setVoice_md5(cursor.getString(5)); alarmClockData.setFile(cursor.getString(6)); alarmClockData.setRemind_type(cursor.getInt(7)); alarmClockData.setIs_onoff(cursor.getInt(8)); if (cursor.getInt(9) == 1) { alarmClockData.setFinished(true); } else { alarmClockData.setFinished(false); } list.add(alarmClockData); } while (cursor.moveToNext()); } cursor.close(); db.close(); return list; } private HashSet pendingIntents; /** * 设置闹钟列表 * * @param data */ public void setAlarmClockData(List data) { if (pendingIntents == null) { pendingIntents = getOldPendingIntents(); } Iterator pendingIntentIterator = pendingIntents.iterator(); while (pendingIntentIterator.hasNext()) { PendingIntent pendingIntent = pendingIntentIterator.next(); alarmManager.cancel(pendingIntent); pendingIntentIterator.remove(); } // for (PendingIntent pendingIntent : pendingIntents) { // // } List newData = mergeData(data); for (AlarmClockData clockData : newData) { setAlarm(clockData); checkResource(clockData.getFile()); } insertListValues(newData); } private void checkResource(String url) { if (TextUtils.isEmpty(url)) { return; } String fileName = url.substring(url.lastIndexOf("/") + 1, url.length()); if (FileUtil.isVideoFile(fileName)) { String realPath = Utils.getDownLoadPath(mContext) + fileName; File file = new File(realPath); if (!file.exists()) { Aria.download(this) .load(url) //读取下载地址 .setFilePath(Utils.getDownLoadPath(mContext) + fileName) // .ignoreFilePathOccupy() .create(); //启动下载} } }else if (FileUtil.isPictureFile(fileName)){ Glide.with(mContext).load(url); } } /** * 合并闹钟列表,删除不存在闹钟 * * @param alarmClockDataList * @return */ private List mergeData(List alarmClockDataList) { HashMap alarmClockDataMap = new HashMap<>(); if (alarmClockDataList != null) { for (AlarmClockData alarmClockData : alarmClockDataList) { alarmClockDataMap.put(alarmClockData.getId(), alarmClockData); } } HashMap oldData = getOldData(); List deleteData = new ArrayList<>(); for (Map.Entry entry : oldData.entrySet()) { if (alarmClockDataMap.get(entry.getKey()) == null) { deleteData.add(entry.getValue()); } } for (AlarmClockData alarmClockData : deleteData) { deleteAlarmClock(alarmClockData); } List newData = new ArrayList<>(); if (alarmClockDataList == null) { return newData; } for (AlarmClockData alarm : alarmClockDataList) { AlarmClockData oldAlarm = oldData.get(alarm.getId()); if (oldAlarm == null) { newData.add(alarm); } else { if (oldAlarm.equals(alarm)) { newData.add(oldAlarm); } else { newData.add(alarm); } } } return newData; } /** * 更新完成状态 * * @param alarmClockData * @return */ public boolean updateAlarmFinished(AlarmClockData alarmClockData) { open(); ContentValues values = new ContentValues(); values.put(AlarmOpenHelper.KEY_ID, alarmClockData.getId()); values.put(AlarmOpenHelper.KEY_TYPE, alarmClockData.getType()); values.put(AlarmOpenHelper.KEY_TIME, alarmClockData.getTime()); values.put(AlarmOpenHelper.KEY_TITLE, alarmClockData.getTitle()); values.put(AlarmOpenHelper.KEY_VOICE, alarmClockData.getVoice()); values.put(AlarmOpenHelper.KEY_VOICE_MD5, alarmClockData.getVoice_md5()); values.put(AlarmOpenHelper.KEY_FILE, alarmClockData.getFile()); values.put(AlarmOpenHelper.KEY_REMIND_TYPE, alarmClockData.getRemind_type()); values.put(AlarmOpenHelper.KEY_IS_ONOFF, alarmClockData.getIs_onoff()); values.put(AlarmOpenHelper.KEY_FINISHED, alarmClockData.isFinished()); long id = 0; db.beginTransaction(); try { id = db.update(AlarmOpenHelper.TABLE_ALARM, values, AlarmOpenHelper.KEY_ID + "=?", new String[]{String.valueOf(alarmClockData.getId())}); db.setTransactionSuccessful(); } catch (Exception e) { Log.e(TAG, "updateAlarmFinished: " + e.getMessage()); } finally { db.endTransaction(); } db.close(); return id > 0; } public HashMap getOldData() { List alarmClockData = getAllAlarms(); if (alarmClockData == null || alarmClockData.size() == 0) { return new HashMap<>(); } else { HashMap hashMap = new HashMap<>(); for (AlarmClockData clockData : alarmClockData) { hashMap.put(clockData.getId(), clockData); } return hashMap; } } /** * 获取最近一次的闹钟 * * @return */ public AlarmClockData getRecentAlarmClock() { List alarmClockData = getAllAlarms(); if (alarmClockData == null || alarmClockData.size() == 0) { return null; } else { Collections.sort(alarmClockData, new Comparator() { @Override public int compare(AlarmClockData o1, AlarmClockData o2) { if ((o1.getTimeStamp()) <= (o2.getTimeStamp())) { return 0; } else { return -1; } } }); return alarmClockData.get(0); } } private HashSet getOldPendingIntents() { HashSet pendingIntents = new HashSet<>(); HashMap data = getOldData(); for (AlarmClockData alarmClockData : data.values()) { pendingIntents.add(getPendingIntent(alarmClockData)); } return pendingIntents; } private PendingIntent getPendingIntent(AlarmClockData alarmClock) { Intent intent = new Intent(MainService.ALARMWAKEUP); intent.putExtra("title", alarmClock.getTitle()); intent.putExtra("id", alarmClock.getId()); PendingIntent startPendingIntent = PendingIntent.getBroadcast(mContext, alarmClock.getId(), intent, PendingIntent.FLAG_CANCEL_CURRENT); return startPendingIntent; } private long getTimestamp(String timeString) { if (TextUtils.isEmpty(timeString)) { return 0; } if (timeString.length() == 5) { String[] timeSplit = timeString.split(":"); int hour = Integer.parseInt(timeSplit[0]); int minute = Integer.parseInt(timeSplit[1]); Calendar c = Calendar.getInstance(); int year = c.get(Calendar.YEAR); int month = c.get(Calendar.MONTH); int day = c.get(Calendar.DAY_OF_MONTH); c.set(year, month, day, hour, minute, 0); long mTimeInfo = c.getTimeInMillis(); Log.e(TAG, "getTimestamp: " + mTimeInfo); // long actualTime = mTimeInfo > System.currentTimeMillis() ? mTimeInfo : mTimeInfo + ONE_DAY_TIME; return mTimeInfo; } else { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm"); try { Date date = simpleDateFormat.parse(timeString); long timestamp = date.getTime(); Log.e(TAG, "getTimestamp2: " + timestamp); return timestamp; } catch (ParseException e) { return System.currentTimeMillis(); } } } private long getZeroTiemstamp() { //设置时区 Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT+8")); calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); long zeroTime = calendar.getTimeInMillis(); Log.e(TAG, "getZeroTiemstamp: " + zeroTime); return zeroTime; } /*一次性*/ public static final int ONCE = 1; /*每天*/ public static final int LOOP = 2; /*周一到周五*/ public static final int WORKING_DAY = 3; /*休息日*/ public static final int OFF_DAY = 4; /** * 设置闹钟 * * @param alarm */ public void setAlarm(AlarmClockData alarm) { int id = alarm.getId(); int type = alarm.getType(); String timeString = alarm.getTime(); String title = alarm.getTitle(); Log.e(TAG, "setAlarm: " + title); long timeStamp = getTimestamp(timeString); Log.e(TAG, "setAlarm: " + timeStamp); boolean finished = alarm.isFinished(); String url = alarm.getVoice(); String md5 = alarm.getVoice_md5(); if (!TextUtils.isEmpty(url)) { ariaDownload(url, md5); } switch (type) { case ONCE: if (!finished) { if (timeStamp < System.currentTimeMillis()) { Intent intent = new Intent(MainService.ALARMWAKEUP); intent.putExtra("title", title); intent.putExtra("id", id); mContext.sendBroadcast(intent); } else { setOnceAlarm(MainService.ALARMWAKEUP, title, id, timeStamp); } } break; case LOOP: setDayLoopAlarm(MainService.ALARMWAKEUP, title, id, timeString); break; case WORKING_DAY: setWorkDayAlarm(MainService.ALARMWAKEUP, title, id, timeString); break; case OFF_DAY: setOffDayAlarm(MainService.ALARMWAKEUP, title, id, timeString); break; default: } } /** * @param action * @param requestCode * @param timestamp 设置一次性闹钟 */ public void setOnceAlarm(String action, String extra, int requestCode, long timestamp) { Intent intent = new Intent(action); intent.putExtra("title", extra); intent.putExtra("id", requestCode); PendingIntent startPendingIntent = PendingIntent.getBroadcast(mContext, requestCode, intent, PendingIntent.FLAG_CANCEL_CURRENT); pendingIntents.add(startPendingIntent); alarmManager.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, timestamp, startPendingIntent); Log.e(TAG, "setOnceAlarm: " + "id: " + requestCode + " title: " + extra + " timeString: " + timestamp); } /** * @param action * @param requestCode * @param timeString 设置循环周期为一天的闹钟 */ public void setDayLoopAlarm(String action, String extra, int requestCode, String timeString) { long timestamp = getTimestamp(timeString); if (System.currentTimeMillis() > timestamp) { timestamp += AlarmManager.INTERVAL_DAY; } Intent intent = new Intent(action); intent.putExtra("title", extra); intent.putExtra("id", requestCode); PendingIntent startPendingIntent = PendingIntent.getBroadcast(mContext, requestCode, intent, PendingIntent.FLAG_CANCEL_CURRENT); pendingIntents.add(startPendingIntent); alarmManager.setExact(AlarmManager.RTC_WAKEUP, timestamp, startPendingIntent); Log.e(TAG, "setDayLoopAlarm: " + "title: " + extra + " timeString: " + timestamp); // setLoopAlarm(action, extra, requestCode, AlarmManager.INTERVAL_DAY, timestamp); } /** * @param action * @param requestCode * @param timestamp 设置循环周期为一小时的闹钟 */ public void setHourLoopAlarm(String action, String extra, int requestCode, long timestamp) { setLoopAlarm(action, extra, requestCode, AlarmManager.INTERVAL_HOUR, timestamp); } /** * @param action * @param requestCode * @param intervalMillis * @param timestamp 循环闹钟 */ public void setLoopAlarm(String action, String extra, int requestCode, long intervalMillis, long timestamp) { Intent intent = new Intent(action); intent.putExtra("title", extra); intent.putExtra("id", requestCode); PendingIntent startPendingIntent = PendingIntent.getBroadcast(mContext, requestCode, intent, PendingIntent.FLAG_CANCEL_CURRENT); pendingIntents.add(startPendingIntent); alarmManager.setWindow(AlarmManager.RTC_WAKEUP, timestamp, intervalMillis, startPendingIntent); Log.e(TAG, "setLoopAlarm: " + "title: " + extra + " timeString: " + timestamp); } public void setWorkDayAlarm(String action, String extra, int requestCode, String timeString) { long timestamp = getTimestamp(timeString); Calendar calendar = Calendar.getInstance(); int day_of_week = calendar.get(Calendar.DAY_OF_WEEK) - 1; switch (day_of_week) { case 6: case 7: timestamp += (8 - day_of_week) * AlarmManager.INTERVAL_DAY; break; default: if (System.currentTimeMillis() > timestamp) { timestamp += AlarmManager.INTERVAL_DAY; } break; } Intent intent = new Intent(action); intent.putExtra("title", extra); intent.putExtra("id", requestCode); PendingIntent startPendingIntent = PendingIntent.getBroadcast(mContext, requestCode, intent, PendingIntent.FLAG_CANCEL_CURRENT); pendingIntents.add(startPendingIntent); alarmManager.setExact(AlarmManager.RTC_WAKEUP, timestamp, startPendingIntent); Log.e(TAG, "setWorkDayAlarm: " + "title: " + extra + " timeString: " + timestamp); } public void setOffDayAlarm(String action, String extra, int requestCode, String timeString) { long timestamp = getTimestamp(timeString); Calendar calendar = Calendar.getInstance(); int day_of_week = calendar.get(Calendar.DAY_OF_WEEK) - 1; switch (day_of_week) { case 6: if (System.currentTimeMillis() > timestamp) { timestamp += AlarmManager.INTERVAL_DAY; } break; case 7: break; default: timestamp += (6 - day_of_week) * AlarmManager.INTERVAL_DAY; break; } Intent intent = new Intent(action); intent.putExtra("title", extra); intent.putExtra("id", requestCode); PendingIntent startPendingIntent = PendingIntent.getBroadcast(mContext, requestCode, intent, PendingIntent.FLAG_CANCEL_CURRENT); pendingIntents.add(startPendingIntent); alarmManager.setExact(AlarmManager.RTC_WAKEUP, timestamp, startPendingIntent); Log.e(TAG, "setOffDayAlarm: " + "title: " + extra + " timeString: " + timestamp); } public void ariaDownload(String url, String md5) { String fileName = Utils.getFileNamefromURL(url); File file = new File(Utils.getDownLoadPath(mContext) + fileName); if (file.exists() && !file.isDirectory()) { String fileMD5 = FileUtils.getFileMD5ToString(file); Log.e("ariaDownload", "fileOnlineMD5=" + md5); Log.e("ariaDownload", "fileMD5=" + fileMD5); if (!md5.equals(fileMD5)) { Aria.download(this) .load(url) //读取下载地址 .setFilePath(Utils.getDownLoadPath(mContext) + fileName) // .ignoreFilePathOccupy() .setExtendField(md5) .create(); //启动下载} } else { Log.e("ariaDownload", "fileName = " + fileName + " exists"); } } else { Aria.download(this) .load(url) //读取下载地址 .setFilePath(Utils.getDownLoadPath(mContext) + fileName) // .ignoreFilePathOccupy() .setExtendField(md5) .create(); //启动下载} } } }