【Android】WorkManager(章二)

剩余的三部分
官方文档在这里插入图片描述

案例

实现下载器,并监听下载进度

界面

在这里插入图片描述

定义Worker

在官方案例的前提下,进行完善
在这里插入图片描述

下载download

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

下载进度

在这里插入图片描述

授予权限

在这里插入图片描述
在这里插入图片描述

开始工作并监听

在这里插入图片描述

完整代码

MainActivity.java

package com.test.downloadworkerapplication;

import static android.content.Context.NOTIFICATION_SERVICE;
import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC;
import static com.test.downloadworkerapplication.MainActivity.MY_LOG_TAG;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.net.Uri;
import android.os.Build;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationCompat;
import androidx.work.Data;
import androidx.work.ForegroundInfo;
import androidx.work.WorkManager;
import androidx.work.Worker;
import androidx.work.WorkerParameters;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

public class DownloadWorker extends Worker {
    public static final String KEY_INPUT_URL = "KEY_INPUT_URL";
    public static final String KEY_OUTPUT_FILE_NAME = "KEY_OUTPUT_FILE_NAME";
    public static final String KEY_FILE_URI = "KEY_FILE_URI";
    public static final String PROGRESS = "PROGRESS";

    private final NotificationManager notificationManager;

    public DownloadWorker(
            @NonNull Context context,
            @NonNull WorkerParameters parameters) {
        super(context, parameters);
        notificationManager = (NotificationManager)
                context.getSystemService(NOTIFICATION_SERVICE);

        Data data = new Data.Builder().putInt(PROGRESS, 0).build();
        setProgressAsync(data);
    }

    @NonNull
    @Override
    public Result doWork() {
        Data inputData = getInputData();
        String inputUrl = inputData.getString(KEY_INPUT_URL);
        String outputFile = inputData.getString(KEY_OUTPUT_FILE_NAME);

        String progress = "Starting Download";
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            setForegroundAsync(createForegroundInfo(progress));
        }
        Uri uri = download(inputUrl, outputFile);

        Data progressData2 = new Data.Builder().putInt(PROGRESS, 100).build();
        setProgressAsync(progressData2);

        Data data = new Data.Builder()
                .putString(KEY_FILE_URI, uri.toString())
                .build();
        return Result.success(data);
    }

    private Uri download(String inputUrl, String outputFile) {
        // Downloads a file and updates bytes read
        // Calls setForegroundAsync(createForegroundInfo(myProgress))
        // periodically when it needs to update the ongoing Notification.
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                String myProgress = "downloading...";
                setForegroundAsync(createForegroundInfo(myProgress));
            }

            long fileSize = FileSizeFetcher.getFileSize(inputUrl);
            URL url = new URL(inputUrl);
            InputStream inputStream = url.openStream();

            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            int downloadLen = 0;
            while ((len = inputStream.read(buffer)) != -1) {
                downloadLen += len;
                byteArrayOutputStream.write(buffer, 0, len);

                /// 下载进度
                double progress = 1.0 * downloadLen / fileSize;
                Data data = new Data.Builder().putDouble(PROGRESS, progress).build();
                setProgressAsync(data);
            }
            byte[] byteArray = byteArrayOutputStream.toByteArray();
            inputStream.close();

            File file = new File(getApplicationContext().getCacheDir(), outputFile + ".pdf");
            FileOutputStream fileOutputStream = new FileOutputStream(file);
            fileOutputStream.write(byteArray);
            fileOutputStream.close();

            String absolutePath = file.getAbsolutePath();
            Log.i(MY_LOG_TAG, absolutePath);
            return Uri.fromFile(file);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.Q)
    @NonNull
    private ForegroundInfo createForegroundInfo(@NonNull String progress) {
        // Build a notification using bytesRead and contentLength
        Context context = getApplicationContext();
        String id = context.getString(R.string.notification_channel_id);
        String title = context.getString(R.string.notification_title);
        String cancel = context.getString(R.string.cancel_download);
        // This PendingIntent can be used to cancel the worker
        PendingIntent intent = WorkManager.getInstance(context)
                .createCancelPendingIntent(getId());

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            createChannel(id);
        }

        Notification notification = new NotificationCompat.Builder(context, id)
                .setContentTitle(title)
                .setTicker(title)
                .setContentText(progress)
                .setSmallIcon(R.drawable.ic_work_notification)
                .setOngoing(true)
                // Add the cancel action to the notification which can
                // be used to cancel the worker
                .addAction(android.R.drawable.ic_delete, cancel, intent)
                .build();

        int notificationId = 1000;
        return new ForegroundInfo(notificationId, notification, FOREGROUND_SERVICE_TYPE_DATA_SYNC);
    }

    @RequiresApi(Build.VERSION_CODES.O)
    private void createChannel(String id) {
        // Create a Notification channel
        NotificationChannel channel = new NotificationChannel(id, "download channel", NotificationManager.IMPORTANCE_NONE);
        notificationManager.createNotificationChannel(channel);
    }
}

