1

我正在编写一个广播应用程序,用户可以在其中下载一些节目。

当用户单击音频播放器上的下载按钮时,该节目将作为SavedShow.

用户可以SavedShow在 a 中查看实例的状态SavedShowsFragment,其中显示了ListView已保存节目的列表。

每一行ListView是已保存节目的标题、其状态 ( NOT_STARTED/DOWNLOADING/PAUSED/DOWNLOADED/ERROR)、aProgressBar和 aButton用于暂停下载、继续下载或播放文件(如果已下载)。

现在我不知道如何将列表中的每个项目绑定到我的,DownloadService也不知道如何在适配器中实现侦听DownloadService器。

基本上,我希望每一行:

  • DownloadTask.onProgressUpdate我的DownloadService
  • DownloadService下载完成或出现错误时收到通知
  • 调用方法DownloadService(例如,如果文件正在下载,则单击按钮时暂停下载)

有人可以帮忙吗?

已保存节目片段

public class SavedShowsFragment extends Fragment {

    private DownloadService mDownloadService;
    private boolean mBoundToDownloadService = false;

    private ListView mListView;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        return inflater.inflate(R.layout.saved_show_list, container, false);
    }

    @Override
    public void onActivityCreated (Bundle savedInstanceState){
        super.onActivityCreated(savedInstanceState);
    }

    private void setSavedShowList(){

        mListView = (ListView) getView().findViewById(R.id.listview);   

        SavedShowAdapter adapter = new SavedShowAdapter(getActivity(), MyApplication.dbHelper.getSavedShowList());
        mListView.setAdapter(adapter); 
    }

    @Override
    public void onCreate (Bundle savedInstanceState){

        super.onCreate(savedInstanceState);

        // start services

        Intent intent = new Intent(getActivity(), DownloadService.class);
        getActivity().startService(intent);
    }

    @Override
    public void onResume() {         
        super.onResume();

        setSavedShowList();

        // bind service

        Intent intent = new Intent(getActivity(), StreamService.class);
        getActivity().bindService(intent, mDownloadServiceConnection, Context.BIND_AUTO_CREATE);

    }

    @Override
    public void onPause() {

        // unbind service

        if (mBoundToDownloadService) {
            getActivity().unbindService(mDownloadServiceConnection);
        }

        super.onPause();
    }   

    private ServiceConnection mDownloadServiceConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName className, IBinder service) {          

            /*
             * Get service instance
             */

            DownloadServiceBinder binder = (DownloadServiceBinder) service;
            mDownloadService = binder.getService();         
            mBoundToDownloadService = true;

            /*
             * Start download for NOT_STARTED saved show
             */

            for(SavedShow savedShow : MyRadioApplication.dbHelper.getSavedShowList()){

                if(savedShow.getState()==SavedShow.State.NOT_STARTED){
                    mDownloadService.downLoadFile(savedShow.getId());
                }           
            }

        }

        @Override
        public void onServiceDisconnected(ComponentName arg0) {
            mBoundToDownloadService = false;
        }
    };  

}

SavedShowAdapter

public class SavedShowAdapter extends ArrayAdapter<SavedShow> { 

    private LayoutInflater mLayoutInflater;

    static class ViewHolder {
        TextView title, status;
        ProgressBar progressBar;
        Button downloadStateBtn;
    }


    public SavedShowAdapter(Context context, List<SavedShow> saved_show_list) {
        super(context, 0, saved_show_list);     
        mLayoutInflater = (LayoutInflater) context.getSystemService( Context.LAYOUT_INFLATER_SERVICE );
    }


    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {

        ViewHolder holder;
        View v = convertView;

        if (v == null) {

            v = mLayoutInflater.inflate(R.layout.podcast_list_item, parent, false);

            holder = new ViewHolder();

            holder.title = (TextView)v.findViewById(R.id.title);
            holder.status = (TextView)v.findViewById(R.id.status);
            holder.progressBar = (ProgressBar)v.findViewById(R.id.progress_bar);
            holder.downloadStateBtn = (Button)v.findViewById(R.id.btn_download_state);

            v.setTag(holder);
        } else {
            holder = (ViewHolder) v.getTag();
        }

        holder.downloadStateBtn.setTag(position);

        // TODO set button state according to item state

        holder.downloadStateBtn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

                int position = (Integer) v.getTag();

                    // TODO call DownloadService method (download or pause) according to the state
            }
        });

        //holder.title.setText(getItem(position).getTitle());

        // do a publish progress listener for progress bar

        return v;
    }
} 

