当程序意外退出时,可以去掉通知栏上显示的图标

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_KEYfalse);

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 通知栏用法例子的更多相关文章

  1. Android GLSurfaceView用法详解(二)

    输入如何处理       若是开发一个交互型的应用(如游戏),通常需要子类化 GLSurfaceView,由此可以获取输入事件.下面有个例子: java代码: package eoe.ClearTes ...

  2. Android通知栏介绍与适配总结

    由于历史原因,Android在发布之初对通知栏Notification的设计相当简单,而如今面对各式各样的通知栏玩法,谷歌也不得不对其进行更新迭代调整,增加新功能的同时,也在不断地改变样式,试图迎合更 ...

  3. [Android Pro] 完美Android Cursor使用例子(Android数据库操作)

    reference to : http://www.ablanxue.com/prone_10575_1.html 完美 Android Cursor使用例子(Android数据库操作),Androi ...

  4. Android Meun 用法

    Android Meun 用法 点击菜单实体键弹出菜单:如下图 main_activity.xml <?xml version="1.0" encoding="ut ...

  5. Android ViewPager 用法

    Android ViewPager 用法 场景:一般第一次打开应用程序时,程序会有一个提示页来给展现应用程序都有哪些功能:或者程序更新时,又更新哪些新特性,都可以使用ViewPager Demo 描述 ...

  6. android通知栏Notification点击,取消,清除响应事件

    主要是检测android通知栏的三种状态的响应事件 这次在实现推送需求的时候,要用到android通知栏Notification点击后进入消息页面,因为要实现一个保存推送用户名字的功能,我在点击后处理 ...

  7. Android --通知栏Notification

    参考博客:Android 通知栏Notification的整合 全面学习 (一个DEMO让你完全了解它) //创建一个通知栏的Builder构造类 (Create a Notification Bui ...

  8. Android Intent 用法全面总结

    [代码全屏查看]-Android Intent 用法全面总结 // [1].[代码] 调用拨号程序 跳至 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] / ...

  9. Android MediaCodec 使用例子

    Android MediaCodec 使用例子 下面的例子是使用MediaCodec 录制到文件的例子. 1 public class AvcEncoder { private MediaCodec ...

随机推荐

  1. Android(java)学习笔记260:JNI之native方法头文件的生成

    1. JDK1.6 ,进入到工程的bin目录下classes目录下: 使用命令: javah  packageName.ClassName 会在当前目录下生成头文件,从头文件找到jni协议方法 下面举 ...

  2. Linux命令 tar 打包解压缩

    --打包:tartar -cvf 命名文件.tar 要压缩的目录tar -xvf 要解压的包.tartar -tf  要查看的包.tartar -f 包.tar -r file             ...

  3. 服务 远程服务 AIDL 进程间通讯 IPC 深化

    示例 aidl接口文件 package com.bqt.aidlservice.aidl; parcelable Person;  package com.bqt.aidlservice.aidl; ...

  4. 一步步启动linux

    可以一步一步启动linux. 在Ubantu刚一启动时,按c健即进入Grub>提示符状态,在此状态下输入(我用的是Ubuntu 13) grub>linux /vmlinuz grub&g ...

  5. Java多线程练习三

    public class ex5 { public static void main(String [] args) { thread5 t1 = new thread5(); thread5_1 t ...

  6. Sass函数--数字函数

    数字函数简介 Sass 中的数字函数提要针对数字方面提供一系列的函数功能: percentage($value):将一个不带单位的数转换成百分比值: round($value):将数值四舍五入,转换成 ...

  7. Discuz!NT 3.5.2正式版与Asp.net网站会员信息整合

    Discuz!NT 提供了很多对外的接口利于与别的网站进行整合,经本人亲测,觉得开放的接口还是挺到位的.开发.测试一次通过,只不过api文档寻找无门,只能自己琢磨,费了不少周折,不过,功夫不负有心人, ...

  8. Code First研究学习2_基本的错误及解决方法

    使用Code First时总有很多的问题出现,以下列举了一些基本的错误及解决方法! 1.当用Enable-Migrations启动数据库迁移后,如果再继续输入Enable-Migrations命令,则 ...

  9. 使用jQuery操作元素的属性与样式

    本文学习如何使用jQuery获取和操作元素的属性和CSS样式. 元素属性和Dom属性 对于下面这样一个标签元素: <img id='img' src="1.jpg" alt= ...

  10. n阶行列式计算----c语言实现(完结)

    花了半天时间,写了这个n阶行列式计算的程序,应该算是比较优美吧,有很多地方多次做了优化,程序占用内存不是很大,要是说小吧,也不合适,因为里边有一个递归,而且递归的深度还比较深.时间复杂度具体没有细看, ...