Android 使用改装库处理带有通知的多个下载

Android 使用改装库处理带有通知的多个下载,android,service,download,Android,Service,Download,我跟在后面 我的应用程序的UI有几个不同的按钮,它们使用上述方法下载不同的文件。问题是,当某人在按下第一个按钮后按下另一个按钮时,它将排队,并在第一个按钮完成后启动。我希望它立即同时启动 以下是下载服务的代码: public class DownloadService extends IntentService { public DownloadService() { super("Download Service"); } private int t

我跟在后面

我的应用程序的UI有几个不同的按钮,它们使用上述方法下载不同的文件。问题是,当某人在按下第一个按钮后按下另一个按钮时,它将排队,并在第一个按钮完成后启动。我希望它立即同时启动

以下是下载服务的代码:

public class DownloadService extends IntentService {

    public DownloadService() {
        super("Download Service");
    }

    private int totalFileSize;
    private NotificationCompat.Builder notificationBuilder;
    private NotificationManager notificationManager;

    @Override
    protected void onHandleIntent(Intent intent) {
        MyApp x = (MyApp)getApplicationContext();
        notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        notificationBuilder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.ic_file_download_deep_orange_a400_18dp)
                .setContentTitle("Downloading")
                .setContentText("Please wait...")
                .setAutoCancel(true);
        notificationManager.notify(x.ID, notificationBuilder.build());
        Log.i("Paras", "onHandleIntent: " + x.filename + x.url);
        initDownload(x.filename,x.url,x.ID);

    }

    private void initDownload(String filename, String url, int id) {

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://dl.dropboxusercontent.com/")
                .build();

        RequestInterface.RetrofitInterface retrofitInterface = retrofit.create(RequestInterface.RetrofitInterface.class);

        Call<ResponseBody> request = retrofitInterface.downloadFile(url);
        try {

            downloadFile(request.execute().body(),filename,id);

        } catch (IOException e) {

            e.printStackTrace();
            Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_SHORT).show();

        }
    }

    private void downloadFile(ResponseBody body, String filename,int id) throws IOException {

        int count;
        byte data[] = new byte[1024 * 4];
        long fileSize = body.contentLength();
        InputStream bis = new BufferedInputStream(body.byteStream(), 1024 * 8);
        File outputFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), filename);
        OutputStream output = new FileOutputStream(outputFile);
        long total = 0;
        long startTime = System.currentTimeMillis();
        int timeCount = 1;

        while ((count = bis.read(data)) != -1) {
            total += count;
            totalFileSize = (int) (fileSize / (Math.pow(1, 2))) / 1000;
            double current = Math.round(total / (Math.pow(1, 2))) / 1000;

            int progress = (int) ((total * 100) / fileSize);

            long currentTime = System.currentTimeMillis() - startTime;

            Download download = new Download();
            download.setTotalFileSize(totalFileSize);

            if (currentTime > 1000 * timeCount) {
                download.setCurrentFileSize((int) current);
                download.setProgress(progress);
                sendNotification(download,id);
                timeCount++;
            }

            output.write(data, 0, count);
        }

        onDownloadComplete(filename,id);
        output.flush();
        output.close();
        bis.close();

    }

    private void sendNotification(Download download, int id) {

        sendIntent(download);
        notificationBuilder.setProgress(100, download.getProgress(), false);
        notificationBuilder.setContentText("Downloading file " + download.getCurrentFileSize() + "/" + totalFileSize + " KB");
        notificationManager.notify(id, notificationBuilder.build());
    }

    private void sendIntent(Download download) {

        Intent intent = new Intent(subject.MESSAGE_PROGRESS);
        intent.putExtra("download", download);
        LocalBroadcastManager.getInstance(DownloadService.this).sendBroadcast(intent);
    }

    private void onDownloadComplete(String filename,int id) {
        try {

            Download download = new Download();
            download.setProgress(100);
            sendIntent(download);

            notificationManager.cancel(id);
            notificationBuilder.setProgress(0, 0, false);
            notificationBuilder.setContentText("Tap to open");
            notificationManager.notify(id, notificationBuilder.build());

            String path1 = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/" + filename;

            File file = new File(path1);
            Uri uri_path = Uri.fromFile(file);
            String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension
                    (MimeTypeMap.getFileExtensionFromUrl(path1));

            Intent intent = new Intent(android.content.Intent.ACTION_VIEW);
            intent.setType(mimeType);
            intent.setDataAndType(uri_path, mimeType);
            PendingIntent pIntent = PendingIntent.getActivity(this, (int) System.currentTimeMillis(), intent, 0);
            String string = filename;
            notificationBuilder
                    .setContentIntent(pIntent)
                    .setAutoCancel(true)
                    .setContentTitle(string + " Downloaded");
            Log.i("Paras", "onDownloadComplete: " + string);
            notificationManager.notify(id, notificationBuilder.build());
        } catch (Exception ex) {

        }
    }

    @Override
    public void onTaskRemoved(Intent rootIntent) {

    }
}
但它不起作用。有什么线索告诉我该怎么做吗?如果需要,我准备提供更多细节


