您的位置:首页 > 移动开发 > Android开发

关于做Notification的一些经验

2017-08-14 14:41 120 查看
需求是这样的:一个显示应用下载器状态的通知栏,能显示下载进度,下载速度,任务数量等等信息。

1. 常驻通知栏

其实出来这个需求是因为下载器需要一个Service作为承载,特别是当应用切换到后台时,没有一个前台Service在跑的话,很容易被系统回收掉。一开始年少无知,不知道为啥应用宝,豌豆荚等等应用商店的下载都要启动一个常驻的通知栏,后来才发现这样才能将Service保持在前台运行。

常驻通知栏需要设置如下几个属性:

mNotificationBuilder = new NotificationCompat.Builder(this.getApplication());
mNotificationBuilder.setAutoCancel(false); //点击不消失
mNotificationBuilder.setOngoing(true); // 不能滑动清除


并且在改变通知栏信息的时候用

this.startForeground(NOTIFACTION_ID, mNotificationBuilder.build());


而不是

mNotificationManager.notify(NOTIFACTION_ID, mNotificationBuilder.build());


startForeground是service的一个方法,能将service声明为前台service防止被清除

2.控制Service的生命周期

在使用过程中发现直接通过显示的发送startService和stopService并不能准确的控制service的生命周期,特别是有可能连续的调用stopService和startService导致start和stop不能顺序执行,经常导致停止没法正常调用,因此通过在service内部建立静态公开方法来控制,代码如下:

public static void stopService(Context context) {
Intent intent = new Intent(context, DownloadService.class);

intent.putExtra(IntentKey.DOWNLOAD_NOTIFICATION_IS_BORN, false);

try {

context.startService(intent);

} catch (Exception e) {

}

}

public static void startService(Context context, String taskId) {

Intent intent = new Intent(context, DownloadService.class);

intent.putExtra(IntentKey.DOWNLOAD_NOTIFICATION_IS_BORN, true);

try {

context.startService(intent);

} catch (Exception e) {

}

}


然后在Service的onStartCommand中进行判断

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null) {
boolean isBorn;
try {
isBorn =intent.getBooleanExtra(IntentKey.DOWNLOAD_NOTIFICATION_IS_BORN, true);
} catch (RuntimeException e) {
e.printStackTrace();
isBorn = false;
}
if (!isBorn) {
LogTool.i(TAG, "stopService");
stopForeground(true);
try {
stopSelf();
} catch (Exception e) {
LogTool.w(TAG, e);
}
mNotificationManager.cancel(NOTIFACTION_ID);
} else {
LogTool.i(TAG, "startService");
initNotification();
}
}
return START_NOT_STICKY;
}


实践证明,这样的控制方法比较靠谱

3.定义通知栏样式

由于谷歌提供的几种基本样式不能满足需求,只能通过RemoteView来自定义通知栏,代码如下:

mRemoteView = new RemoteViews(this.getPackageName(), R.layout.custom_notification);

mNotificationBuilder.setContent(mRemoteView);


要注意,对于RemoteView只能通过其提供的特定方法来改变界面布局。

4.自定义图标的一些坑

一开始直接使用应用图标作为常驻通知栏的小图标,发现会在大部分的机子出现弹出Ticker的时候图标异常的大,甚至在5.0以上的机子上出现一篇白色的情况,查阅文档发现谷歌建议在5.0以上的通知栏常驻图标采用纯白和全透明两种颜色来设计图标,以期达到统一的视觉效果,当然,如果不想折腾,可以直接将编译的版本设置成target 22一下就可以了。

坑当然不止这些,让设计弄了一套白色的和透明的通知栏图标之后,发现在展示ticker的时候仍然会出现异常大的图标,应该是尺寸不适合的原因,看来不能和应用图标一样的规格。Google发现一个网站,可以自动生成一套通知栏图标,地址如下:

生成一套通知栏图标的网站

可以发现为了兼容3.0以下会有两套图标生成,一套是透明底,白色图,一套是透明底,灰色图。具体效果可以自己试验,不过注意,原图必须要符合官方的设计,即只能有两种颜色,白色和透明色。

5.总结

Notification还有一些比较高级的方法没有研究,但是上面所有的已经可以满足需求,以后有什么新的需求再去继续研究吧。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android