|
|
@@ -0,0 +1,338 @@
|
|
|
+package com.usai.redant.rautils.application;
|
|
|
+
|
|
|
+import android.app.Activity;
|
|
|
+import android.app.Application;
|
|
|
+import android.app.Notification;
|
|
|
+import android.app.NotificationChannel;
|
|
|
+import android.app.NotificationManager;
|
|
|
+import android.app.PendingIntent;
|
|
|
+import android.content.ComponentName;
|
|
|
+import android.content.Context;
|
|
|
+import android.content.Intent;
|
|
|
+import android.content.ServiceConnection;
|
|
|
+import android.content.SharedPreferences;
|
|
|
+import android.graphics.BitmapFactory;
|
|
|
+import android.net.Uri;
|
|
|
+import android.os.Build;
|
|
|
+import android.os.Bundle;
|
|
|
+import android.os.IBinder;
|
|
|
+import android.provider.Settings;
|
|
|
+import android.support.v4.app.NotificationCompat;
|
|
|
+import android.text.TextUtils;
|
|
|
+
|
|
|
+import com.usai.redant.rautils.R;
|
|
|
+import com.usai.redant.rautils.receiver.RABroadcast;
|
|
|
+import com.usai.redant.rautils.service.RAService;
|
|
|
+
|
|
|
+import static android.app.Notification.VISIBILITY_PUBLIC;
|
|
|
+import static android.app.PendingIntent.FLAG_UPDATE_CURRENT;
|
|
|
+
|
|
|
+
|
|
|
+public class ApexApplication extends Application {
|
|
|
+
|
|
|
+ // region Activity Life
|
|
|
+ private boolean isBackground = false;
|
|
|
+
|
|
|
+ public boolean isBackground() {
|
|
|
+ return isBackground;
|
|
|
+ }
|
|
|
+
|
|
|
+ private class LifeCallback implements ActivityLifecycleCallbacks {
|
|
|
+
|
|
|
+ private int activityStartCount = 0;
|
|
|
+ private Activity mCurrentActivity = null;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onActivityStarted(Activity activity) {
|
|
|
+ activityStartCount++;
|
|
|
+ mCurrentActivity = activity;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onActivityResumed(Activity activity) {
|
|
|
+
|
|
|
+ if(isBackground==true)
|
|
|
+ {
|
|
|
+ isBackground = false;
|
|
|
+ applicationDidEnterForeground();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onActivityPaused(Activity activity) {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onActivityStopped(Activity activity) {
|
|
|
+
|
|
|
+ activityStartCount--;
|
|
|
+ if(activityStartCount == 0)
|
|
|
+ {
|
|
|
+ isBackground = true;
|
|
|
+ applicationDidEnterBackground();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onActivityDestroyed(Activity activity) {
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // endregion
|
|
|
+
|
|
|
+ // region Life Circle
|
|
|
+
|
|
|
+ private static ApexApplication instance;
|
|
|
+ private LifeCallback mLifeCallback;
|
|
|
+ private ServiceConnection mServiceConnection = null;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onCreate() {
|
|
|
+ super.onCreate();
|
|
|
+ instance = this;
|
|
|
+ mLifeCallback = new LifeCallback();
|
|
|
+ registerActivityLifecycleCallbacks(mLifeCallback);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onTerminate() {
|
|
|
+ super.onTerminate();
|
|
|
+
|
|
|
+ unregisterActivityLifecycleCallbacks(mLifeCallback);
|
|
|
+ if (mServiceConnection != null) {
|
|
|
+ unbindService(mServiceConnection);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // endregion
|
|
|
+
|
|
|
+ // region Getter
|
|
|
+ public static ApexApplication sharedApplication() {
|
|
|
+ return instance;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Activity getCurrentActivity() {
|
|
|
+ if (mLifeCallback != null) {
|
|
|
+
|
|
|
+ return mLifeCallback.mCurrentActivity;
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ // endregion
|
|
|
+
|
|
|
+ // region Callback
|
|
|
+
|
|
|
+ public void applicationDidEnterBackground() {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ public void applicationDidEnterForeground() {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // endregion
|
|
|
+
|
|
|
+ // region Service & Receiver
|
|
|
+
|
|
|
+ private RAService mService;
|
|
|
+ public void startService(Class serviceCls) {
|
|
|
+
|
|
|
+ mServiceConnection = new ServiceConnection() {
|
|
|
+ @Override
|
|
|
+ public void onServiceConnected(ComponentName name, IBinder service) {
|
|
|
+
|
|
|
+ RAService.MyBinder binder = (RAService.MyBinder)service;
|
|
|
+ mService = (RAService) binder.getService();
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onServiceDisconnected(ComponentName name) {
|
|
|
+
|
|
|
+ mService = null;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ Intent serviceintent = new Intent();
|
|
|
+ serviceintent.setClass(this, serviceCls);
|
|
|
+
|
|
|
+ ComponentName cn;
|
|
|
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
|
+ cn =this.startForegroundService(serviceintent);
|
|
|
+ } else {
|
|
|
+ cn =this.startService(serviceintent);
|
|
|
+ }
|
|
|
+
|
|
|
+ Intent intent = new Intent(getApplicationContext(),serviceCls);
|
|
|
+ bindService(intent,mServiceConnection, Context.BIND_AUTO_CREATE);
|
|
|
+ }
|
|
|
+
|
|
|
+ public RAService getService() {
|
|
|
+ return mService;
|
|
|
+ }
|
|
|
+
|
|
|
+ // endregion
|
|
|
+
|
|
|
+ // region Alarm
|
|
|
+
|
|
|
+ public void initAlarm(Class receiverCls) {
|
|
|
+
|
|
|
+ Intent bintent = new Intent(RABroadcast.ACTION_REDANT_INIT_ALARM);
|
|
|
+ bintent.setClass(this, receiverCls);
|
|
|
+ sendBroadcast(bintent);
|
|
|
+ }
|
|
|
+
|
|
|
+ // endregion
|
|
|
+
|
|
|
+ // region Preference
|
|
|
+
|
|
|
+ public SharedPreferences sharedPreferences(String key) {
|
|
|
+
|
|
|
+ SharedPreferences pref=null;
|
|
|
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
|
|
+ {
|
|
|
+ Context c= this.createDeviceProtectedStorageContext();
|
|
|
+ pref = c.getSharedPreferences(key, 0);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ pref = getSharedPreferences(key, 0);
|
|
|
+ }
|
|
|
+ return pref;
|
|
|
+ }
|
|
|
+
|
|
|
+ // endregion
|
|
|
+
|
|
|
+ // region Notification
|
|
|
+
|
|
|
+ public class NotificationContent {
|
|
|
+
|
|
|
+ public static final String ExtraKey = "extra";
|
|
|
+
|
|
|
+ private String title;
|
|
|
+ private String body;
|
|
|
+ private int id;
|
|
|
+ private String extra;
|
|
|
+
|
|
|
+ private int smallIcon;
|
|
|
+ private int largeIcon;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * smallIcon like Driver R.drawable.small_icon_clear
|
|
|
+ * largeIcon like Driver R.drawable.large_notification_icon_clear
|
|
|
+ * */
|
|
|
+ public NotificationContent(int id, String title, String body, int smallIcon, int largeIcon, String extra) {
|
|
|
+ this.id = id;
|
|
|
+ this.title = title;
|
|
|
+ this.body = body;
|
|
|
+ this.extra = extra;
|
|
|
+ this.smallIcon = smallIcon;
|
|
|
+ this.largeIcon = largeIcon;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public Class getMainActivityClass() {
|
|
|
+ return Activity.class;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void showNotification(NotificationContent content, String channelId, String channelName) {
|
|
|
+ if (content == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (TextUtils.isEmpty(content.title) || TextUtils.isEmpty(content.body)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ Intent intent = new Intent(getApplicationContext(), getMainActivityClass());
|
|
|
+ intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP); // getIntent可能是null
|
|
|
+ if (content.extra != null) {
|
|
|
+ intent.putExtra(NotificationContent.ExtraKey,content.extra); // 程序在后台的情况下,点击通知将程序唤醒到前台时,并不能取得extra
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ * requestCode: 需要保证不同,否则id不通的intent取到的extra也是同一个
|
|
|
+ * */
|
|
|
+ int requestCode = content.id;
|
|
|
+ PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), requestCode, intent,FLAG_UPDATE_CURRENT);
|
|
|
+
|
|
|
+ //1.获取系统通知的管理者
|
|
|
+ NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
|
|
|
+
|
|
|
+ Notification noti = null;
|
|
|
+ long[] vibrates = { 0, 1000, 1000, 1000 };
|
|
|
+
|
|
|
+// Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
|
|
|
+ Uri soundUri = Settings.System.DEFAULT_NOTIFICATION_URI;
|
|
|
+
|
|
|
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Oreo不用Priority了,用importance
|
|
|
+ * IMPORTANCE_NONE 关闭通知
|
|
|
+ * IMPORTANCE_MIN 开启通知,不会弹出,但没有提示音,状态栏中无显示
|
|
|
+ * IMPORTANCE_LOW 开启通知,不会弹出,不发出提示音,状态栏中显示
|
|
|
+ * IMPORTANCE_DEFAULT 开启通知,不会弹出,发出提示音,状态栏中显示
|
|
|
+ * IMPORTANCE_HIGH 开启通知,会弹出,发出提示音,状态栏中显示
|
|
|
+ */
|
|
|
+ NotificationChannel channel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_HIGH);
|
|
|
+ // 震动
|
|
|
+ channel.enableVibration(true);
|
|
|
+ channel.setVibrationPattern(vibrates);
|
|
|
+
|
|
|
+ channel.enableLights(true);
|
|
|
+
|
|
|
+ channel.setSound(soundUri, Notification.AUDIO_ATTRIBUTES_DEFAULT);
|
|
|
+
|
|
|
+ nm.createNotificationChannel(channel);
|
|
|
+
|
|
|
+ noti = new NotificationCompat.Builder(this, channelId)
|
|
|
+ .setContentTitle(content.title)
|
|
|
+ .setContentText(content.body)
|
|
|
+ .setSmallIcon(content.smallIcon)
|
|
|
+ .setLargeIcon(BitmapFactory.decodeResource(getResources(),content.largeIcon))
|
|
|
+ .setContentIntent(contentIntent)
|
|
|
+ .setVisibility(VISIBILITY_PUBLIC)
|
|
|
+ .setSound(soundUri)
|
|
|
+ .setLights(0xff00bbff,500,200)
|
|
|
+ .build();
|
|
|
+ } else {
|
|
|
+
|
|
|
+ noti = new Notification.Builder(this)
|
|
|
+ .setContentTitle(content.title)
|
|
|
+ .setContentText(content.body)
|
|
|
+ .setSmallIcon(content.smallIcon)
|
|
|
+ .setLargeIcon(BitmapFactory.decodeResource(getResources(),content.largeIcon))
|
|
|
+ .setContentIntent(contentIntent)
|
|
|
+ .setVisibility(VISIBILITY_PUBLIC)
|
|
|
+ .setSound(soundUri)
|
|
|
+ .setLights(0xff00bbff,500,20)
|
|
|
+ .build();
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * vibrate属性是一个长整型的数组,用于设置手机静止和振动的时长,以毫秒为单位。
|
|
|
+ * 参数中下标为0的值表示手机静止的时长,下标为1的值表示手机振动的时长, 下标为2的值又表示手机静止的时长,以此类推。
|
|
|
+ */
|
|
|
+ noti.vibrate = vibrates;
|
|
|
+
|
|
|
+ noti.flags |= Notification.FLAG_AUTO_CANCEL;
|
|
|
+ nm.notify(content.id, noti);
|
|
|
+ }
|
|
|
+
|
|
|
+ // endregion
|
|
|
+}
|