DownloadWorker.java

package com.test.downloadworkerapplication;

import static android.content.Context.NOTIFICATION_SERVICE;
import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC;
import static com.test.downloadworkerapplication.MainActivity.MY_LOG_TAG;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.net.Uri;
import android.os.Build;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationCompat;
import androidx.work.Data;
import androidx.work.ForegroundInfo;
import androidx.work.WorkManager;
import androidx.work.Worker;
import androidx.work.WorkerParameters;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

public class DownloadWorker extends Worker {
    public static final String KEY_INPUT_URL = "KEY_INPUT_URL";
    public static final String KEY_OUTPUT_FILE_NAME = "KEY_OUTPUT_FILE_NAME";
    public static final String KEY_FILE_URI = "KEY_FILE_URI";
    public static final String PROGRESS = "PROGRESS";

    private final NotificationManager notificationManager;

    public DownloadWorker(
            @NonNull Context context,
            @NonNull WorkerParameters parameters) {
        super(context, parameters);
        notificationManager = (NotificationManager)
                context.getSystemService(NOTIFICATION_SERVICE);

        Data data = new Data.Builder().putInt(PROGRESS, 0).build();
        setProgressAsync(data);
    }

    @NonNull
    @Override
    public Result doWork() {
        Data inputData = getInputData();
        String inputUrl = inputData.getString(KEY_INPUT_URL);
        String outputFile = inputData.getString(KEY_OUTPUT_FILE_NAME);

        String progress = "Starting Download";
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            setForegroundAsync(createForegroundInfo(progress));
        }
        Uri uri = download(inputUrl, outputFile);

        Data progressData2 = new Data.Builder().putInt(PROGRESS, 100).build();
        setProgressAsync(progressData2);

        Data data = new Data.Builder()
                .putString(KEY_FILE_URI, uri.toString())
                .build();
        return Result.success(data);
    }

    private Uri download(String inputUrl, String outputFile) {
        // Downloads a file and updates bytes read
        // Calls setForegroundAsync(createForegroundInfo(myProgress))
        // periodically when it needs to update the ongoing Notification.
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                String myProgress = "downloading...";
                setForegroundAsync(createForegroundInfo(myProgress));
            }

            long fileSize = FileSizeFetcher.getFileSize(inputUrl);
            URL url = new URL(inputUrl);
            InputStream inputStream = url.openStream();

            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            int downloadLen = 0;
            while ((len = inputStream.read(buffer)) != -1) {
                downloadLen += len;
                byteArrayOutputStream.write(buffer, 0, len);

                /// 下载进度
                double progress = 1.0 * downloadLen / fileSize;
                Data data = new Data.Builder().putDouble(PROGRESS, progress).build();
                setProgressAsync(data);
            }
            byte[] byteArray = byteArrayOutputStream.toByteArray();
            inputStream.close();

            File file = new File(getApplicationContext().getCacheDir(), outputFile + ".pdf");
            FileOutputStream fileOutputStream = new FileOutputStream(file);
            fileOutputStream.write(byteArray);
            fileOutputStream.close();

            String absolutePath = file.getAbsolutePath();
            Log.i(MY_LOG_TAG, absolutePath);
            return Uri.fromFile(file);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.Q)
    @NonNull
    private ForegroundInfo createForegroundInfo(@NonNull String progress) {
        // Build a notification using bytesRead and contentLength
        Context context = getApplicationContext();
        String id = context.getString(R.string.notification_channel_id);
        String title = context.getString(R.string.notification_title);
        String cancel = context.getString(R.string.cancel_download);
        // This PendingIntent can be used to cancel the worker
        PendingIntent intent = WorkManager.getInstance(context)
                .createCancelPendingIntent(getId());

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            createChannel(id);
        }

        Notification notification = new NotificationCompat.Builder(context, id)
                .setContentTitle(title)
                .setTicker(title)
                .setContentText(progress)
                .setSmallIcon(R.drawable.ic_work_notification)
                .setOngoing(true)
                // Add the cancel action to the notification which can
                // be used to cancel the worker
                .addAction(android.R.drawable.ic_delete, cancel, intent)
                .build();

        int notificationId = 1000;
        return new ForegroundInfo(notificationId, notification, FOREGROUND_SERVICE_TYPE_DATA_SYNC);
    }

    @RequiresApi(Build.VERSION_CODES.O)
    private void createChannel(String id) {
        // Create a Notification channel
        NotificationChannel channel = new NotificationChannel(id, "download channel", NotificationManager.IMPORTANCE_NONE);
        notificationManager.createNotificationChannel(channel);
    }
}

