第八章:丰富你的程序——运用手机多媒体
Android在这方面也做的非常出色,它提供了一系列的API,使得我们可以在程序中调用很多手机的多媒体资源,从而编写出更加丰富多彩的应用程序。
8.1 将程序运行到手机上
8.2 使用通知
通知(Notification)是Android系统中比较有特色的一个功能,当某个应用程序希望向用户发出一些提示信息,而该应用程序又不在前台运行时,就可以借助通知来实现。发出一条通知后,手机最上方的状态栏中会显示一个通知图标,下拉状态栏后就可以看到通知的详细内容了。
8.2.1 通知的基本用法
通知的用法还是比较灵活的,既可以在活动里创建,也可以在广播接收器里创建,当然还可以在下一章中我们即将学习的服务里创建。相比于广播接收器和服务,在活动力创建通知的场景还是比较少的,因为一般只有当程序进入到后台的时候我们才需要使用通知。
- //创建通知的详细步骤:
- //1)需要一个NotificationManager来对通知进行管理,可以调用Context的getSystemService方法获取到。
- NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)
- //2) 接下来需要使用一个Builder构造器来创建Notification对象(使用support-v4库中提供的NotificationCompat类的构造器来创建)
- Notification notification = new NotificationCompat.Builder(context).build(); //这是一个空的Notification对象
- //3)最后只需要调用NotificationManager的notify()方法就可以让通知显示出来了。
- //notify()方法接收两个参数,一个是id(要保证为每个通知所指定的id都是不同的),一个是Notification对象
- manager.notify(1,notification);
- //在最终的build()方法之前连缀任意多的设置方法来创建一个丰富的Notification对象
- NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)
- Notification notification = new NotificationCompat.Builder(context).setContentTitle("This is content title") /*指定通知的标题内容*/ .setContentText("This is content text") /*指定通知的正文内容*/.setWhen("System.currentTimeMillis()) /*指定通知被创建的时间,以毫秒为单位*/.setSmallIcon(R.drawable.small_icon) /*用于设置通知的小图标*/.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.large_icon))/*用于设置通知的大图标*/.build();
到这里就把创建通知的每一个步骤都分析完了,下面就通过一个具体的例子来看一看通知到底是长什么样儿的。
- //新建一个NotificationTest项目,并修改activity_main.xml
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- <Button
- android:id="@+id/send_notice"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="Send notice" />
- LinearLayout>
- //布局文件只有一个Send notice按钮,用于发出一条通知
- //接下来修改MainActivity中的代码
- public class MainActivity extends AppCompatibleActivity implements View.OnClickListener {
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- Button sendNotice = (Button) findViewById(R.id.send_notice);
- sendNotice.setOnClickListener(this);
- }
- @Override
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.send_notice:
- NotificationManager manager = (NotificationManager) getSysytemService(NOTIFICATION_SERVICE);
- Notification notification = new NotificationCompat.Builder(context).setContentTitle("This is content title").setContentText("This is content text".setWhen("System.currentTimeMillis()).setSmallIcon(R.drawable.small_icon)".setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.large_icon)).build();
- manager.notify(1,notfication);
- break;
- default:
- break;
- }
- }
- }
注意:做完以上操作后,点击该通知发现没反应,想要实现通知的点击效果,我们还需要在代码中进行相应的设置,这就涉及了新概念PendingIntent。
PendingIntent:它和Intent有些类似,他们都可以去指明某一个意图,都可以用于启动活动,启动服务以及发送广播等。
不同在于Intent更加倾向于去立即执行某个动作,而PendingIntent更加倾向于在某个合适的时机去执行某个动作。所以可以把他理解为延迟执行的Intent。
PendingIntent提供了几个静态方法用于获取PendingIntent的实例,可以根据需求来选择是使用getActivity()方法、getBroadcast()方法,还是getService()方法。
这几个方法的参数都是一样的;
分别为:Context,0,Intent对象,(FLAG_ONE_SHOT)/ (FLAG_NO_CREATE)/ (FLAG_CANCEL_CURRENT)/(FLAG_UPDATE_CURRENT)/(通常0)
NotificationCompatBuilder这个构造器还可以连缀一个setContentIntent()方法,接收的参数就是PendingIntent对象。(因此就可以通过PendingIntent构建出一个延迟执行的“意图”,当用户点击这条通知时,就会执行相应的逻辑)
//新建一个NotificationActivity,布局起名notification_layout //修改notification_layout <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:textSize="24sp" android:text="This is notification layout" /> RelativeLayout> //相对布局
//接下来修改MainActivity中的代码 //先新建一个intent,在将intent传入PendingIntent,最后用setContentIntent(pi)接收一个PendingIntent对象 public class MainActivity extends AppCompatibleActivity implements View.OnClickListener { ... @Override public void onClick(View v) { switch (v.getId()) { case R.id.send_notice: //使用Intent表达我们想要启动NotificationActivity的“意图” Intent intent = new Intent(this,NotificationActivity.class); //将构建好的intent传入到PendingIntent.getActivity方法里 PendingIntent pi = PendingIntent.getActivity(this,0,intent,0); NotificationManager manager = (NotificationManager) getSysytemService(NOTIFICATION_SERVICE); Notification notification = new NotificationCompat.Builder(context).setContentTitle("This is content title").setContentText("This is content text".setWhen("System.currentTimeMillis()).setSmallIcon(R.drawable.small_icon)".setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.large_icon)).setContentIntent(pi)/*接收一个PendingIntent对象*/.build(); manager.notify(1,notfication); break; default: break; } } }注意:如果我们没有在代码中对该通知进行取消,他就会一直显示在系统的状态栏
解决办法:1)在NotificationCompat.Builder中再连缀一个setAutoCancel()方法2)显式调用NotificationManager的cancel方式将它取消
//1) Notification notification = new NotificationCompat.Builder(this).setAutoCancel(true).build(); //2) public class NotificationActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.notification_layout); NotificationManager manager = (NotificationManager) getSysytemService(NOTIFICATION_SERVICE); manager.cancel(1); //这里的1是通知的id,对应manager.notify(1,notification)中的1 } }
8.2.2 通知的进阶技巧
setSound()可以在通知发出的时候播放一段音频,这样能够更好地告知用户有通知的到来。
- //setSound方法接收一个Uri参数,所以在指定音频文件的时候还需要先获取到音频文件对应的URI
- //在手机的/system/media/audio/ringtones目录下选取的音频文件
- Notification notification = new NotificationCompat.Builder(this).setSound(Uri.fromFile(new File("/system/media/audio/ringtones/Luna.ogg"))).build();
vibrate:是一个长整型数组,用于设置手机静止和振动的时长,以毫秒为单位
参数分别表示:手机静止时长,手机振动的时长,又表示时间静止的时长...
- //表示让手机在通知到来的时候立刻振动1秒,然后静止1秒,再振动1秒(以毫秒为单位)
- Notification notification = new NotificationCompat.Builder(this).setVibrate(new long[] {0,1000,1000,1000}).build();
- //想要控制手机的振动还要声明权限,还得编辑AndroidManifest.xml文件
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.example.notificationtest"
- android:versionCode="1"
- android:versionName="1.0" >
- ...
- <uses-permission android:name="android.permission.VIBRATE"/>
- ...
- manifest>
setLights(Color.GREEN,1000,1000) //实现LED灯一闪一闪的效果
作用及参数:当有未接电话或未读短信时,可以让LED灯闪烁提醒用户去看
参数分别为:LED灯的颜色,LED灯亮起的时长,LED灯暗去的时长
setDefaults(NotificationCompat.DEFAULT_ALL) //直接使用通知的默认效果
8.2.3 通知的高级功能
正常情况下,若通知的正文部分较多,通知内容是无法显示完整的,多余的部分会用省略号代替,但是如果真的非常需要在通知当中显示一长段文字,Android也是支持的,通过setStyle()就可以做到。
- //通知里显示长文本
- //new NotificationCompat.BigTextStyle()方法是用来封装长文字信息的,调用它的bigText将文字传入就行
- Notification notification = new NotificationCompat.Builder(this).setStyle(new NotificationCompat.BigTextStyle().bigText("dhwih hfioeafew fhalhfeuw fhewioqpfe fheaofhewdhiow fehiwoqfheiow fheiowqufeiw fhewioqfpeiw fheiwoqf.")).build();
- //通知里显示大图片
- //通过BitmapFactory的decodeResources()方法将图片解析成Bitmap对象
- Notification notification = new NotificationCompat.Builder(this).setStyle(new NotificationCompat.BigPictureStyle().bigPicture(BitmapFactory.decodeResources(getResoruces(),,R.drawable.big_image))).build();
setPriority(整型参数)方法用于设置通知的重要程度,它接收一个整型参数,五个常量值可选,分别为:
1)PRIORITY_DEFAULT 默认程度
2)PRIORITY_MIN 最低重要程度
3)PRIORITY_LOW 较低重要程度:系统可能会将它缩小排在后面
4)PRIORITY_HIGH 较高重要程度:系统可能会改变他的位置排在前面
5)PRIORITY_MAX 最高重要程度:这类通知消息必须要让用户立刻看到