編輯:關於Android編程
代碼中用的自定義常量
public static final int TYPE_Normal = 1;
public static final int TYPE_Progress = 2;
public static final int TYPE_BigText = 3;
public static final int TYPE_Inbox = 4;
public static final int TYPE_BigPicture = 5;
public static final int TYPE_Hangup = 6;
public static final int TYPE_Media = 7;
public static final int TYPE_Customer = 8;
private NotificationManager manger = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
所需權限
<uses-permission android:name="android.permission.VIBRATE">
<uses-permission android:name="android.permission.FLASHLIGHT"></uses-permission></uses-permission>
這是最常見通知樣式,如下圖


舉例
private void simpleNotify(){
//為了版本兼容 選擇V7包下的NotificationCompat進行構造
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
//Ticker是狀態欄顯示的提示
builder.setTicker("簡單Notification");
//第一行內容 通常作為通知欄標題
builder.setContentTitle("標題");
//第二行內容 通常是通知正文
builder.setContentText("通知內容");
//第三行內容 通常是內容摘要什麼的 在低版本機器上不一定顯示
builder.setSubText("這裡顯示的是通知第三行內容!");
//ContentInfo 在通知的右側 時間的下面 用來展示一些其他信息
//builder.setContentInfo("2");
//number設計用來顯示同種通知的數量和ContentInfo的位置一樣,如果設置了ContentInfo則number會被隱藏
builder.setNumber(2);
//可以點擊通知欄的刪除按鈕刪除
builder.setAutoCancel(true);
//系統狀態欄顯示的小圖標
builder.setSmallIcon(R.mipmap.ic_launcher);
//下拉顯示的大圖標
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.push));
Intent intent = new Intent(this,SettingsActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(this,1,intent,0);
//點擊跳轉的intent
builder.setContentIntent(pIntent);
//通知默認的聲音 震動 呼吸燈
builder.setDefaults(NotificationCompat.DEFAULT_ALL);
Notification notification = builder.build();
manger.notify(TYPE_Normal,notification);
}
build內提供了很多設置,但是在不同的系統版本顯示有很多差異,使用時需要注意
效果圖

代碼舉例
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.push));
//禁止用戶點擊刪除按鈕刪除
builder.setAutoCancel(false);
//禁止滑動刪除
builder.setOngoing(true);
//取消右上角的時間顯示
builder.setShowWhen(false);
builder.setContentTitle("下載中..."+progress+"%");
builder.setProgress(100,progress,false);
//builder.setContentInfo(progress+"%");
builder.setOngoing(true);
builder.setShowWhen(false);
Intent intent = new Intent(this,DownloadService.class);
intent.putExtra("command",1);
Notification notification = builder.build();
manger.notify(MainActivity.TYPE_Progress,notification);
注意事項
1. setProgress的第三個bool類型的參數表示progressbar的Indeterminate屬性 指是否使用不確定模式
2. 高版本上progressbar的進度值可以在setContentInfo顯示,但是低版本上使用這個屬性會導致progressbar不顯示,setContentText一樣
點擊後展開可顯示大段文字內容的通知
效果圖
點擊前

點擊後

代碼舉例<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwPiZuYnNwOzwvcD4NCjxwcmUgY2xhc3M9"brush:java;">
private void bigTextStyle(){
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setContentTitle("BigTextStyle");
builder.setContentText("BigTextStyle演示示例");
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.notification));
android.support.v4.app.NotificationCompat.BigTextStyle style = new android.support.v4.app.NotificationCompat.BigTextStyle();
style.bigText("這裡是點擊通知後要顯示的正文,可以換行可以顯示很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長");
style.setBigContentTitle("點擊後的標題");
//SummaryText沒什麼用 可以不設置
style.setSummaryText("末尾只一行的文字內容");
builder.setStyle(style);
builder.setAutoCancel(true);
Intent intent = new Intent(this,SettingsActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(this,1,intent,0);
builder.setContentIntent(pIntent);
builder.setDefaults(NotificationCompat.DEFAULT_ALL);
Notification notification = builder.build();
manger.notify(TYPE_BigText,notification);
}
注意事項
1. 使用類Android.support.v4.app.NotificationCompat.BigTextStyle
2. 在低版本系統上只顯示點擊前的普通通知樣式 如4.4可以點擊展開,在4.0系統上就不行
3. 點擊前後的ContentTitle、ContentText可以不一致,bigText內容可以自動換行 好像最多5行的樣子
與bigTextStyle類似,點擊前顯示普通通知樣式,點擊後展開
效果圖 (點擊後)

