ユーザーがいくつかの番組をダウンロードできるラジオアプリケーションを作成しています。
ユーザーがオーディオ プレーヤーのダウンロード ボタンをクリックすると、番組が として DB に追加されSavedShow
ます。
ユーザーは でSavedShow
インスタンスの状態を確認できます。SavedShowsFragment
これListView
には、保存されたショーのリストが表示されます。
の各行にはListView
、保存されたショーのタイトル、その状態 ( NOT_STARTED/DOWNLOADING/PAUSED/DOWNLOADED/ERROR
)、ダウンロードを一時停止、再開、またはダウンロードされている場合はファイルを再生するためのProgressBar
aがあります。Button
リストの各項目を my にバインドする方法も、アダプター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;
}
};
}
保存されたShowAdapter
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?
}
}
}