前言:
动态效果图就不展示了,因为我的安卓模拟器是Android3.几的,在模拟器上跑不了,索性就上张图片,知道是要实现什么效果就行了。
代码如下,注释都已经在代码中给出,可以直接拿起来就用。
public class MainActivity extends AppCompatActivity { //定义notification实用的ID private static final String MESSAGES_CHANNEL = "messages"; private NotificationManager notificationManager; private Context context; private static final String TAG = "MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void show(View view) { createMessageNotificationChannel(); final int NEW_MESSAGE_ID = 0; NotificationCompat.Builder builder = new NotificationCompat.Builder(this, MESSAGES_CHANNEL); String title = "正在下载"; String text = "我正在下载Android相关资料"; Intent intent = new Intent(); PendingIntent pendingIntent = null; intent.setClass(MainActivity.this, BrodeCaste.class); pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); builder.setSmallIcon(R.drawable.ic_launcher_background) // //小图标 .setContentTitle(title) //通知标题 .setContentText(text) //描述性文本 .setContentIntent(pendingIntent) //点击通知栏跳转到指定页面 .setAutoCancel(true) //点击通知后关闭通知 .setOnlyAlertOnce(true); //设置提示音只响一次 //通知栏进度条 new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < 100; i++) { builder.setProgress(100, i, false); builder.setContentText("下载" + i + "%"); notificationManager.notify(NEW_MESSAGE_ID, builder.build()); } //模拟网络加载 try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } builder.setContentText("下载完成"); notificationManager.notify(NEW_MESSAGE_ID, builder.build()); } }).start(); } //在Android8.0之后必须创建通知渠道 private void createMessageNotificationChannel() { //Build.VERSION.SDK_INT 代表操作系统的版本号 //Build.VERSION_CODES.O 版本号为26 对应的Android8.0版本 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { CharSequence name = this.getString(R.string.app_name); NotificationChannel channel = new NotificationChannel( MESSAGES_CHANNEL, name, NotificationManager.IMPORTANCE_HIGH ); notificationManager = this.getSystemService(NotificationManager.class); notificationManager.createNotificationChannel(channel); } } }
上面是通过模拟网络加载去实现进度条的更新,在实际开发中肯定不会这样做,下面以下载文件为例,通过网络加载,显示进度条效果。
//设置进度条操作 URL url = new URL(fileurl); 打开和URL之间的连接 connection = (HttpURLConnection) url.openConnection(); //设置网络请求为get请求 connection.setRequestMethod("GET"); //开始读取服务器端数据,到了指定时间还没有读到数据,则报超时异常 connection.setReadTimeout(50000); //建立实际的连接 connection.connect(); new Thread(new Runnable() { @Override public void run() { int total_length = 0; try { if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) { InputStream is = connection.getInputStream(); //获取文件流大小,更新进度 byte[] buffer = new byte[1024]; int len; int pro1 = 0; long file_length = connection.getContentLength(); while ((len = is.read(buffer)) != -1) { total_length += len; if (file_length > 0) { pro1 = (int) ((total_length / (float) file_length) * 100);//进度条传递进度 builder.setProgress(100, pro1, false); builder.setContentText("下载" + pro1 + "%"); notificationManager.notify(NEW_MESSAGE_ID, builder.build()); } } builder.setStyle(new NotificationCompat.BigTextStyle().bigText("下载完成,点击查看")); //显示多行文本 notificationManager.notify(NEW_MESSAGE_ID, builder.build()); //关闭资源 is.close(); } } catch (IOException e) { e.printStackTrace(); } } }).start();
这个是在主线程中操作的,但是我们都知道在主线程中进行网络请求,会阻塞后面代码的执行,当然也会影响主界面UI显示,造成进度条显示卡顿,不能切换页面的操作。
当然并不是说就没有办法在主线程中执行网络操作了,我们可以用StrictMode类去修改默认的策略。
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy);
加入这行代码即可,这样进度条就会根据文件大小去进行快与慢的显示,达到了一个很好的用户体验效果,当然这个进度条只是显示给用户看的其实没有什么实际的意义,就只是单单的一个显示效果而已,但这也是不可或缺的。
分析:
URL (UniformResource Locator)对象代表统一资源定位器,它是指向互联网“资源”的指针。资源可以是简单的文件或目录,也可以是对更复杂的对象的引用。
connection.getResponseCode():http状态返回代码
HttpURLConnection.HTTP_OK:状态代码200 服务器已成功处理了请求