代碼舉例
public void inBoxStyle(){
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setContentTitle("InboxStyle");
builder.setContentText("InboxStyle演示示例");
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.notification));
android.support.v4.app.NotificationCompat.InboxStyle style = new android.support.v4.app.NotificationCompat.InboxStyle();
style.setBigContentTitle("BigContentTitle")
.addLine("第一行,第一行,第一行,第一行,第一行,第一行,第一行")
.addLine("第二行")
.addLine("第三行")
.addLine("第四行")
.addLine("第五行")
.setSummaryText("SummaryText");
builder.setStyle(style);
builder.setAutoCancel(true);
Intent intent = new Intent(this,SettingsActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(this,1,intent,0);
builder.setContentIntent(pIntent);
builder.setDefaults(NotificationCompat.DEFAULT_ALL);
Notification notification = builder.build();
manger.notify(TYPE_Inbox,notification);
}
注意事項
1. 使用類android.support.v4.app.NotificationCompat.InboxStyle
2. 每行內容過長時並不會自動換行
3. addline可以添加多行 但是多余5行的時候每行高度會有截斷
4. 同BigTextStyle 低版本上系統只能顯示普通樣式
點擊後可以顯示一個大圖的通知
效果圖(點擊後)

代碼舉例
public void bigPictureStyle(){
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setContentTitle("BigPictureStyle");
builder.setContentText("BigPicture演示示例");
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setDefaults(NotificationCompat.DEFAULT_ALL);
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.notification));
android.support.v4.app.NotificationCompat.BigPictureStyle style = new android.support.v4.app.NotificationCompat.BigPictureStyle();
style.setBigContentTitle("BigContentTitle");
style.setSummaryText("SummaryText");
style.bigPicture(BitmapFactory.decodeResource(getResources(),R.drawable.small));
builder.setStyle(style);
builder.setAutoCancel(true);
Intent intent = new Intent(this,ImageActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(this,1,intent,0);
//設置點擊大圖後跳轉
builder.setContentIntent(pIntent);
Notification notification = builder.build();
manger.notify(TYPE_BigPicture,notification);
}
1. 使用類android.support.v4.app.NotificationCompat.BigPictureStyle
2. style.bigPicture傳遞的是個bitmap對象 所以也不應該傳過大的圖 否則會oom
3. 同BigTextStyle 低版本上系統只能顯示普通樣式
類似於手機QQ消息的通知,不顯示在通知欄而是以橫幅的模式顯示在其他應用上方
效果圖

代碼示例
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setContentTitle("橫幅通知");
builder.setContentText("請在設置通知管理中開啟消息橫幅提醒權限");
builder.setDefaults(NotificationCompat.DEFAULT_ALL);
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.notification));
Intent intent = new Intent(this,ImageActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(this,1,intent,0);
builder.setContentIntent(pIntent);
//這句是重點
builder.setFullScreenIntent(pIntent,true);
builder.setAutoCancel(true);
Notification notification = builder.build();
manger.notify(TYPE_Hangup,notification);
注意事項
1. 此種效果只在5.0以上系統中有效
2. mainfest中需要添加
3. 可能還需要在設置開啟橫幅通知權限(在設置通知管理中)
4. 在部分改版rom上可能會直接彈出應用而不是顯示橫幅
主要是用來關聯音頻播放服務的,點擊後不會自動消失,通知欄的清空也不可用
效果圖
點擊前

點擊展開後

在4.0系統上的效果 不能展開但是可以最多顯示3個按鈕外加一個CancelButton

代碼示例
private void mediaStyle(){
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setContentTitle("MediaStyle");
builder.setContentText("Song Title");
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.notification));
builder.setDefaults(NotificationCompat.DEFAULT_ALL);
Intent intent = new Intent(this,ImageActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(this,1,intent,0);
builder.setContentIntent(pIntent);
//第一個參數是圖標資源id 第二個是圖標顯示的名稱,第三個圖標點擊要啟動的PendingIntent
builder.addAction(R.drawable.ic_previous_white,"",null);
builder.addAction(R.drawable.ic_stop_white,"",null);
builder.addAction(R.drawable.ic_play_arrow_white_18dp,"",pIntent);
builder.addAction(R.drawable.ic_next_white,"",null);
NotificationCompat.MediaStyle style = new NotificationCompat.MediaStyle();
style.setMediaSession(new MediaSessionCompat(this,"MediaSession",
new ComponentName(MainActivity.this,Intent.ACTION_MEDIA_BUTTON),null).getSessionToken());
//CancelButton在5.0以下的機器有效
style.setCancelButtonIntent(pIntent);
style.setShowCancelButton(true);
//設置要現實在通知右方的圖標 最多三個
style.setShowActionsInCompactView(2,3);
builder.setStyle(style);
builder.setShowWhen(false);
Notification notification = builder.build();
manger.notify(TYPE_Media,notification);
}
注意事項
1. 使用類v7包下的NotificationCompat.MediaStyle
2. addAction方法並普通樣式也可以用,使用後普通通知可以點擊展開,展開部分會顯示一排添加的圖標,並且可以給每個圖標設置不同的點擊事件
3. 最多可以添加5哥action 並排顯示在點擊展開的部分
4. setShowActionsInCompactView的參數是添加的action在所有action組成的數組中的下標,從0開始
5. setShowActionsInCompactView設置的action會顯示在點擊前的通知的右側,低版本上也可以顯示
6. setShowCancelButton(true)會在通知的右上部分顯示一個刪除圖標 5.0以下有效
其實就是設置一個romateViews
演示效果

