Android的改造 - onProgressUpdate用于显示进度通知进度、通知、Android、onProgressUpdate

2023-09-12 10:46:20 作者:理想人格

我目前使用的改造由广场为Android网络通信。有没有一种方法任务,以创建进度的通知中得到了进步,上传图片时,它的Facebook使用类似的东西?

使用情况是有希望的完整图像质量的图像加载没有COM pression或缩放。

我看它是如何可能与AsyncTask的,但是这不符合使用改造的目的。然而,可能是该路由我将不得不考虑。

解决方案

我有同样的问题,终于成功地做到这一点。我用春天的lib前,我下面展示样的工作了,但春天是不一致的,因为我犯了一个错误的使用它的InputStream的。我把我所有的API的使用改造和上传在名单上的最后一个,我只是重写 TypedFile 的writeTo()上读取到的OutputStream的字节更新我。也许这可以改进,但正如我说我做到了,当我使用Spring,所以我只是重复使用它。 这是code上传和它的工作对我来说我的应用程序,如果你想下载的反馈,那么你可以使用@Streaming和读取的InputStream。

ProgressListener

 公共接口ProgressListener {
 虚空转移(长NUM);
}
 

CountingTypedFile

 公共类CountingTypedFile扩展TypedFile {

 私有静态最终诠释BUFFER_SIZE = 4096;

 私人最终ProgressListener监听;

 公共CountingTypedFile(字符串MIMETYPE,文件档案,ProgressListener监听器){
    超(MIMETYPE,文件);
    this.listener =侦听器;
 }

 @覆盖公共无效的writeTo(OutputStream中出)抛出IOException异常{
    byte []的缓冲区=新的字节[BUFFER_SIZE];
    在的FileInputStream =新的FileInputStream(super.file());
    总长= 0;
    尝试 {
        INT读取;
        而((读= in.read(缓冲))!= -1){
            共有+ =读取;
            this.listener.transferred(总);
            out.write(缓冲,0,读);
        }
    } 最后 {
        附寄();
    }
 }
}
 
Android 系统启动流程

MyApiService

 公共接口MyApiService {
 @Multipart
 @POST(/文件)
 ApiResult uploadFile(@Part(文件)TypedFile资源,@Query(路径)字符串路径);
}
 

SendFileTask

 私有类SendFileTask扩展的AsyncTask<字符串,整数,ApiResult> {
    私人ProgressListener监听;
    私人字符串文件路径;
    私人文件类型的fileType;

    公共SendFileTask(字符串文件路径,文件类型的fileType){
        this.filePath =文件路径;
        this.fileType =的fileType;
    }

    @覆盖
    保护ApiResult doInBackground(字符串... PARAMS){
        档案文件=新的文件(文件路径);
        totalSize = file.length();
        Logger.d(上传文件大小[%D],totalSize);
        监听=新ProgressListener(){
            @覆盖
            公共无效转移(长NUM){
                publishProgress((INT)((NUM /(浮点)totalSize)* 100));
            }
        };
        字符串_fileType = FileType.VIDEO.equals(的fileType)? 视频/ MP4:(FileType.IMAGE.equals(的fileType)为image / jpeg:* / *);
        返回MyRestAdapter.getService()uploadFile(新CountingTypedFile(_fileType,文件,侦听器),/手机上传)。
    }

    @覆盖
    保护无效onProgressUpdate(整数...值){
        Logger.d(的String.Format(进步[%D],值[0]));
        //做些什么值[0],它的比例,所以你可以很容易做到
        //progressBar.setProgress(values​​[0]);
    }
}
 

在 CountingTypedFile 是只是一个副本的 TypedFile 但包括ProgressListener。

I'm currently using Retrofit by Square for Android network communications. Is there a way to get its progress during a task to create a progress notification, something similar to that which Facebook uses when uploading an image?

Use Case would be to load an image hopefully of full image quality without compression or scaling.

I see how it is possible with an asynctask but that would defeat the purpose of using Retrofit. However that might be the route I would have to take.

解决方案

I had the same problem and finally managed to do it. I was using spring lib before and what I show below kind worked for Spring but was inconsistent since I made a mistake on using it for the InputStream. I moved all my API's to use retrofit and upload was the last one on the list, I just override TypedFile writeTo() to update me on the bytes read to the OutputStream. Maybe this can be improved but as I said I made it when I was using Spring so I just reused it. This is the code for upload and it's working for me on my app, if you want download feedback then you can use @Streaming and read the inputStream.

ProgressListener

public interface ProgressListener {
 void transferred(long num);
}

CountingTypedFile

public class CountingTypedFile extends TypedFile {

 private static final int BUFFER_SIZE = 4096;

 private final ProgressListener listener;

 public CountingTypedFile(String mimeType, File file, ProgressListener listener) {
    super(mimeType, file);
    this.listener = listener;
 }

 @Override public void writeTo(OutputStream out) throws IOException {
    byte[] buffer = new byte[BUFFER_SIZE];
    FileInputStream in = new FileInputStream(super.file());
    long total = 0;
    try {
        int read;
        while ((read = in.read(buffer)) != -1) {
            total += read;
            this.listener.transferred(total);
            out.write(buffer, 0, read);
        }
    } finally {
        in.close();
    }
 }
}

MyApiService

public interface MyApiService {
 @Multipart
 @POST("/files")
 ApiResult uploadFile(@Part("file") TypedFile resource, @Query("path") String path);
}

SendFileTask

private class SendFileTask extends AsyncTask<String, Integer, ApiResult> {
    private ProgressListener listener;
    private String filePath;
    private FileType fileType;

    public SendFileTask(String filePath, FileType fileType) {
        this.filePath = filePath;
        this.fileType = fileType;
    }

    @Override
    protected ApiResult doInBackground(String... params) {
        File file = new File(filePath);
        totalSize = file.length();
        Logger.d("Upload FileSize[%d]", totalSize);
        listener = new ProgressListener() {
            @Override
            public void transferred(long num) {
                publishProgress((int) ((num / (float) totalSize) * 100));
            }
        };
        String _fileType = FileType.VIDEO.equals(fileType) ? "video/mp4" : (FileType.IMAGE.equals(fileType) ? "image/jpeg" : "*/*");
        return MyRestAdapter.getService().uploadFile(new CountingTypedFile(_fileType, file, listener), "/Mobile Uploads");
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        Logger.d(String.format("progress[%d]", values[0]));
        //do something with values[0], its the percentage so you can easily do
        //progressBar.setProgress(values[0]);
    }
}

The CountingTypedFile is just a copy of TypedFile but including the ProgressListener.