编辑1:DownloadService在“startDownload”功能上运行,该功能由各种按钮执行。正如您在第二段代码中看到的,类扩展了服务。有一个线程处理所有这些按钮点击。若你们查看评论,建议我应该使用服务和不同的线程来完成所有这些点击。现在,我如何以编程方式生成这么多线程。几乎有40个按钮使用下载服务。

多亏了@Lxu,我才让它工作起来。因此,
IntentService
意味着一次只能执行一项任务,不能同时执行多个任务。我们应该使用
服务
。它允许同时执行多个任务。我们可以在
服务
中创建多个线程,这些线程将同时执行。通过将
onCreate()
的所有代码放到
onStartCommand()
中,我的问题得到了解决。第一次调用服务时,将调用
onCreate()
,之后,无论调用多少次服务,都不再调用该服务。在每次服务调用时,都会执行
onStartCommand()
,每次都会创建新线程。就这样

以下是完整的代码:

public class DownloadService extends Service {

    public DownloadService() {
        super();
    }
    private Looper mServiceLooper;
    private ServiceHandler mServiceHandler;

    int id1;
    int id2;
    private final class ServiceHandler extends Handler {
        public ServiceHandler(Looper looper) {
            super(looper);
        }
        @Override
        public void handleMessage(Message msg) {
            MyApp x = (MyApp)getApplicationContext();
            notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

            notificationBuilder = new NotificationCompat.Builder(getApplicationContext())
                    .setSmallIcon(R.drawable.ic_file_download_deep_orange_a400_18dp)
                    .setContentTitle("Downloading")
                    .setContentText("Please wait...")
                    .setAutoCancel(true);
            notificationManager.notify(x.ID, notificationBuilder.build());
            Log.i("Paras", "onHandleIntent: " + x.filename + x.url + "  " + x.ID);
            initDownload(x.filename,x.url,x.ID);
        }
    }
    @Override
    public void onCreate() {
        // Get the HandlerThread's Looper and use it for our Handler
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // For each start request, send a message to start a job and deliver the
        // start ID so we know which request we're stopping when we finish the job
        HandlerThread thread = new HandlerThread("ServiceStartArguments", Process.THREAD_PRIORITY_BACKGROUND);
        thread.start();
        mServiceLooper = thread.getLooper();
        mServiceHandler = new ServiceHandler(mServiceLooper);
        MyApp x = (MyApp)getApplicationContext();
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        mServiceHandler.sendMessage(msg);


        // If we get killed, after returning from here, restart
        return START_STICKY;
    }
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {

        return null;
    }

    private int totalFileSize;
    private NotificationCompat.Builder notificationBuilder;
    private NotificationManager notificationManager;