代碼示例
//command是自定義用來區分各種點擊事件的
private void sendCustomerNotification(int command){
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setContentTitle("Notification");
builder.setContentText("自定義通知欄示例");
builder.setSmallIcon(R.mipmap.ic_launcher);
//builder.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.push));
builder.setAutoCancel(false);
builder.setOngoing(true);
builder.setShowWhen(false);
RemoteViews remoteViews = new RemoteViews(getPackageName(),R.layout.notification_template_customer);
remoteViews.setTextViewText(R.id.title,"Notification");
remoteViews.setTextViewText(R.id.text,"song"+index);
if(command==CommandNext){
remoteViews.setImageViewResource(R.id.btn1,R.drawable.ic_pause_white);
}else if(command==CommandPlay){
if(playerStatus==StatusStop){
remoteViews.setImageViewResource(R.id.btn1,R.drawable.ic_pause_white);
}else{
remoteViews.setImageViewResource(R.id.btn1,R.drawable.ic_play_arrow_white_18dp);
}
}
Intent Intent1 = new Intent(this,MediaService.class);
Intent1.putExtra("command",CommandPlay);
//getService(Context context, int requestCode, @NonNull Intent intent, @Flags int flags)
//不同控件的requestCode需要區分開 getActivity broadcoast同理
PendingIntent PIntent1 = PendingIntent.getService(this,5,Intent1,0);
remoteViews.setOnClickPendingIntent(R.id.btn1,PIntent1);
Intent Intent2 = new Intent(this,MediaService.class);
Intent2.putExtra("command",CommandNext);
PendingIntent PIntent2 = PendingIntent.getService(this,6,Intent2,0);
remoteViews.setOnClickPendingIntent(R.id.btn2,PIntent2);
Intent Intent3 = new Intent(this,MediaService.class);
Intent3.putExtra("command",CommandClose);
PendingIntent PIntent3 = PendingIntent.getService(this,7,Intent3,0);
remoteViews.setOnClickPendingIntent(R.id.btn3,PIntent3);
builder.setContent(remoteViews);
Notification notification = builder.build();
manger.notify(MainActivity.TYPE_Customer,notification);
}
布局文件
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/status_bar_latest_event_content" android:layout_width="match_parent" android:layout_height="64dp" android:gravity="center_vertical" android:orientation="horizontal">
<imageview android:id="@+id/icon" android:layout_width="64dp" android:layout_height="50dp" android:scaletype="fitCenter" android:src="@drawable/push">
<linearlayout android:orientation="vertical" android:paddingright="8dp" android:paddingend="8dp" android:paddingtop="2dp" android:paddingbottom="2dp" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content">
<textview android:id="@+id/title" android:textappearance="@style/TextAppearance.StatusBar.EventContent.Title" android:layout_width="fill_parent" android:layout_height="wrap_content" android:singleline="true" android:layout_marginleft="2dp" android:layout_marginstart="2dp" android:paddingtop="6dp" android:paddingbottom="6dp" android:ellipsize="marquee" android:fadingedge="horizontal" android:layout_weight="1" android:text="Title">
<textview android:id="@+id/text" android:textappearance="@style/TextAppearance.StatusBar.EventContent" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginleft="2dp" android:layout_marginstart="2dp" android:singleline="true" android:text="Content" android:ellipsize="marquee" android:fadingedge="horizontal">
</textview></textview></linearlayout>
<linearlayout android:id="@+id/media_actions" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="center_vertical|end" android:orientation="horizontal" android:layoutdirection="ltr">
<imagebutton style="?android:attr/borderlessButtonStyle" android:id="@+id/btn1" android:layout_width="48dp" android:layout_height="match_parent" android:layout_marginleft="2dp" android:layout_marginright="2dp" android:layout_weight="1" android:src="@drawable/ic_play_arrow_white_18dp" android:gravity="center">
<imagebutton style="?android:attr/borderlessButtonStyle" android:id="@+id/btn2" android:layout_width="48dp" android:layout_height="match_parent" android:layout_marginleft="2dp" android:layout_marginright="2dp" android:layout_weight="1" android:src="@drawable/ic_next_white" android:gravity="center">
<imagebutton style="?android:attr/borderlessButtonStyle" android:id="@+id/btn3" android:layout_width="48dp" android:layout_height="match_parent" android:layout_marginleft="2dp" android:layout_marginright="2dp" android:layout_weight="1" android:src="@drawable/abc_ic_clear_mtrl_alpha" android:gravity="center">
</imagebutton></imagebutton></imagebutton></linearlayout>
<imageview android:id="@+id/end_padder" android:layout_width="6dp" android:layout_height="match_parent">
</imageview></imageview></linearlayout>
1. 不同控件 PendingIntent.getXXX的requestCode不能相同
2. RemoteViews的具體用法請自行百度 這裡就不展開說明了
3. 自定義布局的高需要是64dp 沒有為什麼 官方給的
4. 需要更改通知欄布局的時候 其實就是以同一個NotifyId發個新的通知 替換掉老的
5. LargeIcon可以不設置,但是smallIcon和title需要設置,不然通知不能顯示
6. LargeIcon如果設置了並且自定義布局內相同位置還有一個icon的畫在低版本系統上可能會都顯示,高版本不會顯示LargeIcon
有人想要仿 QQ 音樂的樣式,其實代碼很簡單和自定義的差不多。
點擊或下拉後展示效果圖