FileSizeFetch.java

package com.test.downloadworkerapplication;

import java.net.HttpURLConnection;
import java.net.URL;

public class FileSizeFetcher {
    public static long getFileSize(String urlString) {
        long fileSize = 0;
        HttpURLConnection connection = null;
        try {
            URL url = new URL(urlString);
            connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("HEAD"); // 使用HEAD请求以节省带宽
            int responseCode = connection.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                String contentLength = connection.getHeaderField("Content-Length");
                fileSize = Long.parseLong(contentLength);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }
        return fileSize;
    }
}

运行

请添加图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/632904.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

键盘盲打是练出来的

键盘盲打是练出来的,那该如何练习呢?很简单,看着屏幕提示跟着练。屏幕上哪里有提示呢?请看我的截屏: 截屏下方有8个带字母的方块按钮,这个就是提示,也就是我们常说的8个基准键位,我…

Redis学习篇2:Redis在IEDA中的应用

本文继上文开始讲述了Redis在IDEA中如何应用以及集成进入spring开发环境,以及如何使用Redis客户端。上一个文章:Redis学习篇1:初识Redishttps://blog.csdn.net/jialuosi/article/details/139057088 一、Redis在java中的客户端 二、SpringDat…

通联支付API集成(适用于SpringBoot)

目标: 学习如何使用Java与通联支付API进行交互 实现一个简单的支付下单和查询订单状态的示例 所需材料: 通联支付API文档 官方文档https://aipboss.allinpay.com/know/devhelp/main.php?pid38#mid313 通联支付加签代码SybUtil package com.allin…

从GPT-4o和Google I/O看AI技术变革与未来趋势

引言 在科技界的激烈竞争中,OpenAI 和 Google 这两大巨头不断推出新技术,引领着人工智能的发展。最近,OpenAI 发布了 GPT-4o,恰逢 Google I/O 大会前一天,这一发布会似乎有意“截胡” Google I/O。今天,我…

python实现520表白图案

今天是520哦,作为程序员有必要通过自己的专业知识来向你的爱人表达下你的爱意。那么python中怎么实现绘制520表白图案呢?这里给出方法: 1、使用图形库(如turtle) 使用turtle模块,你可以绘制各种形状和图案…

go 爬虫之 colly 简单示例

1. 背景 colly 是 Go 实现的比较有名的一款爬虫框架,而且 Go 在高并发和分布式场景的优势也正是爬虫技术所需要的。它的主要特点是轻量、快速,设计非常优雅,并且分布式的支持也非常简单,易于扩展。 2. 官方文档 https://go-col…

大模型的实践应用24-LLaMA-Factory微调通义千问qwen1.5-1.8B模型的实例

大家好,我是微学AI,今天给大家介绍一下大模型的实践应用24-LLaMA-Factory微调通义千问qwen1.5-1.8B模型的实例, LLaMA-Factory是一个专门用于大语言模型微调的框架,它支持多种微调方法,如LoRA、QLoRA等,并提供了丰富的数据集和预训练模型,便于用户进行模型微调。通义千问…

15:00面试,15:08就出来了,问的问题有点变态。。。

