Android 实现通知栏和进度条效果(适用于Android8.0以上)

Posted 路 宇

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 实现通知栏和进度条效果(适用于Android8.0以上)相关的知识,希望对你有一定的参考价值。

前言:

动态效果图就不展示了,因为我的安卓模拟器是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 服务器已成功处理了请求

以上是关于Android 实现通知栏和进度条效果(适用于Android8.0以上)的主要内容,如果未能解决你的问题,请参考以下文章

android 实现Service上传并在通知栏显示进度条

androidprogressbar横向进度条动画效果

如何使用 C# HttpClient PostAsync 显示上传进度

CSS实现不规则自定义进度条效果

我的Android进阶之旅------>Android自定义View实现带数字的进度条(NumberProgressBar)

自定义进度条Android,kotlin