使用AlarmManager 定时发送Notification

 1.新建闹钟定时器

private AlarmManager alarmMgr;
private PendingIntent alarmIntent;

alarmMgr = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE);
//跳转到AlarmReceiver广播接收
Intent alaIntent = new Intent(getContext(), AlarmReceiver.class);
//识别不同的闹钟类型
alaIntent.setAction("com.cy.TIMER_ACTION");
SickPersonVo sickPersonVo = application.sickPersonVo;
//传递对象消息,对象类里要序列化(引用的也要序列化)
alaIntent.putExtra("sickPerson", sickPersonVo);
//第二个参数是id
alarmIntent = PendingIntent.getBroadcast(getContext(),
        Integer.parseInt(sickPersonVo.ZYH.substring(sickPersonVo.ZYH.length() - 4)),
        alaIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
alarmMgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 3600 * 1000, alarmIntent);

2.创建广播接收器

public class AlarmReceiver extends BroadcastReceiver {

    private NotificationManager m_notificationMgr = null;

    private NotificationManager mNManager;

    private Notification notify;


    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    public void onReceive(Context context, Intent intent) {
        mNManager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
        if (intent.getAction().equals("com.cy.TIMER_ACTION")) {
            //传递参数,在UserModelActivity的onNewIntent方法中跳转到对象的fragment
            Intent notifyIntent = new Intent(context, UserModelActivity.class);
            SickPersonVo sickPerson = (SickPersonVo) intent.getSerializableExtra("sickPerson");
            notifyIntent.putExtra("sickPerson", sickPerson);
            int id = Integer.parseInt(sickPerson.ZYH.substring(sickPerson.ZYH.length() - 4));
            Log.e("alarm_receiver", "定时闹钟:" + id);
            PendingIntent pit = PendingIntent.getActivity(context, Integer.parseInt("1" + sickPerson.ZYH.substring(sickPerson.ZYH.length() - 4)), notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
            Notification.Builder mBuilder = new Notification.Builder(context);
            mBuilder.setContentTitle("title")
                    .setSmallIcon(R.drawable.ic_launcher)
                    .setContentText("msg")      //内容
                    //点击通知后自动清除
                    .setAutoCancel(true)
                    .setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE)
                    .setContentIntent(pit);
            notify = mBuilder.build();
            mNManager.notify(id, notify);
        }
    }

}

 3.在AndroidManifest.xml注册广播接收器

 <receiver android:name="com.bsoft.mob.ienr.receiver.AlarmReceiver">
    <intent-filter>
         //要拦截的action
         <action android:name="com.cy.TIMER_ACTION" />
    </intent-filter>
 </receiver>

4.UserModelActivity中跳转的方法

@Override
    protected void onNewIntent(Intent intent) {
        if (intent.getSerializableExtra("sickPerson") != null) {
            SickPersonVo person = (SickPersonVo) intent.getSerializableExtra("sickPerson");
            AppApplication application = (AppApplication) getApplication();
            application.sickPersonVo = person;
            TransfusionBloodTourFragment bloodFragment = new TransfusionBloodTourFragment();
            switchContent(bloodFragment);
        } else {
            fastSwitch(intent);
        }
    }

Activity启动模式详解

在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作。在Android中Activity的启动模式决定了Activity的启动运行方式。

Android总Activity的启动模式分为四种:

1 Standard模式

Standard模式是Android的默认启动模式,你不在配置文件中做任何设置,那么这个Activity就是standard模式,这种模式下,Activity可以有多个实例,每次启动Activity,无论任务栈中是否已经有这个Activity的实例,系统都会创建一个新的Activity实例,以下是实验验证。

2 SingleTop模式

SingleTop模式和standard模式非常相似,主要区别就是当一个singleTop模式的Activity已经位于任务栈的栈顶,再去启动它时,不会再创建新的实例,如果不位于栈顶,就会创建新的实例,现在把配置文件中FirstActivity的启动模式改为SingleTop,我们的应用只有一个Activity,FirstActivity自然处于任务栈的栈顶。

3 SingleTask模式

         SingleTask模式的Activity在同一个Task内只有一个实例,如果Activity已经位于栈顶,系统不会创建新的Activity实例,和singleTop模式一样。但Activity已经存在但不位于栈顶时,系统就会把该Activity移到栈顶,并把它上面的activity出栈。

4 SingleInstance模式

singleInstance模式也是单例的,但和singleTask不同,singleTask只是任务栈内单例,系统里是可以有多个singleTask Activity实例的,而singleInstance Activity在整个系统里只有一个实例,启动一singleInstanceActivity时,系统会创建一个新的任务栈,并且这个任务栈只有他一个Activity。

SingleInstance模式并不常用,如果我们把一个Activity设置为singleInstance模式,你会发现它启动时会慢一些,切换效果不好,影响用户体验。它往往用于多个应用之间,例如一个电视launcher里的Activity,通过遥控器某个键在任何情况可以启动,这个Activity就可以设置为singleInstance模式,当在某应用中按键启动这个Activity,处理完后按返回键,就会回到之前启动它的应用,不影响用户体验。

onNewIntent(Intent intent)方法

当我们在activity的启动模式中设置为栈内唯一时,也就是android:launchMode=”singleTask”或android:launchMode=”signleTop”时,会用到这个方法。

比如说在一个应用中A activity 跳转至 B activity 在跳转至 C activity 然后C做了一定的操作之后再返回A 界面。这样在A activity的启动模式设置为singleTask后。C界面跳转至A界面时,就会去判断栈内是否有改Activity实例,如果有就直接执行A界面的onNewIntent()方法,我们就可以把逻辑处理放在改生命周期方法中,如果没有就会走Activity的oncrate方法去创建实例。

在比如说我们做了一个应用。没个界面都有一个返回至主界面操作的按钮。这样的话我们就给主界面的启动模式设置为android:launchMode=”singleTask”。当用户在任何界面点击返回至主界面的按钮时,就正常的使用Intent去跳转。只不过在栈内存在主界面的实例时,不会执行onCrate()方法而是执行的onNewIntent()方法。这时我们就把操作逻辑放在此处。

需要注意的是,在onCrate()方法中最好也写一份操作逻辑,因为当系统内存不足时,我们的主界面实例已经被系统回收了,还是会去执行onCrate()方法的。
 

大家遇到一个应用的Activity供多种方式调用启动的情况,多个调用希望只有一个Activity的实例存在,这就需要Activity的onNewIntent(Intent intent)方法了。只要在Activity中加入自己的onNewIntent(intent)的实现加上Manifest中对Activity设置lanuchMode=“singleTask”就可以。

       onNewIntent()非常好用,Activity第一启动的时候执行onCreate()---->onStart()---->onResume()等后续生命周期函数,也就时说第一次启动Activity并不会执行到onNewIntent(). 而后面如果再有想启动Activity的时候,那就是执行onNewIntent()---->onResart()------>onStart()----->onResume().  如果android系统由于内存不足把已存在Activity释放掉了,那么再次调用的时候会重新启动Activity即执行onCreate()---->onStart()---->onResume()等。

     当调用到onNewIntent(intent)的时候,需要在onNewIntent() 中使用setIntent(intent)赋值给Activity的Intent.否则,后续的getIntent()都是得到老的Intent。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值