从小厂出来,没想到在另一家公司又寄了。 到这家公司开始上班,加班是每天必不可少的,看在钱给的比较多的份上,就不太计较了。没想到8月一纸通知,所有人不准加班,加班费不仅没有了,薪资还要降40%…

mysql 慢查询

一、开启mysql自己的慢查询日志 1、查看慢日志参数设置 show VARIABLES like %query% 2、修改配置文件 vim /etc/my.cnf [mysqld] slow_query_log 1 #是否开启慢查询日志记录 long_query_time 1 #慢查询时间,单位秒 #log_outputtable,file #慢查询…

学习Thymeleaf时遇到的问题

使用idea创建web项目,启动服务器后无法访问页面 原因是tomcat 新版本引用包名改变 由javax变为jakarta 解决办法1 把项目的poe.xml文件由 改为 解决办法2 新建项目时选择新版本,但是新版本不支持thymeleaf

基础2 JAVA图形编程桌面:探索图形程序的抽象实现

嘿,大家好!我非常高兴又一次有机会与大家相聚,分享新的知识和经验。对于热爱编程和探索新技术的朋友们来说,今天的内容绝对不容错过。我为大家准备了一个详尽的视频教程:《基础2 JAVA 图形编程:主程序调用…

word-表格疑难杂症诊治

一、用表格进行排版图片、制作公文头 可以在插入图片时固定列宽 二、表格中的疑难杂症 问题一:表格超过页面,右侧文字看不见 解决:表格窗口-布局-自动调整-根据窗口自动调整表格 问题二:表格底部文字被遮挡 解决:布…

sheng的学习笔记-AI-EM算法

AI学习笔记目录:sheng的学习笔记-AI目录-CSDN博客 目录 基础知识 什么是EM算法 EM算法简介 数学知识 极大似然估计 问题描述 用数学知识解决现实问题 最大似然函数估计值的求解步骤 Jensen不等式 定义 EM算法详解 问题描述 EM算法推导流程 EM算法流程…

Java——内部类

内部类概念 当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服 务,那么这个内部的完整结构最好使用内部类。在 Java 中,可以将一个类定义在另一个类或者一个方法的内部&…

CustomTkinter:便捷美化Tkinter的UI界面(附模板)

CustomTkinter是一个基于Tkinter的Python用户界面库。 pip3 install customtkinter它提供了各种UI界面常见的小部件。这些小部件可以像正常的Tkinter小部件一样创建和使用,也可以与正常的Tkinter元素一起使用。 它的优势如下: CustomTkinter的小部件和…

Python 机器学习 基础 之 数据表示与特征工程 【单变量非线性变换 / 自动化特征选择/利用专家知识】的简单说明

Python 机器学习 基础 之 数据表示与特征工程 【单变量非线性变换 / 自动化特征选择/利用专家知识】的简单说明 目录 Python 机器学习 基础 之 数据表示与特征工程 【单变量非线性变换 / 自动化特征选择/利用专家知识】的简单说明 一、简单介绍 二、单变量非线性变换 三、自…

C语言游戏实战(12):植物大战僵尸(坤版)

植物大战僵尸 前言: 本游戏使用C语言和easyx图形库编写,通过这个项目我们可以深度的掌握C语言的各种语言特性和高级开发技巧,以及锻炼我们独立的项目开发能力, 在开始编写代码之前,我们需要先了解一下游戏的基本规则…

倍思/西圣/UHB电容笔怎么选?2024热门电容笔全面性能测评大PK

​在这个追求速度和效率的时代,ipad以其便携性和高性能成为很多上班族、学生党提高生产力和学习效率的重要工具,很多人更是会搭配一支电容笔来进一步发挥ipad的使用价值,可原装的电容笔毕竟价格较高,于是很多人将目光转向平替&…

Day35 代码随想录打卡|二叉树篇---二叉树的层序遍历

题目: 给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。 方法:二叉树的层序遍历感觉是相对简单的,只需要定义一个队列,从根节点开始放入队列…

SQL靶场搭建

概述 简单介绍一下SQL靶场的搭建,以及在搭建过程中遇到的一些问题。使用该软件搭建靶场相对简单,适合新手小白。当然,也可以在自己的虚拟机下进行搭建,相对来说就较为复杂。本章主要讲解使用Phpstudy进行SQL靶场搭建。 这里我推…