Android 通知栏用法例子
当程序意外退出时,可以去掉通知栏上显示的图标
1.创建TestNotificationActivity activity类,
package com.notioni.test.notification;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
public class TestNotificationActivity extends Activity implementsView.OnClickListener{
/** Called when the activity is first created. */
private boolean mStart = false;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
int[] ids = {R.id.btnShow,R.id.btnUpdate,R.id.btnRemove};
for(int i = 0; i < ids.length; i++){
findViewById(ids[i]).setOnClickListener(this);
}
mStart = false;
}
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.btnShow://显示通知栏
mStart = true;
sendMsgToService(NotificationService.KEY_COMMAND_SHOW,mStart);
break;
case R.id.btnUpdate://修改通知栏内容
sendMsgToService(NotificationService.KEY_COMMAND_UPDATE,!mStart);
break;
case R.id.btnRemove:
mStart = false;//移除通知栏
sendMsgToService(NotificationService.KEY_COMMAND_REMOVE,mStart);
break;
}
}
@Override
protected void onDestroy() {
mStart = false;
sendMsgToService(NotificationService.KEY_COMMAND_REMOVE,mStart);
super.onDestroy();
}
private void sendMsgToService(String cmd,boolean isStart){
Intent intent = new Intent(this,NotificationService.class);
intent.setAction(NotificationService.ACTION_NOTIFICATION_CONTROL);
intent.putExtra(NotificationService.COMMAND_KEY, cmd);
intent.putExtra(NotificationService.TIME_KEY, isStart);
startService(intent);
}
}
2.main.xml 显示几个button,用来演示效果
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Button
android:id="@+id/btnShow"
android:layout_width="fill_parent"
android:layout_height="100dip"
android:text="@string/notification_show"
/>
<Button
android:id="@+id/btnUpdate"
android:layout_width="fill_parent"
android:layout_height="100dip"
android:text="@string/notification_update"
/>
<Button
android:id="@+id/btnRemove"
android:layout_width="fill_parent"
android:layout_height="100dip"
android:text="@string/notification_remove"
/>
</LinearLayout>
3.NotificationService.java
对Notification显示,修改,移除操作的核心类
package com.notioni.test.notification;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.SystemClock;
import android.util.Log;
import android.widget.RemoteViews;
public class NotificationService extends Service {
private static final String TAG = "NotificationService";
public static final String ACTION_NOTIFICATION_CONTROL ="action_notification_control";
public static final String COMMAND_KEY = "cmd_key";
public static final String KEY_COMMAND_SHOW = "show_notification";
public static final String KEY_COMMAND_UPDATE = "update_notification";
public static final String KEY_COMMAND_REMOVE = "remove_notification";
public static final String TIME_KEY = "time_key";
public static final int NOTIFICATIN_ID = 100;
private Notification mNotification;
private long mTime;
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
String action = intent.getAction();
//Log.i(TAG, "[onStartCommand] action:"+action);
if(ACTION_NOTIFICATION_CONTROL.equals(action)){
String cmd = intent.getStringExtra(COMMAND_KEY);
boolean isStart = intent.getBooleanExtra(TIME_KEY, false);
Log.i(TAG, "[onStartCommand] action:"+action+",cmd:"+cmd+",isStart:"+isStart);
if(KEY_COMMAND_SHOW.equals(cmd)){
showNotification(isStart);
}else if(KEY_COMMAND_UPDATE.equals(cmd)){
updateNotification(isStart);
}else if(KEY_COMMAND_REMOVE.equals(cmd)){
removeNotification();
}
}else{
Log.e(TAG, "illegality action:"+action);
}
return super.onStartCommand(intent, flags, startId);
}
/*
* 显示在通知栏
*/
private void showNotification(boolean isStart){
createNotification(isStart);
}
/*
* 修改通知栏显示
*/
private void updateNotification(boolean isStart){
createNotification(isStart);
}
/*
* 从通知栏移除
*/
public void removeNotification(){
stopForeground(true);
mTime = 0;
stopSelf();
}
/*
* 创建Notification对象
*/
public void createNotification(boolean started){
if(mNotification == null){
mNotification = new Notification();
mNotification.icon = R.drawable.ic_launcher;
mNotification.flags |=Notification.FLAG_ONGOING_EVENT;//表示正处于活动中
Intent intent = new Intent(this,TestNotificationActivity.class);
//这里要加入此Flags,作用:当你通过点击通知栏来唤起Activity时,对应的Activity启动模式要为android:launchMode="singleTop"
//于此Flag一起使用,可以保证你要启动的Activity不会重新启动,在一个堆栈只有一个对应的实例对象
//使用这个标志,如果正在启动的Activity的Task已经在运行的话,那么,新的Activity将不会启动;代替的,当前Task会简单的移入前台。
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
mNotification.contentIntent = pendingIntent;
RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.notification_layout);
contentView.setImageViewResource(R.id.icon, R.drawable.ic_launcher);
mNotification.contentView = contentView;
mTime = SystemClock.elapsedRealtime();
}
long time = mTime;
mNotification.contentView.setChronometer(R.id.text1, time, null, started);
mNotification.contentView.setTextViewText(R.id.text2, getString(started?R.string.time_running:R.string.time_pause));
//使用服务来启动通知栏,这样的好处时,
//1.当应用程序在后台运行时,startForeground可以使本应用优先级提高,不至于被系统杀掉
//2.当应用被异常挂掉时,可以保证通知栏对应的图标被系统移除
startForeground(NOTIFICATIN_ID, mNotification);
}
}
4. notification_layout.xml文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:baselineAligned="false"
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="65sp"
android:background="@android:drawable/status_bar_item_background"
android:id="@+id/layoutMain"
>
<ImageView android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="4dip"
android:layout_marginRight="6dip" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<Chronometer android:id="@+id/text1"
android:textColor="?android:attr/textColorPrimaryInverse"
android:textStyle="bold"
android:textSize="18sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
/>
<TextView android:id="@+id/text2"
android:textColor="#ff6b6b6b"
android:textSize="14sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
/>
</LinearLayout>
</LinearLayout>
5.AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.notioni.test.notification"
android:versionCode="1"
android:versionName="1.0" >
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".TestNotificationActivity"
android:launchMode="singleTop"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".NotificationService" android:exported="false"></service>
</application>
</manifest>
总结:通知栏采用Service中的startForeground方法去显示到状态栏,
而不采用NotificationManager中的notify的好处有以下两点
1. 当应用程序转入后台运行时startForeground方法可以提高应用程序的运行等级,不至于被系统杀掉
2. 当应用程序由于异常或其他未知的情况下,终止,ActivityManagerService会移除通知栏的图标,不会导致程序已经关闭而图标还显示在通知栏
对startForeground的简单分析说明,此方法会调用ActivityManagerService.java类的setServiceForeground方法,此方法会保存Notification对象,并调用NotificationManger中的notify将通知显示到状态栏,然后设置Service是forground= ture
当应用程序异常退出时ActivityManagerService会监听到应用死亡,根据保存的Notification对象可以去掉通知栏上的显示图标
Android 通知栏用法例子的更多相关文章
- Android GLSurfaceView用法详解(二)
输入如何处理 若是开发一个交互型的应用(如游戏),通常需要子类化 GLSurfaceView,由此可以获取输入事件.下面有个例子: java代码: package eoe.ClearTes ...
- Android通知栏介绍与适配总结
由于历史原因,Android在发布之初对通知栏Notification的设计相当简单,而如今面对各式各样的通知栏玩法,谷歌也不得不对其进行更新迭代调整,增加新功能的同时,也在不断地改变样式,试图迎合更 ...
- [Android Pro] 完美Android Cursor使用例子(Android数据库操作)
reference to : http://www.ablanxue.com/prone_10575_1.html 完美 Android Cursor使用例子(Android数据库操作),Androi ...
- Android Meun 用法
Android Meun 用法 点击菜单实体键弹出菜单:如下图 main_activity.xml <?xml version="1.0" encoding="ut ...
- Android ViewPager 用法
Android ViewPager 用法 场景:一般第一次打开应用程序时,程序会有一个提示页来给展现应用程序都有哪些功能:或者程序更新时,又更新哪些新特性,都可以使用ViewPager Demo 描述 ...
- android通知栏Notification点击,取消,清除响应事件
主要是检测android通知栏的三种状态的响应事件 这次在实现推送需求的时候,要用到android通知栏Notification点击后进入消息页面,因为要实现一个保存推送用户名字的功能,我在点击后处理 ...
- Android --通知栏Notification
参考博客:Android 通知栏Notification的整合 全面学习 (一个DEMO让你完全了解它) //创建一个通知栏的Builder构造类 (Create a Notification Bui ...
- Android Intent 用法全面总结
[代码全屏查看]-Android Intent 用法全面总结 // [1].[代码] 调用拨号程序 跳至 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] / ...
- Android MediaCodec 使用例子
Android MediaCodec 使用例子 下面的例子是使用MediaCodec 录制到文件的例子. 1 public class AvcEncoder { private MediaCodec ...
随机推荐
- C#自定义List类
代码如下: using System; using System.Collections.Generic; using System.Linq; using System.Text; namespac ...
- 知问前端--Ajax
本节课主要是创建一个问题表,将提问数据通过 ajax 方式提交出去.然后对内容显示进行布局,实现内容部分隐藏和完整显示的功能. 一.Ajax 提问创建一个数据表:question,分别建立:id.ti ...
- 转载——CLR标量函数、表值函数和聚合函数(UDA)
本节主要介绍使用CLR创建标量函数,表值函数和聚合函数. 所谓标量函数指的就是此函数只返回一个值.表值函数返回值是一个表.聚合函数是在select语句中使用的,用来聚合一个结果集,类似于Sum()或是 ...
- eclipse中安装genymotion
在eclipse中安装genymotion.安装genymotion需要先安装virtualbox.选择Help选项中的install new software 然后点击进去点击ADD,在locati ...
- c++中static的使用
static可以用来修饰变量,包括函数的局部变量,类的成员变量.可以用来修饰函数,包括类的成员函数,普通函数. 今天就只说说static修饰类之外的函数的情况.假设你写了一个head.h,一个a.cp ...
- Http服务器性能测试工具ab..
-A auth-username:password 对服务器提供BASIC认证信任.用户名和密码由一个:隔开,并以base64编码形式发送,无论服务器是否需要(即,是否发送了401认证需求代码),此字 ...
- C++基于模板顺序表的实现(带排序)
说明:代码是可以运行的,但是发表在博客上后复制到编译器里面报N多错误,找了半天原因是网页里面生成了一些空白字符,这些字符编译器无法识别. 因此使用了2种插入格式插入代码. 第二个带注释解释的代码不可复 ...
- JQuery原理介绍及学习方法
前言 对于JQuery,想必大家都很熟悉.目前,很多web项目,在实施的过程中,考虑到各浏览器原生JS API的兼容性,大都会选用JQuery或类似于JQuery这样的框架来进行网页效果开发.JQue ...
- Oracle字符串分割函数
今天在创建视图的时候,碰到一个问题,问题如下: 将字符格式为“XXX,YYY”分割出来,并且分割后作为两个字段放入视图中. 考虑使用字符分割函数,但是查找资料Oracle没有字符分割的函数(我对Ora ...
- uC/OS 的任务调度解析 (转)
uC/OS 的任务调度解析 1.任务调度器启动之后(初始化,主要是TCB的初始化),就可以创建任务,开始任务调度了,实际上第一个任务准确的说不是进行任务切换,而是进行启动当前最高优先级任务.uC/OS ...