消息广播
四大组件之一,用于响应来自其它应用程序或者系统的广播消息。这些消息被称为事件或意图。广播可以被一个以上的应用程序接收,也可以不被任何程序接收。
使用场景
- 同一app内同一组件内的消息通信(单个或多个线程);
- 同一app内部的不同组件之间的消息通信(单个进程);
- 同一app具有多个进程的不同组件之间的消息通信;
- 不同app之间的组件之间消息通信;
- Android系统在特定情况下与App之间的消息通信。
三要素
广播
用于发送广播,是一种运用在应用程序之间的传递消息的机制。
广播接收器(过滤)
用于接收广播,是对发出来的广播进行过滤、接收、响应的组件。
意图内容
用于保存广播相关信息。
使用方法
1 | Intent intent = new Intent(); |
系统产生的事件被定义为类Intent中的静态常量值。下面的表格列举了重要的系统事件
新版本Android,发送静态广播,必须是定向广播,否则收不到。
需要设置
Package
1 | intent.setPackage("com.example.app"); //这是在代码中的设置,加在sendBroadcast之前 |
- 发送广播
1 | sendBroadcast(intent); //使用sendBroadcast方法发送广播内容 |
- 创建广播接收器
New—Other—Broadcast Receiver
注意不是创建Activity而是Broadcast Receiver
编写一个继承BroadcastReceiver的广播接收器,并重写onReceive方法
1 | class BCReceiver extends BroadcastReceiver{ |
- 注册广播接收器
在AndroidManifest.xml中注册广播接受类(系统会自动完成这个过程,默认静态注册)。
(1)静态注册
直接在AndroidManifest.xml文件中进行注册。规则如下:
1 | <receiver android:enabled=["true" | "false"] |
属性介绍
- android:name:此broadcastReceiver的类名
- android:enabled:是否可以被系统实例化,默认为 true。为true时服务才会被激活,否则不会激活
- android:exported:此broadcastReceiver能否接收其他App的发出的广播,其默认值是由receiver中有无
- intent-filter决定的,如果有intent-filter,默认值为true,否则为false
- android:permission:如果设置,具有相应权限的广播发送方发送的广播才能被此broadcastReceiver所接收;
- intent-filter:指定此广播接收器将用于接收特定的广播类型
(2)动态注册
1 | protected void onCreate(Bundle savedInstanceState) { |
- 销毁广播接收器
在一定时间后销毁
动态注册
- 注销
系统服务
Android有许多标准系统服务(SystemService),如窗口管理服务WindowManager,通知管理服务NotificationManager、振动管理服务Vibrator、电池管理服务BatteryManager等。
系统服务实际上可以看作一个对象,通过Activity 的getSystemService() 方法可以获得指定对象(系统服务)。
接下来介绍两个常见的系统服务
通知管理服务
常说的通知栏
Notification是一种具有全局效果的通知,在手机的通知栏显示。当应用程序向系统发出通知时,它先以图标的形式显示在通知栏中,用户下拉通知栏可以查看通知的详细信息。
状态栏通知用到两个类:NotificationManager
和Notification
。
Notification
是具体的状态栏通知对象,可以设置icon、文字、提示声音、振动等等参数。
Notification主要涉及
Notification.Builder()
方法
1 | 小图标:必须提供,通过 setSmallIcon() 进行设置。 |
NotificationManager
状态栏通知的管理类,负责发通知、清除通知等。
NotificationManager是一个系统Service,必须通过getSystemService()方法来获取。
1 | NotificationManager nm=(NotificationManager)getSystemService(NOTIFICATION_SERVICE); |
调用NotificationManager对象的notify()
方法把通知发送到状态栏。
1 | nm.notify(); |
创建通知
首先,您需要使用
NotificationCompat.Builder
对象设置通知内容和渠道。以下示例显示了如何创建包含下列内容的通知:
- 小图标,通过
setSmallIcon()
设置。这是所必需的唯一用户可见内容。 - 标题,通过
setContentTitle()
设置。 - 正文文本,通过
setContentText()
设置。 - 通知优先级,通过
setPriority()
设置。优先级确定通知在 Android 7.1 和更低版本上的干扰程度。(对于 Android 8.0 和更高版本,必须设置渠道重要性,如下一节中所示。)
1 | NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID) |
请注意,NotificationCompat.Builder
构造函数要求您提供渠道 ID。这是兼容 Android 8.0(API 级别 26)及更高版本所必需的,但会被较旧版本忽略。
默认情况下,通知的文本内容会被截断以放在一行。如果您想要更长的通知,可以使用 setStyle()
添加样式模板来启用可展开的通知。例如,以下代码会创建更大的文本区域:
1 | NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID) |
创建渠道并设置重要性
必须先通过向 createNotificationChannel()
传递 NotificationChannel
的实例在系统中注册应用的通知渠道,然后才能在 Android 8.0 及更高版本上提供通知。因此以下代码会被 SDK_INT
版本上的条件阻止:
1 | private void createNotificationChannel() { |
由于您必须先创建通知渠道,然后才能在 Android 8.0 及更高版本上发布任何通知,因此应在应用启动时立即执行这段代码。反复调用这段代码是安全的,因为创建现有通知渠道不会执行任何操作。
请注意,NotificationChannel
构造函数需要一个 importance
,它会使用 NotificationManager
类中的一个常量。此参数确定出现任何属于此渠道的通知时如何打断用户,但您还必须使用 setPriority()
设置优先级,才能支持 Android 7.1 和更低版本(如上所示)。
虽然必须按本文所示设置通知重要性/优先级,但系统不能保证您会获得提醒行为。在某些情况下,系统可能会根据其他因素更改重要性级别,并且用户始终可以重新定义指定渠道适用的重要性级别。
如需详细了解不同级别的含义,请参阅通知重要性级别。
设置通知的点按操作
每个通知都应该对点按操作做出响应,通常是在应用中打开对应于该通知的 Activity。为此,您必须指定通过 PendingIntent
对象定义的内容 Intent,并将其传递给 setContentIntent()
。
以下代码段展示了如何创建基本 Intent,以在用户点按通知时打开 Activity:
1 | // Create an explicit intent for an Activity in your app |
请注意,此代码会调用 setAutoCancel()
,它会在用户点按通知后自动移除通知。
以上所示的 setFlags()
方法可帮助保留用户在通过通知打开应用后的预期导航体验。但您是否要使用这一方法取决于您要启动的 Activity 类型,类型可能包括:
- 专用于响应通知的 Activity。用户在正常使用应用时不会无缘无故想导航到这个 Activity,因此该 Activity 会启动一个新任务,而不是添加到应用的现有任务和返回堆栈。这就是以上示例中创建的 Intent 类型。
- 应用的常规应用流程中存在的 Activity。在这种情况下,启动 Activity 时应创建返回堆栈,以便保留用户对返回和向上按钮的预期。
如需详细了解配置通知 Intent 的不同方法,请参阅从通知启动 Activity。
显示通知
如需显示通知,请调用 NotificationManagerCompat.notify()
,并将通知的唯一 ID 和 NotificationCompat.Builder.build()
的结果传递给它。例如:
1 | NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); |
请记得保存您传递到 NotificationManagerCompat.notify()
的通知 ID,因为如果之后您想要更新或移除通知,将需要使用这个 ID。
注意:从 Android 8.1(API 级别 27)开始,应用每秒最多只能发出一次通知提示音。如果应用在一秒内发出了多条通知,这些通知都会按预期显示,但是每秒中只有第一条通知发出提示音。
区分渠道优先级和通知优先度
区分渠道id和通知id
@NonNull String channelId |
The constructed Notification will be posted on this NotificationChannel. |
---|---|
int id |
the ID of the notification. The pair (tag, id) must be unique within your app. |
系统定时服务
注:Android对时间的控制模式会影响定时效果
后台服务
Service是一种类似Activity的组件,但Service没有用户操作界面,也不能自己启动。需要通过特殊指令才能终止。
创建Service子类
- 重写onClick方法
- 重写onStartCommand方法
- 重写onDestory方法
创建Activity
- 新建Intent对象,建立Activity 与Service的关联。
- 调用Activity的 startSevice(Intent) 方法启动 Service 后合服务;
- 调用Activity 的 stopService(lntent) 方法关闭 Service 后台服务。
修改配置文件AndroidManifest.xml
在<application>标签中添加以下代码
1 | <service android:enabled="true" android:name=".后台服务程序" /> |
数据存储
文件存储
文件读写
Java的输入输出流
Json数据格式
JSON是一种轻量级的数据交换格式,与xml一样,也是基于纯文本的
数据格式。
对象结构JSONObject
JSON对象可以包括多个键值对,要求在大括号“{ }”中书写。
数组结构JSONArray
JSON数组可以包含多个JSON对象做元素,每个元素之间用逗号“, ”分隔,最外面用方括号“ [ ] ”。JSON数组是SON对象的有序集合。
JSON的使用
创建json
1 | JSONObject jsonObject=new JSONObject(); |
放入键值对
1 | json.put("key","value") ; |
assets目录
assets目录是Android的一种特殊目录,用于放置APP所需的固定文件,
且该文件被打包到APK中时,不会被编码到二进制文件。
assets和raw的区别
- assets不会映射到R,而res/raw会映射到R,即可以使用R.raw或getResource()方法获取资源,;assets必须通过AssetManager进行操作。
- assets可以存在多级目录,raw不可以
- 在AssertManager中不能处理单个超过1MB的文件,不然会报异常,raw没这个限制。
轻量级存储SharedPerferences
SharedPreferences 是 Android 平台为应用开发者提供的一个轻量级的存储辅助类,用来保存应用的一些常用配置。
采用键值对的形式组织和管理数据,其数据存储在
XML格式
的文件中。在应用中通常做一些简单数据的持久化存储。类似电脑上的
Cookie
,用于在一段时间内保存数据。
具体步骤
- 获取SharedPerference对象
首先声明一个sp对象,然后获取sp对象。
1 | //声明SharePerference对象 |
- 设置参数
必须通过一个SharedPreference.Editor对象。存储键值对。只能存
放Boolean,Float,Int,Long,String 等类型(对应代码中的Xxx)。
1 | SharedPreference.Editor editor = sp.edit(); |
- 提交数据与清除数据
通过editor.commit()提交数据。也可以通过clean(),remove()清除。
1 | editor.commit(); |
获得对象
三种获得sp对象的方法
- Context类中的getSharedPreferences()方法
1 | //此方法接受两个参数,第一个是指定SharedPreferences的文件名称,第二个参数是操作模式,目前只有MODE_PRIVATE这一种模式可选,表示只有当前文件可以对这个文件进行读写。 |
- Activity类中的getPreferences()方法
1 | //只接受操作模式这一个参数(目前只有MODE_PRIVATE这一种模式可选),使用这个方法的活动类名会作为SharedPreferences的文件名 |
- PreferenceManager类中的getDefaultSharedPreferences()方法
1 | //只接受一个context参数,使用这个方法的包名会作为SharedPreferences的文件名。 |
访问数据
可以使用getXxx()方法获取对应的键值对,第一个参数为key名,第二个参数为不存在key名时的默认值。(Xxx指Boolean,Float,Int,Long,String 等类型)
1 | sp.getString(); |
回调方法
在布局文件中绑定回调函数
xml
1 | android:onClick="function" |
java
1 | public void function(View view){ |