如何在活动中获取服务对象?

时间:2012-06-24 13:26:32

标签: android android-asynctask android-service

这是我的服务代码:

public class DownloadService extends Service {
    LocalBroadcastManager mLocalBroadcastManager;
    ArrayList<DownloadAsyncTask> dat = new ArrayList<DownloadAsyncTask>();
    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }

    @Override
    public void onStart( Intent intent, int startId ) {
          super.onStart( intent, startId );
          Log.d("service","DownloadService started");
    }
    public void startDownload(String url, String fname, ProgressBar pBar){
        int dID = dat.size();
        Log.d("status","dat length:"+dID);
        dat.add( new DownloadAsyncTask(url,fname,pBar));
        dat.get(dID).execute();
    }

    public void cancelDownload(String fname){
        for(DownloadAsyncTask da: dat){
            if(da.getName().equals(fname)){
                da.cancel(true);
            }
        }
    }

    public DownloadAsyncTask getDownloadByName(String fname){
        for(DownloadAsyncTask da: dat){
            if(da.getName().equals(fname)){
                return da;
            }
        }
        return null;
    }
    public ArrayList<DownloadAsyncTask> getAllDownloads(){
        return dat;
    }
    public class DownloadAsyncTask extends AsyncTask<String, Integer, String>{
        ProgressBar progressBar;
        File sdCard = Environment.getExternalStorageDirectory();
        File dir = new File (sdCard.getAbsolutePath() + "/com.ms.rightel.store/");
        int percentage = 0;
        static final int DOWNLOAD_STATUS_FINISHED = 1;
        static final int DOWNLOAD_STATUS_RUNNING = 0;
        static final int DOWNLOAD_STATUS_FAILED = -1;
        static final int DOWNLOAD_STATUS_PAUSED = 2;
        int status = DOWNLOAD_STATUS_RUNNING;
        double fileSize = 0;
        String downloadUrl,fileName;

        public DownloadAsyncTask(String url, String fname, ProgressBar pBar){
            downloadUrl = url;
            fileName = fname;
            progressBar = pBar;
        }
        public String getName(){
            return fileName;
        }
        public void replaceProgressBar(ProgressBar pBar){
            progressBar = pBar;
        }

        private boolean checkDirs(){
            if(!dir.exists()){
                return dir.mkdirs();
            }
            return true;
        }
        public int getDownloadStatus(){
            return status;
        }
        private long isIncomplete(){
            File from = new File(dir,fileName+"-incomplete");
            if(from.exists()){
                Log.d("status","download is incomplete, filesize:" + from.length());
                return from.length();
            }
            return 0;
        }

        @Override
        protected String doInBackground(String... params) {
                //fileName = downloadUrl.substring(downloadUrl.lastIndexOf("/")+1);
                if(!checkDirs()){
                    return "Making directories failed!";
                }
                try {
                    byte[] buffer = new byte[500];
                    int bufferLength = 0;
                    double downloadedSize = 0;
                    URL url = new URL(downloadUrl);
                    HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
                    urlConnection.setRequestMethod("GET");
                    urlConnection.setConnectTimeout(10000);
                    urlConnection.setReadTimeout(10000);
                    //Log.d("status","ReadTimeOut: "+urlConnection.getReadTimeout() + "ConnectTimeOut: "+urlConnection.getConnectTimeout());
                    long downloaded = isIncomplete();
                    if(downloaded > 0){
                        urlConnection.setRequestProperty("Range", "bytes="+(downloaded)+"-");
                        downloadedSize = downloaded;
                        fileSize = downloaded;
                    }
                    urlConnection.setDoOutput(true);
                    urlConnection.connect();
                    fileSize += urlConnection.getContentLength();
                    FileOutputStream fos = new FileOutputStream(new File(dir,fileName+"-incomplete"),true);
                    InputStream inputStream = urlConnection.getInputStream();
                    while ( (bufferLength = inputStream.read(buffer)) > 0 ) 
                    {
                        if(isCancelled()){
                            break;
                        }
                        fos.write(buffer, 0, bufferLength);
                        downloadedSize += bufferLength;
                        percentage = (int) ((downloadedSize / fileSize) * 100);
                        publishProgress(percentage);
                        //Log.d("status","downloading: " + downloadedSize+"/"+fileSize+" ("+percentage+"%)");
                    }
                    fos.close();
                    urlConnection.disconnect();
                } catch (Exception e) {
                    Log.e("Download Failed","Error: " + e.getMessage());
                    return "Download failed";
                }
                if(isCancelled()){
                    return "Download cancelled";
                }
            return "Download complete";
        }
        @Override
        protected void onProgressUpdate(Integer... values){
            super.onProgressUpdate(values[0]);
            if(progressBar != null){
                progressBar.setProgress(values[0]);
            }else{
                Log.w("status", "ProgressBar is null, please supply one!");
            }
        }

        @Override
        protected void onPreExecute(){
            mLocalBroadcastManager.sendBroadcast(new Intent("org.test.download.DOWNLOAD_STARTED"));
        }

        @Override
        protected void onPostExecute(String str){
            if(str.equals("Download complete")){
                File from = new File(dir,fileName+"-incomplete");
                File to = new File(dir,fileName);
                from.renameTo(to);
                mLocalBroadcastManager.sendBroadcast(new Intent("org.test.download.DOWNLOAD_FINISHED"));
            }
            if(str.equals("Download failed")){
                mLocalBroadcastManager.sendBroadcast(new Intent("org.test.download.DOWNLOAD_FAILED"));
            }
        }

        @Override
        protected void onCancelled(){
            mLocalBroadcastManager.sendBroadcast(new Intent("org.test.download.DOWNLOAD_CANCELLED"));
        }

    }

}

我正在使用此服务来管理多个下载。现在我需要在不同的活动中访问此服务对象,以便能够添加到下载或获取当前正在运行的下载列表。我怎么能这样做?

2 个答案:

答案 0 :(得分:6)

好吧,我通过使用单例来完成它。我在类中添加了一个静态变量,该变量由null初始化。然后在onStart方法内部,我将类的当前实例分配给此静态变量,然后使用静态方法返回实际对象。

private static DownloadService self = null;
public static DownloadService getServiceObject(){
    return self;
}
@Override
public void onStart( Intent intent, int startId ) {
   super.onStart( intent, startId );
   self = this;
}

答案 1 :(得分:1)

Yo可以将数据从Activity传递到您的服务:

Intent myIntent = new Intent(MainActivity.this, DownloadService.class);
Bundle bundle = new Bundle();
bundle.putCharSequence("extraData", "DATA YOU WANT TO SEND SERVICE");
myIntent.putExtras(bundle);
pendingIntent = PendingIntent.getService(MainActivity.this, 0, myIntent, 0);

并在DownloadService中

public void onStart(Intent intent, int startId) {
 // TODO Auto-generated method stub
 super.onStart(intent, startId);

 Bundle bundle = intent.getExtras();
 data = (String) bundle.getCharSequence("extraData");
 smsTextToSend = (String) bundle.getCharSequence("extraSmsText");
 ...
}

和另一个在服务和活动之间进行通信的选项使用Custom BroadcastReceiver

see this example用于使用BroadcastReceiver在服务和活动之间进行通信:

Communication between service and activity