    private void initDownload(String filename, String url, int id) {

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://dl.dropboxusercontent.com/")
                .build();

        RequestInterface.RetrofitInterface retrofitInterface = retrofit.create(RequestInterface.RetrofitInterface.class);

        Call<ResponseBody> request = retrofitInterface.downloadFile(url);
        try {

            downloadFile(request.execute().body(),filename,id);

        } catch (IOException e) {

            e.printStackTrace();
            Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_SHORT).show();

        }
    }

    private void downloadFile(ResponseBody body, String filename,int id) throws IOException {

        int count;
        byte data[] = new byte[1024 * 4];
        long fileSize = body.contentLength();
        InputStream bis = new BufferedInputStream(body.byteStream(), 1024 * 8);
        File outputFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), filename);
        OutputStream output = new FileOutputStream(outputFile);
        long total = 0;
        long startTime = System.currentTimeMillis();
        int timeCount = 1;
        while ((count = bis.read(data)) != -1) {

            total += count;
            totalFileSize = (int) (fileSize / (Math.pow(1, 2))) / 1000;
            double current = Math.round(total / (Math.pow(1, 2))) / 1000;

            int progress = (int) ((total * 100) / fileSize);

            long currentTime = System.currentTimeMillis() - startTime;

            Download download = new Download();
            download.setTotalFileSize(totalFileSize);

            if (currentTime > 1000 * timeCount) {

                download.setCurrentFileSize((int) current);
                download.setProgress(progress);
                sendNotification(download,id);
                timeCount++;
            }

            output.write(data, 0, count);
        }
        onDownloadComplete(filename,id);
        output.flush();
        output.close();
        bis.close();

    }

    private void sendNotification(Download download, int id) {

        sendIntent(download,id);
        notificationBuilder.setProgress(100, download.getProgress(), false)
                            .setContentTitle("Downloading");
        notificationBuilder.setContentText("Downloading file " + download.getCurrentFileSize() + "/" + totalFileSize + " KB");
        notificationManager.notify(id, notificationBuilder.build());
    }

    private void sendIntent(Download download, int id) {

        Intent intent = new Intent(subject.MESSAGE_PROGRESS);
        intent.putExtra("download", download);
        LocalBroadcastManager.getInstance(DownloadService.this).sendBroadcast(intent);
    }

    private void onDownloadComplete(String filename,int id) {
        try {

            Download download = new Download();
            download.setProgress(100);
            sendIntent(download,id);

            notificationManager.cancel(id);
            notificationBuilder.setProgress(0, 0, false);
            notificationBuilder.setContentText("Tap to open");
            notificationManager.notify(id, notificationBuilder.build());

            String path1 = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/" + filename;

            File file = new File(path1);
            Uri uri_path = Uri.fromFile(file);
            String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension
                    (MimeTypeMap.getFileExtensionFromUrl(path1));

            Intent intent = new Intent(android.content.Intent.ACTION_VIEW);
            intent.setType(mimeType);
            intent.setDataAndType(uri_path, mimeType);
            PendingIntent pIntent = PendingIntent.getActivity(this,(int) System.currentTimeMillis(), intent, 0);
            String string = filename;
            notificationBuilder
                    .setContentIntent(pIntent)
                    .setAutoCancel(true)
                    .setContentTitle(string + " Downloaded");
            Log.i("Paras", "onDownloadComplete: " + string);
            notificationManager.notify(id, notificationBuilder.build());
        }catch (Exception ex){

        }
    }
    @Override
    public void onTaskRemoved(Intent rootIntent) {

    }
}
公共类下载服务扩展服务{
公共下载服务(){
超级();
}
专用活套;
私有服务处理程序mServiceHandler;
INTID1;
INTID2;
私有最终类ServiceHandler扩展处理程序{
公共服务处理程序(活套-活套){
超级(活套);
}
@凌驾
公共无效handleMessage(消息消息消息){
MyApp x=(MyApp)getApplicationContext();
notificationManager=(notificationManager)getSystemService(Context.NOTIFICATION\u服务);
notificationBuilder=新建NotificationCompat.Builder(getApplicationContext())
.setSmallIcon(R.drawable.ic_文件_下载_deep_orange_a400_18dp)
.setContentTitle(“下载”)
.setContentText(“请稍候…”)
.setAutoCancel(真);
notificationManager.notify(x.ID,notificationBuilder.build());
Log.i(“段落”,“OnHandleContent:”+x.filename+x.url+”+x.ID);
initDownload(x.filename,x.url,x.ID);
}
}
@凌驾
public void onCreate(){
//获取HandlerThread的活套并将其用于我们的处理程序
}
@凌驾
公共int onStartCommand(Intent Intent、int标志、int startId){
//对于每个启动请求,发送消息以启动作业并交付
//启动ID,以便在完成作业时知道要停止的请求
HandlerThread线程=新的HandlerThread(“ServiceStartArguments”,Process.thread\u PRIORITY\u BACKGROUND);
thread.start();
mServiceLooper=thread.getLooper();
MSServiceHandler=新的ServiceHandler(MSServiceLooper);
MyApp x=(MyApp)getApplicationContext();
Message msg=mServiceHandler.obtainMessage();
msg.arg1=startId;
mServiceHandler.sendMessage(msg);
//如果我们被杀了,从这里回来后,重新开始
返回开始时间;
}
@可空
@凌驾
公共IBinder onBind(意向){
返回null;
}
私有整数文件大小;
私人通知建筑商通知建筑商;
私人通知经理通知经理;
私有void initDownload(字符串文件名、字符串url、int id){
改装改装=新改装.Builder()
.baseUrl(“https://dl.dropboxusercontent.com/")
.build();
RequestInterface.RefundationInterface=Refundation.create(RequestInterface.RefundationInterface.class);
调用请求=interface.downloadFile(url);
试一试{
下载文件(request.execute().body(),文件名,id);
}捕获(IOE异常){
e、 printStackTrace();
Toast.makeText(getApplicationContext(),e.getMessage(),Toast.LENGTH_SHORT).show();
}
}
私有void下载文件(ResponseBody主体、字符串文件名、int-id)引发IOException{
整数计数;
字节数据[]=新字节[1024*4];
long fileSize=body.contentLength();
InputStream bis=新的BufferedInputStream(body.ByTestStream(),1024*8);
File outputFile=新文件(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY\u下载),文件名);
OutputStream output=新文件OutputStream(outputFile);
长总计=0;
long startTime=System.currentTimeMillis();
int timeCount=1;
而((计数=二读(数据))!=-1){
总数+=计数;
totalFileSize=(int)(fileSize/(Math.pow(1,2))/1000;
双电流=数学圆整(总/(数学功率(1,2))/1000;
int进度=(int)((总计*100)/文件大小);
长currentTime=System.currentTimeMillis()-startTime;
下载=新下载();
下载.setTotalFileSize(totalFileSize);
如果(当前时间>1000*时间计数){
下载.setCurrentFileSize((int)current);
下载.setProgress(progress);
发送通知(下载,id);
timeCount++;
}
输出.写入(数据,0,计数);
}
昂敦
public class DownloadService extends Service {

    public DownloadService() {
        super();
    }
    private Looper mServiceLooper;
    private ServiceHandler mServiceHandler;

    int id1;
    int id2;
    private final class ServiceHandler extends Handler {
        public ServiceHandler(Looper looper) {
            super(looper);
        }
        @Override
        public void handleMessage(Message msg) {
            MyApp x = (MyApp)getApplicationContext();
            notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

            notificationBuilder = new NotificationCompat.Builder(getApplicationContext())
                    .setSmallIcon(R.drawable.ic_file_download_deep_orange_a400_18dp)
                    .setContentTitle("Downloading")
                    .setContentText("Please wait...")
                    .setAutoCancel(true);
            notificationManager.notify(x.ID, notificationBuilder.build());
            Log.i("Paras", "onHandleIntent: " + x.filename + x.url + "  " + x.ID);
            initDownload(x.filename,x.url,x.ID);
        }
    }
    @Override
    public void onCreate() {
        // Get the HandlerThread's Looper and use it for our Handler
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // For each start request, send a message to start a job and deliver the
        // start ID so we know which request we're stopping when we finish the job
        HandlerThread thread = new HandlerThread("ServiceStartArguments", Process.THREAD_PRIORITY_BACKGROUND);
        thread.start();
        mServiceLooper = thread.getLooper();
        mServiceHandler = new ServiceHandler(mServiceLooper);
        MyApp x = (MyApp)getApplicationContext();
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        mServiceHandler.sendMessage(msg);


        // If we get killed, after returning from here, restart
        return START_STICKY;
    }
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {

        return null;
    }

    private int totalFileSize;
    private NotificationCompat.Builder notificationBuilder;
    private NotificationManager notificationManager;

    private void initDownload(String filename, String url, int id) {

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://dl.dropboxusercontent.com/")
                .build();

        RequestInterface.RetrofitInterface retrofitInterface = retrofit.create(RequestInterface.RetrofitInterface.class);

        Call<ResponseBody> request = retrofitInterface.downloadFile(url);
        try {

            downloadFile(request.execute().body(),filename,id);

        } catch (IOException e) {

            e.printStackTrace();
            Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_SHORT).show();

        }
    }

    private void downloadFile(ResponseBody body, String filename,int id) throws IOException {

        int count;
        byte data[] = new byte[1024 * 4];
        long fileSize = body.contentLength();
        InputStream bis = new BufferedInputStream(body.byteStream(), 1024 * 8);
        File outputFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), filename);
        OutputStream output = new FileOutputStream(outputFile);
        long total = 0;
        long startTime = System.currentTimeMillis();
        int timeCount = 1;
        while ((count = bis.read(data)) != -1) {

            total += count;
            totalFileSize = (int) (fileSize / (Math.pow(1, 2))) / 1000;
            double current = Math.round(total / (Math.pow(1, 2))) / 1000;

            int progress = (int) ((total * 100) / fileSize);

            long currentTime = System.currentTimeMillis() - startTime;

            Download download = new Download();
            download.setTotalFileSize(totalFileSize);

            if (currentTime > 1000 * timeCount) {

                download.setCurrentFileSize((int) current);
                download.setProgress(progress);
                sendNotification(download,id);
                timeCount++;
            }

            output.write(data, 0, count);
        }
        onDownloadComplete(filename,id);
        output.flush();
        output.close();
        bis.close();

    }

    private void sendNotification(Download download, int id) {

        sendIntent(download,id);
        notificationBuilder.setProgress(100, download.getProgress(), false)
                            .setContentTitle("Downloading");
        notificationBuilder.setContentText("Downloading file " + download.getCurrentFileSize() + "/" + totalFileSize + " KB");
        notificationManager.notify(id, notificationBuilder.build());
    }

    private void sendIntent(Download download, int id) {

        Intent intent = new Intent(subject.MESSAGE_PROGRESS);
        intent.putExtra("download", download);
        LocalBroadcastManager.getInstance(DownloadService.this).sendBroadcast(intent);
    }

    private void onDownloadComplete(String filename,int id) {
        try {

            Download download = new Download();
            download.setProgress(100);
            sendIntent(download,id);

            notificationManager.cancel(id);
            notificationBuilder.setProgress(0, 0, false);
            notificationBuilder.setContentText("Tap to open");
            notificationManager.notify(id, notificationBuilder.build());

            String path1 = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/" + filename;

            File file = new File(path1);
            Uri uri_path = Uri.fromFile(file);
            String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension
                    (MimeTypeMap.getFileExtensionFromUrl(path1));

            Intent intent = new Intent(android.content.Intent.ACTION_VIEW);
            intent.setType(mimeType);
            intent.setDataAndType(uri_path, mimeType);
            PendingIntent pIntent = PendingIntent.getActivity(this,(int) System.currentTimeMillis(), intent, 0);
            String string = filename;
            notificationBuilder
                    .setContentIntent(pIntent)
                    .setAutoCancel(true)
                    .setContentTitle(string + " Downloaded");
            Log.i("Paras", "onDownloadComplete: " + string);
            notificationManager.notify(id, notificationBuilder.build());
        }catch (Exception ex){

        }
    }
    @Override
    public void onTaskRemoved(Intent rootIntent) {

    }
}