Android 在使用服务进行文件上载时,如何更新状态栏中的进度栏?

Android 在使用服务进行文件上载时,如何更新状态栏中的进度栏?,android,service,notifications,progress-bar,Android,Service,Notifications,Progress Bar,我对此进行了研究,但没有找到一个明确的答案,即进度条+状态条+服务?我的问题是实现文件上传的方式(这是唯一的方式,因为服务器支持这种方式),我无法跟踪写入的字节数。因此,我无法正确增加进度条以反映准确的文件上载状态。 当前实现增加进度条,执行上载,并在进度条达到100时删除进度条。但这一进展并不能准确反映上传情况。上传的时间要早得多,但酒吧还在继续。我希望在该请求/响应发生时显示进度。 以下是我的代码片段: public class UploadFileService extends Int

我对此进行了研究,但没有找到一个明确的答案,即进度条+状态条+服务?我的问题是实现文件上传的方式(这是唯一的方式,因为服务器支持这种方式),我无法跟踪写入的字节数。因此,我无法正确增加进度条以反映准确的文件上载状态。 当前实现增加进度条,执行上载,并在进度条达到100时删除进度条。但这一进展并不能准确反映上传情况。上传的时间要早得多,但酒吧还在继续。我希望在该请求/响应发生时显示进度。 以下是我的代码片段:

  public class UploadFileService extends IntentService {
    public UploadFileService() {
super("UploadFileService");
}

@Override
protected void onHandleIntent(Intent intent) {
    fName = intent.getExtras().getString(Constants.EXTRA_K_FILENAME);
    path = intent.getExtras().getString(Constants.EXTRA_K_FILEPATH);
            attribute = intent.getExtras().getString(Constants.EXTRA_K_ATTRIBUTE);

//Start thread to doFilepUpload
uploadthread = new UploadThread(fName, path, attribute);
uploadthread.start();
}

//定义从线程接收消息并更新进度的处理程序

    final Handler handler = new Handler() {
    public void handleMessage(Message msg) {

        Integer total = msg.arg1;
        notification.contentView.setProgressBar(R.id.status_progress, 100, total, false);
        nm.notify(NOTIFICATION_ID, notification);



        if ( total.equals(100)  && getResponse() != null ){
            // inform the progress bar of updates in progress
            uploadthread.setState(UploadThread.STATE_DONE);

            Intent broadcastIntent = prepareBroadcast();
            // remove the notification (we're done)
            nm.cancel(NOTIFICATION_ID);
            sendBroadcast(broadcastIntent);
        }
    }
};


public class UploadThread extends Thread {

    private String name;
    private String path;
    private String attribute;
    final static int STATE_DONE = 0;
    final static int STATE_RUNNING = 1;
    int mState;
    int total;


    public UploadThread(String fName, String path, String attribute) {
        // TODO Auto-generated constructor stub
        this.name = fName;
        this.path = path;
        this.attribute = attribute;
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        setResponse(doFileUpload(name, path, attribute));

        if( getResponse() != null){
                            // house keeping for the application
            if(response.result.equalsIgnoreCase("success")){
                saveFileName = response.data.savedFileName;
                responseMessage = response.message;
            }else if (response.result.equalsIgnoreCase("error") || 
         response ==  null ){
                responseMessage = response.message; 
                saveFileName = null;
                originalName = fName;
            }
        }

        mState = STATE_RUNNING;   
        total = 0;
        while (mState == STATE_RUNNING && total <=100) {
            try {
                Log.d(TAG, "^^ Thread.sleep");
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                Logger.e("ERROR", "Thread Interrupted");
            }
            Message msg = handler.obtainMessage();
            msg.arg1 = total;
            handler.sendMessage(msg);
            total++;
        }
    }

    /* sets the current state for the thread,
     * used to stop the thread */
    public void setState(int state) {
        mState = state;
    }

}

我找到了解决这个问题的办法。这不是一个理想的解决方案,但由于字节计数是不可能的,我求助于这条路线。在我创建的上传服务中,我有两个不同的线程。线程#1负责上传,线程#2负责在通知区域维护进度条。线程2依赖于线程1。当#1处于活动状态时,线程#2增加1并休眠1秒,每增加一次进度,休眠间隔就会增加0.2秒。如果上传在45%完成,进度条将跳到100%

您是否尝试过在上传作业中使用
AsyncTask
?它允许您使用
publishProgress()
,无论何时调用此方法,您都可以从这里向UI广播…?@NikolaDespotoski:我确实尝试过AsyncTask,但由于一些问题,例如一次上载一个文件,服务似乎是此应用程序的最佳选择。如果您是从服务中执行此操作,为什么还要使用线程,由于服务在单独的进程上运行,这不会导致活动中的任何UI冻结。只要想办法计算上传进度就行了。从服务运行线程是可以的,我完全理解…这是我的简短想法…@NikolaDespotoski:实际上这就是我现在的问题和障碍:“计算上传的进度”progress=file.getTotalSpace()-(file.getTotalSpace()-上传);也许:D,然后使用简单的数学计算将进度转换为进度条,其中进度条的最大值将是文件的总大小。。。
    paramString = p.getName()+"="+URLEncoder.encode(p.getValue(), HTTP.UTF_8);
                    } catch (UnsupportedEncodingException e) {
                        Log.e(TAG, "unsupported encoding --> 
           name="+p.getName()+"; value="+p.getValue(), e);
                        throw e;
                    }
                    if (combinedParams.length() > 1) {
                        combinedParams += "&" + paramString;
                    } else {
                        combinedParams += paramString;
                    }
                }
            }

            request = new HttpPost(url + combinedParams);

            MultipartEntity entity = new MultipartEntity();

            // add headers
            for (NameValuePair h : headers) {               
                request.addHeader(h.getName(), h.getValue());
            }

            // add cookies
            for(NameValuePair c : cookies) {            
                request.addHeader(H_COOKIE,          
                         c.getName()+"="+c.getValue());                 
            }           
                 entity.addPart(uploadFile.getName(), new FileBody(uploadFile));

            request.setEntity(entity)