zoukankan      html  css  js  c++  java
  • 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_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_IDmNotification);

     

    }

     

    }

    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对象可以去掉通知栏上的显示图标

  • 相关阅读:
    java oop
    traceroute
    ping
    ICMP Internet控制报文协议
    window,centos双系统坏了
    bcm53344 gpio驱动分析
    ioctl参数cmd=2错误
    BCM_GPIO驱动测试
    C++ 类和对象
    C++ 内存管理
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/4118961.html
Copyright © 2011-2022 走看看