代碼示例
if(Build.VERSION.SDK_INT>=16){
Notification notification = new Notification();
notification.icon = R.mipmap.ic_launcher;
notification.tickerText = "BigContent";
notification.contentView = new RemoteViews(getPackageName(), R.layout.notification_template_customer);
RemoteViews expandedView = new RemoteViews(getPackageName(), R.layout.notification_big_content);
//contentView和expandedView的 pendingIntent 我就不寫了 和自定義的一樣的
notification.bigContentView = expandedView;
manger.notify(10,notification);
}else{
Toast.makeText(MainActivity.this, "系統版本過低,不支持此種樣式!", Toast.LENGTH_SHORT).show();
}
R.layout.notification_big_content的布局文件也很簡單就不上代碼了
需要注意的是
bigContentView是 api16以上才支持的,所以4.1以下還是沒有效果的
另外bigContentView布局的高度需要是100dp。
Android 語言切換實現(就是這麼簡單)
近期因為項目需要,點擊系統設置-》語言和輸入法-》選擇語言-》應用內語言跟著切換的實現,廢話不多說,直接接入主題以我的為例:我的需求是實現簡體中文,和繁體字的切換1.你需
Android UI系列-----ScrollView和HorizontalScrollView
本篇隨筆將講解一下Android當中比較常用的兩個布局容器--ScrollView和HorizontalScrollView,從字面意義上來看也是非常的簡單的,Scrol
Android 自定義View (一)
笑對人生,能穿透迷霧;笑對人生,能堅持到底;笑對人生,能化解危機;笑對人生,能照亮黑暗。 本講內容:自定義View(可以在布局文件多次用) 一、步驟:
Android開發系列(十一):對手機通訊錄的讀取、添加、刪除、查找
一、通訊錄介紹 通訊錄是Android手機自帶的一個應用,它是一個ContentProvider應用,其它應用可以對通訊錄進行訪問,進行對聯系人的CRUD操作。 二、