閱讀104 返回首頁    go 阿裏雲 go 技術社區[雲棲]


自定義Notification並利用Handler更新Notification

 

在消息通知的時候,我們經常用到兩個控件Notification和Toast。特別是重要的和需要長時間顯示的信息,用Notification最合適不過了。他可以在頂部顯示一個圖標以標示有了新的通知,當我們拉下通知欄的時候,可以看到詳細的通知內容。

最典型的應用就是未看短信和未接來電的顯示,還有QQ企鵝,我們一看就知道有一個未接來電或者未看短信,正在掛QQ。同樣,我們也可以自定義一個Notification來定義我們自己的程序想要傳達的信息。

Notification我把他分為兩種,一種是默認的顯示方式,另一種是自定義的。

默認的Notification設置方式見我的早一篇博文
https://www.liuzhaocn.com//?p=364

在這裏我主要介紹自定義Notification的用法,自定義Notification原理很簡單,就是把通知區域自己寫一個View,在代碼裏把Notification的contantview設置為我們自定義的view即可。

例如,這裏有一個View

XML語言: notification.xml
<?xml version=”1.0″ encoding=”utf-8″?>
<LinearLayout android:id=“@+id/noti_lay”
xmlns:android=“https://schemas.android.com/apk/res/android”
android:layout_width=“wrap_content”
android:layout_height=“fill_parent”
android:orientation=“vertical”
>
    <LinearLayout android:id=“@+id/top_lay”
        xmlns:android=“https://schemas.android.com/apk/res/android”
        android:layout_width=“wrap_content”
        android:layout_height=“wrap_content”
        android:orientation=“horizontal”
        >
        <ImageView android:id=“@+id/down_iv”
            android:layout_width=“30sp”  �
            android:layout_height=“30sp”
            android:src=“@drawable/downnoti”
            />
        <TextView android:id=“@+id/down_tv”
            android:layout_width=“wrap_content”  �
            android:layout_height=“fill_parent”
            android:textSize=“20sp”
            android:textColor=“#000000″
            />
    </LinearLayout>
    <LinearLayout android:id=“@+id/progress_lay”
        xmlns:android=“https://schemas.android.com/apk/res/android”
        android:layout_width=“wrap_content”
        android:layout_height=“fill_parent”
        android:orientation=“horizontal”
        >
        <TextView android:id=“@+id/down_rate”
            android:layout_width=“wrap_content”  �
            android:layout_height=“fill_parent”
            android:textSize=“20sp”
            android:textColor=“#000000″
            />
        <ProgressBar android:id=“@+id/pb”
            android:layout_width=“260dip”
            android:layout_height=“wrap_content”
            style=“?android:attr/progressBarStyleHorizontal”
            android:layout_gravity=“center_vertical”/>
    </LinearLayout>
</LinearLayout>

把他放在layout文件夾下。
這就是在通知區域要顯示的東西,顯示效果如下:

操作Notification的代碼:

Java語言: Codee#17015
public Notification downloadNotification;
public NotificationManager downloadNM;

//……..

/**
                 * 添加頂部下載通知
                 * liuzhao
                 */
                downloadNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
                downloadNotification = new Notification(R.drawable.downnoti,apkname+“下載…”,System.currentTimeMillis());
                downloadNotification.contentView = newRemoteViews(getPackageName(),R.layout.notification);
                //設置進度條的最大進度和初始進度
                downloadNotification.contentView.setProgressBar(R.id.pb, 100,0, false);
                //顯示下載的包名
                downloadNotification.contentView.setTextViewText(R.id.down_tv, apkname);
                //顯示下載的進度
                downloadNotification.contentView.setTextViewText(R.id.down_rate, “0%”);
              �
                Intent notificationIntent = new Intent(tykmAndroid.this,tykmAndroid.class);
                PendingIntent contentIntent =PendingIntent.getActivity(tykmAndroid.this,0,notificationIntent,0);
                downloadNotification.contentIntent = contentIntent;
                //顯示通知
                downloadNM.notify(downNotiID, downloadNotification);
              �
                //…….

以上是讓通知顯示出來,下邊要根據下載的進度,改變進度條的進度:
下載進程中的核心代碼:

Java語言: 下載進程

InputStream is = conn.getInputStream();
                            FileOutputStream fos = new FileOutputStream(file);
                            byte[] bt = new byte[1024];
                            int i = 0;
                            int progresCount = 0;
                            int times = 0;
                            while ((i = is.read(bt)) > 0) {
                                fos.write(bt, 0, i);
                                tykmAndroid.flagloading=1;
                                firstCat.flagloading=1;
                                long tempFileLength = file.length();
                                if((times == 512)||(tempFileLength == length)){
                                    //更新通知中的進度條
                                    int progress = (int)(tempFileLength*100/length);
                                    if(progresCount<progress){
                                        
                                        progresCount=progress;
                                        System.out.println("progresCount="+progresCount);
                                        
                                        //利用Handler在主線程中更新
                                        Message msg = new Message();
                                        msg.what = 6001;
                                        Bundle b = new Bundle();
                                        b.putInt("progressValue", progresCount);
                                        b.putString("apkName", filename);
                                        msg.setData(b);
                                        tykmAndroid.tykmAndroid_Entity.handler.sendMessage(msg);
                                        
                                    }
                                    times=0;
                                    continue;
                                }
                                times++;
                            }
                            fos.flush();
                            fos.close();
                            is.close();
                            conn.disconnect();

這裏沒有直接對通知進行更新,而是用了一個handler,讓UI線程去更新。
UI線程中的Handler是這樣寫的:

Java語言: Handler中的核心代碼

case 6001://下載的時候更新Notification
                Bundle b = msg.getData();
                //得到進度條的當前值
                int progressCount = b.getInt("progressValue");
                //得到包名
                String apkName = b.getString("apkName");
                
                //下載未完成,顯示進度條
                if(progressCount !=100 ){
                    //設置進度條
                    downloadNotification.contentView.setProgressBar(R.id.pb, 100, progressCount, false);
                    //設置百分比
                    downloadNotification.contentView.setTextViewText(R.id.down_rate,""+progressCount+"%");
                    //更新進度條
                }
                //下載完成,顯示下載完成
                else{
                    downloadNotification.contentView.removeAllViews(R.id.progress_lay);
                    PendingIntent contentIntent =PendingIntent.getActivity(tykmAndroid.tykmAndroid_Entity, 0, getIntent(), 0); 
                   downloadNotification.setLatestEventInfo(tykmAndroid.tykmAndroid_Entity,apkName,"下載完成",contentIntent);
                }
                downloadNM.notify(downNotiID, downloadNotification);
                break;

這裏有一段代碼:
在Download線程裏麵:
if((times == 512)||(tempFileLength == length)){
這是防止頻繁地更新通知,而導致係統變慢甚至崩潰。
非常重要。。。。。

最後更新:2017-04-02 06:51:59

  上一篇:go Jni使用過程中出現 error: request for member &#39;FindClass&#39; in something not a structure or union,解決辦法
  下一篇:go SQL與Excel導入導出