下载服务

public class DownloadService extends Service {

    private static final int MAX_DOWNLOAD_TASKS = 10;

    private final IBinder mBinder = new DownloadServiceBinder();

    private class MaxDownloadsException extends Exception
    {

        private static final long serialVersionUID = 6859017750734917253L;

        public MaxDownloadsException()
        {
            super(getResources().getString(R.string.max_downloads));
        }
    }

    private List<DownloadTask> mTaskList= new ArrayList<DownloadTask>();

    private void addTaskToList(DownloadTask task) throws MaxDownloadsException {

        if(mTaskList.size() < MAX_DOWNLOAD_TASKS+1){
            mTaskList.add(task);
        }
        else{
            throw new MaxDownloadsException(); 
        }
    }

    private void removeTaskToList(DownloadTask task) {

        mTaskList.remove(task);

        // if no more tasks, stop service

        if(mTaskList.size() == 0){
            stopSelf();
        }

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        return START_NOT_STICKY;
    }

    /*
     * Binding-related methods
     */

    public class DownloadServiceBinder extends Binder {
        DownloadService getService() {
            return DownloadService.this;
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    public void downLoadFile(long savedShowId){

        new DownloadTask().execute(savedShowId);

    }

    private class DownloadTask extends AsyncTask<Long, Integer, Void> {

        private SavedShow savedShow;

        private int contentLength;

        @Override
        protected Void doInBackground(Long... params) {

            savedShow = MyApplication.dbHelper.getSavedShow(params[0]);

            int contentLength;

            HttpURLConnection connection = null;
            BufferedInputStream in = null;

            try {               

                URL url = new URL(savedShow.getUrl());  

                connection = (HttpURLConnection) url.openConnection();

                long fileLength = new File(getFilesDir(), savedShow.getFilename()).length();

                FileOutputStream outputStream = openFileOutput(savedShow.getFilename(), MODE_PRIVATE | MODE_APPEND);

                int downloaded = 0;             
                contentLength = connection.getContentLength();

                // If there is already a file with that filename,
                // add 'Range' property in header                       

                if(fileLength != 0){
                    connection.setRequestProperty("Range", "bytes=" + fileLength + "-");
                }       

                in = new BufferedInputStream(connection.getInputStream());

                //BufferedOutputStream out = new BufferedOutputStream(outputStream, 1024);

                byte[] data = new byte[1024];
                int x = 0;

                while ((x = in.read(data, 0, 1024)) >= 0) {
                    outputStream.write(data, 0, x);
                    downloaded += x;
                    publishProgress((int) (downloaded));
                }
            } catch (IOException e) {               
                MyApplication.dbHelper.updateSavedShowError(savedShow.getId(), e.toString());

            }
            finally{
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if(connection != null){
                    connection.disconnect();
                }
            }
            return null;        

        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);

            // How can I pass values to SavedShowAdapter's items?
        }

        @Override
        protected void onPostExecute(Void nothing) {
            super.onPostExecute(nothing);

            // TODO remove task

            // How can I notify SavedShowAdapter's items?
        }
    }
}
4

2 回答 2

1

这是我所做的:

  • 要从调用DownloadService方法SavedShowAdapter,我将Service绑定传递SavedShowFragmentSavedShowAdapter

  • 为了得到DownloadService监听器Adapter,我在 中设置了一些BroadcastReceiverSavedShowFragment然后调用SavedShowAdapter修改数据并调用的方法notifyDataSetChanged()

于 2013-07-18T08:43:48.773 回答
0

我看到您已经绑定到该服务。您可以继承默认的活页夹,并在其上实现您喜欢的任何方法,或者创建一个信使并发送消息。两种方法都在 API 指南中进行了探讨,请务必通读并充分了解每种方法的优缺点:

http://developer.android.com/guide/components/bound-services.html

于 2013-07-14T11:05:12.527 回答