Android权威编程指南笔记 第二十八章 后台服务(未完)

第二十八章 后台服务

服务类(service)

  • 服务能在用户离开当前应用时仍在后台运行
  • 服务类的使用
  1. 继承service类, 例如intentService
  2. 声明service类
    类似于activity, 需要在AndroidManifest中声明
    <service android:name="com.bignerdranch.android.photogallery.PollService"/>
  3. 构造方法
  4. 重写相应的方法
    onHandleIntent(Intent)
  5. 启动, 构造intent并通过Context.startService(intent).

PendingIntent

  • 是一种token对象. 用于描述intent及其最终的行为 不像intent是一种立即的行为.
  • 有三种方法可以了解:
    Pendingintent.getActivity()
    Pendingintent.getService()
    Pendingintent.getBroadcast()
  • Pendingintent.getservice(Context, int, Intent, flags) 打包了一个Context.startService(intent)
    其flags有以下几种标志:
  1. FLAG_ONE_SHOT:只能使用一次的标志. 它将自动为您取消. 以后通过它发送的任何尝试都将失败。
  2. FLAG_NO_CREATE:如果所描述的PendingIntent尚不存在,则只返回null而不创建它。
  3. FLAG_CANCEL_CURRENT: 如果所描述的PendingIntent已存在,则应在生成新内容之前取消当前内容。
  4. FLAG_UPDATE_CURRENT: 如果所描述的PendingIntent已经存在,那么保留它,但用这个新的intent替换它的extra数据。
  5. FLAG_IMMUTABLE: 创建的PendingIntent应是不可变的.
  6. 0: 就意味着你不打算使用任何一种flag来控制PendingIntent的创建。

使用AlarmManager延迟启动服务

  1. 使用Context.ALARM_SERVICE检索
 AlarmManager alarmManager = (AlarmManager)
                context.getSystemService(Context.ALARM_SERVICE);
  1. 设置AlarmManager有三点需要注意:
    1.启动时间的精准与否: 非精准重复setRepeating. 精准启动一次setWindowsetExact, 想重复, 则需要自己手动设置
    2.时间的选择: 基于流逝的相对时间(推荐) 还是达到某个固定的时刻启动
    3.强制唤醒设备(在黑屏状态下): ELAPSED_REALTIME_WAKEUPRTC_WAKEUP
  2. AlarmManager.ELAPSED_REALTIME对应SystemClock.elapsedRealtime() 相对流逝
    AlarmManager.RTC对应SystemClock.currentThreadTimeMillis 固定时刻
  3. private static final long POLL_INTERVAL = TimeUnit.MINUTES.toMillis(1);参数为流逝的时间, 以分钟为单位. 是long型
        Intent i = PollService.newIntent(context);
        PendingIntent pi = PendingIntent.getService(context, 0, i, 0);
        // ALARM_SERVICE 可检索AlarmManager,以便在您选择的时间接收意图。
        AlarmManager alarmManager = (AlarmManager)
                context.getSystemService(Context.ALARM_SERVICE);
        if (isOn){
            alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME,
                    /*表明我们是以SystemClock.elapsedRealtime()走过的时间来确定何时启动。
                    另有 AlarmManager.RTC 启动基准时间就是固定时刻,
                    如SystemClock.currentThreadTimeMillis*/
                    SystemClock.elapsedRealtime(), POLL_INTERVAL, pi );
        }else{
            alarmManager.cancel(pi);
            pi.cancel();
        }

Notification

  • (由于Android 8.0 的各种心累原因)
  • 闪光灯权限<uses-permission android:name="android.permission.FLASHLIGHT"/>
  • 振动器权限 <uses-permission android:name="android.permission.VIBRATE"/>
  • 步骤
  1. 创建NotificationManager
  2. 创建NotificationchannelNotificationChannel channel = new NotificationChannel("fore_service", "前台服务", NotificationManager.IMPORTANCE_HIGH);
    1.ID: 通道的ID。每个包中必须是唯一的。如果值太长,可能会被截断。
    2.name: 频道的用户可见名称。当系统区域设置更改时,可以通过侦听ACTION_LOCALE_CHANGED广播来重命名此频道。建议的最大长度为40个字符;如果值太长,可能会被截断。
    3.importance: 渠道的重要性。这将控制发送到此channel中通知的方式。
  3. NotificationManager中创建Notificationchannel
  4. 创建Notification
  5. 定制Notification的各种行为
  6. 发布notificationNotificationManager.notify(id, Notification) id唯一标识, 如果相同就会替换消息(可以实现类似与进度条或者其他动态视觉效果)
                Intent intent = new Intent(this, NotificationActivity.class);
                PendingIntent pi = PendingIntent.getActivity(this, 0, intent, 0);
                NotificationManager manager = (NotificationManager) getSystemService
                        (NOTIFICATION_SERVICE);

                NotificationChannel channel = new NotificationChannel
                        ("fore_service", "前台服务", NotificationManager.IMPORTANCE_HIGH);
                assert manager != null;
                manager.createNotificationChannel(channel);

                notification = new NotificationCompat.Builder(MainActivity.this, "fore_service")
                            .setContentTitle("This is a content title")
                            .setContentText("This is a content text")
                            .setWhen(System.currentTimeMillis())
                            .setSmallIcon(R.mipmap.ic_launcher)
                            .setLargeIcon(BitmapFactory.decodeResource(getResources(),
                                    R.mipmap.ic_launcher))
                            .setContentIntent(pi)
                            .setAutoCancel(true)  //点击通知后可以取消的第一种方法
                            .setVibrate(new long[]{0, 1000, 1000, 1000})//控制震动的时间,第一个是禁止,第二个是震动。以此类推。
                            .setLights(Color.GREEN, 1000, 1000) //设置呼吸灯的时长,第一个参数是颜色,第二个参数是亮起的时间,第三个参数是暗去的时间
                        /*将其他所有设置为默认值
                        .setDefaults(NotificationCompat.DEFAULT_ALL)
                        设置长文本
                        .setStyle(new NotificationCompat.BigTextStyle().bigText("fahfkhfklhfhashkfhksdhf之类的")
                        设置大图片
                        setStyle(new NotificationCompat.BigPictureStyle().bigPicture
                            (BitmapFactory.decodeResource(getResource, R.drawable.big_image))
                        设置通知的重要级别
                        .setPriority(NotificationCompat.PRIORITY_MAX)  这里直接弹出横幅
                        有几种级别:
                        _DEFAULT, _MIN, _LOW, _HIGH, _MAX,
                        */
                            .build();
                manager.notify(1, notification);
                Log.d(TAG, "正常运行");
  • 取消通知栏的第二种方法
    在跳转到的界面取消
        //取消通知栏的第二种方法
        NotificationManager manager = (NotificationManager) getSystemService
                (NOTIFICATION_SERVICE);
        manager.cancel(1);

相关小记

  • 相关服务还没有学习
  1. non-sticky
  2. sticky
  3. 绑定服务: 本地服务绑定和远程服务绑定

挑战练习

  • 可穿戴设备上的通知
  • 在Lollipop设备上使用JobScheduleJobService
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值