我是靠谱客的博主 烂漫悟空,这篇文章主要介绍Notification下拉通知1.先看BaseNoticeActivity类MainActivity是继承这个类的2.BaseTools 两个方法获取APP的版本和SDK的版本3.MainActivity,现在分享给大家,希望可以做个参考。
昨天弄手机,突然看到通知栏。看这东西这么简单的效果,心想应该能搞定,然后就拍起来了。
本以为这个下拉通知左边的图片是就有这方法,谁知道还得自己自定义的,累人了。
如有问题请指正。
看了看API 找到一套源码,然后就按着顺序写起来了。实在不记得哪位前辈的成果了,就不打签了,如侵权联系本人。
看一下目录:
第一个ActionNameActivity类没什么意义就是点击弹出的通知进入这个Activity.
不算太麻烦。
1.先看BaseNoticeActivity类MainActivity是继承这个类的
类主要是进行注册系统服务和删除通知栏和兼容适配的。
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47package com.example.hejingzhou.notifications; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; /** * Created by Hejingzhou on 2016/3/13. */ public class BaseNoticeActivity extends AppCompatActivity{ public NotificationManager notificationManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); InitService(); } private void InitService() { notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); } /** * 清除这个编号的通知栏 * @param noticeNumber */ public void clearThisNotice(int noticeNumber){ notificationManager.cancel(noticeNumber); } /** * 清除所有的通知 */ public void clearAllNotice(){ notificationManager.cancelAll(); } /** * @获取默认的pendingIntent,为了防止2.3及以下版本报错 没有理解为什么这样做 就能防止报错 * @flags属性: * 在顶部常驻:Notification.FLAG_ONGOING_EVENT * 点击去除: Notification.FLAG_AUTO_CANCEL */ public PendingIntent getDefalutIntent(int flag){ PendingIntent pendingIntent = PendingIntent.getActivities(this,1, new Intent[]{new Intent()},flag); return pendingIntent; } } <span style="color:#ff0000;"> </span>
2.BaseTools 两个方法获取APP的版本和SDK的版本
这两个方法在Android开发中挺重要的。
我们在这个程序中要的是SDK版本,而软件的版本号没什么用 ,SDK版本小于等于9可能造成错误,需要避免这个问题。
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32package com.example.hejingzhou.notifications; import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.os.Build; import android.util.Log; /** * Created by Hejingzhou on 2016/3/15. */ public class BaseTools { /** * 获得App版本 * @param context * @return * @throws Exception */ public static String getAppVersion(Context context) throws Exception{ PackageManager packageManager = context.getPackageManager(); PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(),0); String versionName = packageInfo.versionName; return versionName; } /** * 获取当前系统SDK版本号 * @return */ public static int getSystemVersion(){ int version = Build.VERSION.SDK_INT; return version; } }
3.MainActivity
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381package com.example.hejingzhou.notifications; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.support.v4.app.NotificationCompat; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.RemoteViews; import android.widget.Toast; import java.io.File; /** * 首先明白 Intent 与 PendingIntent的大概区别: * intent英文意思是意图,pending表示即将发生或来临的事情。 * PendingIntent这个类用于处理即将发生的事情。 */ public class MainActivity extends BaseNoticeActivity implements View.OnClickListener { private String TAG = getClass().getSimpleName(); NotificationCompat.Builder mNotiBuilder;//通知构造器类 private int noticeID01 = 01; private int noticeID02 = 02; private int noticeID03 = 03; private int noticeID04 = 04; private int noticeID05 = 05; private int noticeID06 = 06; public boolean isPaly = false; public ButtonBroadcastReceiver broadcastReceiver; //通知栏上的Button按下后会发出intent消息 这是接收消息的类继承接收类 public final static String ACTION_BUTTON = "ButtonActionFlag"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(); initNotice(); initButtonReceiver(); /** * 获取的当前的APP版本好并没有什么用,只是在软件升级的时候用的到 * 这里的获取SDK的版本号 是因为自定义的通知须在SDK3.0的版本上支持,低于3.0不响应 */ BaseTools baseTools = new BaseTools(); try { String appversion = baseTools.getAppVersion(getApplicationContext()); Log.i(TAG,"当前的App版本号"+appversion); int SystemVersion = baseTools.getSystemVersion(); Log.i(TAG,"当前的SDK版本号是"+SystemVersion); } catch (Exception e) { e.printStackTrace(); } } private void initButtonReceiver() { broadcastReceiver = new ButtonBroadcastReceiver(); IntentFilter intentFilter = new IntentFilter();//意向结构化描述要匹配的值 intentFilter.addAction(ACTION_BUTTON); registerReceiver(broadcastReceiver, intentFilter);//注册 } /** * 初始化通知栏 */ private void initNotice() { mNotiBuilder = new NotificationCompat.Builder(this); mNotiBuilder.setContentIntent(getDefalutIntent(Notification.FLAG_ONGOING_EVENT)); mNotiBuilder.setContentIntent(getDefalutIntent(Notification.FLAG_ONGOING_EVENT)).//防止2.3一下报错?? setContentTitle("Test Title") .setContentText("Test Content") /**setContentIntent提供一个当单击通知时,发送 * *FLAG_AUTO_CANCEL 该通知能被状态栏的清除按钮给清除掉 *FLAG_NO_CLEAR 该通知能被状态栏的清除按钮给清除掉 *FLAG_ONGOING_EVENT 通知放置在正在运行 */ .setTicker("通知来了") .setWhen(System.currentTimeMillis())//通知的时间一般为系统时间 .setPriority(Notification.PRIORITY_DEFAULT)//设置优先显示级别 范围 【-2 , 2】 .setOngoing(false)//设置这是否是一个持续的通知//如果设置为false 可以通过通知栏侧滑删除,true则不能 .setDefaults(Notification.DEFAULT_VIBRATE)//设置通知默认要使用的选项 .setNumber(100)//Show出一个数,也不知道使用它有啥用 .setSmallIcon(R.drawable.feiji);//只是在setTicker弹出的提示的时候是这个图标 } private void findViewById() { Button btnBasicNotice = (Button) findViewById(R.id.buttonBasicNotice); btnBasicNotice.setOnClickListener(this); Button btnBigNotice = (Button)findViewById(R.id.buttonBigNotice); btnBigNotice.setOnClickListener(this); Button btnPermanent = (Button)findViewById(R.id.buttonPermanent); btnPermanent.setOnClickListener(this); Button btnClearNotice = (Button)findViewById(R.id.buttonClearNotice); btnClearNotice.setOnClickListener(this); Button btnActionActivity = (Button)findViewById(R.id.buttonActionActivity); btnActionActivity.setOnClickListener(this); Button btnClearAllNotice = (Button)findViewById(R.id.buttonClearAllNotice); btnClearAllNotice.setOnClickListener(this); Button btnInstallApp = (Button)findViewById(R.id.buttonInstallApp); btnInstallApp.setOnClickListener(this); Button btnUserDefine = (Button)findViewById(R.id.buttonUserDefine); btnUserDefine.setOnClickListener(this); Button btnUserDefineButton = (Button)findViewById(R.id.buttonUserDefineButton); btnUserDefineButton.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.buttonBasicNotice: Log.i(TAG,"Click The Basic Notice"); showBasicNotice(); break; case R.id.buttonBigNotice: showBigNotice(); break; case R.id.buttonPermanent: showPermanent(); break; case R.id.buttonClearNotice: clearThisNotice(noticeID03); break; case R.id.buttonActionActivity: ActionNewActivity(); break; case R.id.buttonClearAllNotice: clearAllNotice(); break; case R.id.buttonInstallApp: InstallApp(); break; case R.id.buttonUserDefine://自定义 UserDefineNotice(); break; case R.id.buttonUserDefineButton://自定义带Button UserDefineButtonNotice(); break; default: break; } } /** * 用户定义的通知 */ private void UserDefineNotice() { RemoteViews view_notice = new RemoteViews(getPackageName(),R.layout.view_notice);//自定义布局 view_notice.setImageViewResource(R.id.custom_icon, R.drawable.jian); view_notice.setTextViewText(R.id.tv_custom_title, "今日特价"); view_notice.setTextViewText(R.id.tv_custom_content,"白菜价 ----白菜价 --- 今日只卖白菜"); mNotiBuilder = new NotificationCompat.Builder(this); mNotiBuilder.setContent(view_notice) .setPriority(Notification.PRIORITY_DEFAULT) .setTicker("今日特价") .setContentIntent(getDefalutIntent(Notification.FLAG_AUTO_CANCEL))//因为运行时已经初始化了,可以以没有 .setWhen(System.currentTimeMillis()) .setOngoing(false) .setSmallIcon(R.drawable.qian); Notification notification = mNotiBuilder.build(); notification.contentView = view_notice; notificationManager.notify(noticeID05, notification); } /** * 安装APP */ private void InstallApp() { mNotiBuilder.setAutoCancel(true)//点击后消失 .setContentTitle("Download Over") .setContentText("Click Install the App") .setTicker("Download Over"); Intent apkIntent = new Intent(); apkIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); apkIntent.setAction(android.content.Intent.ACTION_VIEW); String appPath = "./mnt/sdcard/ProMonkey_2.0.apk"; Uri uri = Uri.fromFile(new File(appPath)); Log.i(TAG,""+uri); apkIntent.setDataAndType(uri,"application/vnd.android.package-archive"); //这个类型不懂动的上 http://zengyan2012.iteye.com/blog/1646492 进行理解 就是定义好的文件类型定值 PendingIntent contextIntent = PendingIntent.getActivity(this,0,apkIntent,0); //getActivity参数类型 context, requestCode, intent, flags, null mNotiBuilder.setContentIntent(contextIntent); notificationManager.notify(noticeID06, mNotiBuilder.build()); Toast.makeText(MainActivity.this,"运行了到这里了",Toast.LENGTH_SHORT).show(); } /** * 跳转到新的Activity */ private void ActionNewActivity() { mNotiBuilder.setAutoCancel(true)//点击后通条消失 .setContentTitle("ActionNewActivity") .setContentText("This is a ActionNewActivity") .setTicker("ActionNewActivity Come on...") .setSmallIcon(R.drawable.action); Intent actionIntent = new Intent(this,ActionNewActivity.class); actionIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); PendingIntent pendingIntent = PendingIntent.getActivity(this,0,actionIntent,PendingIntent.FLAG_UPDATE_CURRENT); /** * PendingIntent.FLAG_UPDATE_CURRENT 一个标志符 标志操作是否完成 */ mNotiBuilder.setContentIntent(pendingIntent); notificationManager.notify(noticeID04,mNotiBuilder.build()); } /** * 常驻栏 */ private void showPermanent() { NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, getIntent(), 0); /** *public static PendingIntent getActivity(Context context, int requestCode, Intent intent, @Flags int flags) { return getActivity(context, requestCode, intent, flags, null); } */ mBuilder.setSmallIcon(R.drawable.ren) .setTicker("Permanent Notice ...") .setContentTitle("常住栏,无法右划取消") .setContentText("This is a Permanent Notice") .setContentIntent(pendingIntent);//setContentIntent:提供一个供通知栏单击时响应PendingIntent Notification mNotification = mBuilder.build(); mNotification.iconLevel = R.drawable.ren;//设置图标 mNotification.flags = Notification.FLAG_ONGOING_EVENT; mNotification.defaults = Notification.DEFAULT_VIBRATE; mNotification.tickerText = "Notice Come in..."; mNotification.when = System.currentTimeMillis(); notificationManager.notify(noticeID03,mNotification); } /** * 创建一个大的通知栏 没看出效果没什么不同 */ private void showBigNotice() { NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle(); String[] events = new String[6]; inboxStyle.setBigContentTitle("Big Notice:"); for(int i=0;i<events.length;i++){ inboxStyle.addLine(events[i]); } mNotiBuilder.setContentTitle("Big Notice") .setContentText("This a Big Notice") .setSmallIcon(R.drawable.feiji) .setTicker("Big Notice Come in..."); notificationManager.notify(noticeID02,mNotiBuilder.build()); } /** * 创建一个基本的通知 */ private void showBasicNotice() { mNotiBuilder.setContentTitle("Basic"); mNotiBuilder.setContentText("This is a Basic Notice!!!"); mNotiBuilder.setTicker("Basic Notice Come in");//首次出现上升滚动 //mNotiBuilder.setColor(red); mNotiBuilder.setSmallIcon(R.drawable.xiao); notificationManager.notify(noticeID01, mNotiBuilder.build()); } public final static String INITENT_BUTTONID_TAG = "ButtonId"; public final static int BUTTON_PREV_ID = 1; public final static int BUTTON_PLAY_ID = 2; public final static int BUTTON_NEXT_ID = 3; /** * 创建的负责接收Intent传过来的信息内部类 */ private class ButtonBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); //public final static String ACTION_BUTTON = "com.notifications.intent.action.ButtonClick"; if(action.equals(ACTION_BUTTON)){ //public final static String INITENT_BUTTONID_TAG = "ButtonId"; int buttonId = intent.getIntExtra(INITENT_BUTTONID_TAG,0); switch (buttonId){ case BUTTON_PREV_ID: Log.i(TAG, "按下的上一首"); Toast.makeText(getApplicationContext(),"点击了上一首",Toast.LENGTH_SHORT); break; case BUTTON_PLAY_ID: Log.i(TAG,"点击了播放"); String play_status = ""; isPaly = !isPaly; if(isPaly){ play_status = "开始播放"; }else play_status = "已暂停"; UserDefineButtonNotice(); Log.i(TAG, play_status); Toast.makeText(getApplicationContext(),play_status,Toast.LENGTH_SHORT).show(); break; case BUTTON_NEXT_ID: Log.i(TAG, "下一首"); Toast.makeText(getApplicationContext(),"下一首",Toast.LENGTH_SHORT).show(); break; default: break; } } } } /** * 用户自定义的带Button */ private void UserDefineButtonNotice() { NotificationCompat.Builder mbBuilder = new NotificationCompat.Builder(this);//构建 RemoteViews mRemoteViews = new RemoteViews(getPackageName(),R.layout.view_notice_button); mRemoteViews.setImageViewResource(R.id.custom_song_icon, R.drawable.yinyue); mRemoteViews.setTextViewText(R.id.tv_custom_song_singer,"田嘱"); mRemoteViews.setTextViewText(R.id.tv_custom_song_name,"采蘑菇的小姑娘"); if(BaseTools.getSystemVersion() <= 9){ mRemoteViews.setViewVisibility(R.id.ll_custom_button, View.GONE); }else { mRemoteViews.setViewVisibility(R.id.ll_custom_button, View.VISIBLE); if (isPaly) { mRemoteViews.setImageViewResource(R.id.btn_custom_play, R.drawable.btn_pause); } else mRemoteViews.setImageViewResource(R.id.btn_custom_play, R.drawable.btn_play); } //点击事件处理 Intent buttonIntent = new Intent(ACTION_BUTTON); /** * public final static String INITENT_BUTTONID_TAG = "ButtonId"; * public final static int BUTTON_PREV_ID = 1; * */ //上一首 发送消息 buttonIntent.putExtra(INITENT_BUTTONID_TAG,BUTTON_PREV_ID);//传递消息 PendingIntent intent_prev = PendingIntent.getBroadcast(this,1,buttonIntent,PendingIntent.FLAG_UPDATE_CURRENT); mRemoteViews.setOnClickPendingIntent(R.id.btn_custom_prev, intent_prev); /**getBroadcast(Context context, int requestCode,Intent intent, @Flags int flags) * getBroadcast返回现有连接或新处理意图匹配给定参数 * * setOnClickPendingIntent(int viewId, PendingIntent pendingIntent) { * addAction(new SetOnClickPendingIntent(viewId, pendingIntent)); * 指定键位,与发送内容 */ //播放暂停 发送消息 buttonIntent.putExtra(INITENT_BUTTONID_TAG,BUTTON_PLAY_ID); PendingIntent intent_play = PendingIntent.getBroadcast(this,2,buttonIntent,PendingIntent.FLAG_UPDATE_CURRENT); mRemoteViews.setOnClickPendingIntent(R.id.btn_custom_play, intent_play); //下一首消息 buttonIntent.putExtra(INITENT_BUTTONID_TAG, BUTTON_NEXT_ID); PendingIntent intent_next = PendingIntent.getBroadcast(this, 3, buttonIntent, PendingIntent.FLAG_UPDATE_CURRENT); mRemoteViews.setOnClickPendingIntent(R.id.btn_custom_next, intent_next); mbBuilder.setContent(mRemoteViews) .setContentIntent(getDefalutIntent(Notification.FLAG_ONGOING_EVENT))防止2.3一下报错???! .setTicker("playing ...") .setPriority(Notification.PRIORITY_DEFAULT) .setOngoing(true) .setSmallIcon(R.drawable.yinyue); Notification notification = mbBuilder.build();//Notification代表着一个持久提交通知 notification.flags = Notification.FLAG_ONGOING_EVENT; notificationManager.notify(200,notification); /** * void notify(int id, Notification notification) * 发布一个通知在状态栏显示。如果一个通知,已经发布的应用程序相同的id和尚未被取消,它将取而代之的是更新的信息。 * @param id An identifier for this notification unique within your * application. * @param notification A {@link Notification} object describing what to show the user. Must not * be null. */ } @Override protected void onDestroy() { if(broadcastReceiver != null){ unregisterReceiver(broadcastReceiver); } super.onDestroy(); } }
Ps:在启动应用程序的时候我的SD卡存放的程序。路径为我的SD卡。所以APK文件路径还是需要符合您的路径。
访问SD卡是需要添加SD卡的权限,这个不要忘了。
关于这个具体路径按照 Android Device Monitor 里进行寻找,如果是在Sd卡中的话,就是在mnt/sdcard/里面。
比如我的文件是在内存卡的根目录,那么我的路劲格式为
./mnt/sdcard/ProMonkey_2.0.apk
千万不能忘记前面的点
打印Uri解析完的日志为
盗个图 ,类方法挺详细的:来自http://yiibai.com/android/android_notifications.html
运行结果:
源码:
http://download.csdn.net/detail/csdnhejingzhou/9462551
最后
以上就是烂漫悟空最近收集整理的关于Notification下拉通知1.先看BaseNoticeActivity类MainActivity是继承这个类的2.BaseTools 两个方法获取APP的版本和SDK的版本3.MainActivity的全部内容,更多相关Notification下拉通知1.先看BaseNoticeActivity类MainActivity是继承这个类的2.BaseTools内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复