下载管理器广播接收器并循环浏览列表视图

时间:2014-08-06 06:06:49

标签: android listview

我有一个带有可下载文件列表视图的应用程序。我使用下载管理器来处理多个下载。现在我的问题是我需要更新已完成下载的列表视图行,因此在广播接收器中我会通过列表视图行来查找适当的数据行并更新它但我在列表视图中的第6项中收到Null指针异常。

BroadcastReceiver downloadReceiver = new BroadcastReceiver() {

      @Override
      public void onReceive(Context context, Intent intent) {

       long referenceId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);

        final ListView listView = getListView();
        String[] a = null;

        for (int i = 0; i < listView.getCount(); i++) {
            View v = listView.getChildAt(i);
            TextView et = (TextView) v.findViewById(R.id.dmrefrence);
            Log.d( "position",et.getText().toString() );
            Log.d( "i",Integer.toString(i) );
            if(et.getText().toString() == Long.toString(referenceId) ){

                ImageButton cancelButton = (ImageButton) v.findViewById(R.id.cancelButton);
                cancelButton.setVisibility( View.GONE );
            }

        }

      }
};//end of broadcast reciever

这是我的适配器:

public class LazyAdapter extends BaseAdapter {

private Activity activity;
private ArrayList<HashMap<String, String>> data;
private static LayoutInflater inflater=null;
public ImageLoader imageLoader; 

public LazyAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
    activity = a;
    data=d;
    inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    imageLoader=new ImageLoader(activity.getApplicationContext());
}

public int getCount() {
    return data.size();
}

public Object getItem(int position) {
    return position;
}

public long getItemId(int position) {
    return position;
}

public View getView(int position, View convertView, ViewGroup parent) {
    View vi=convertView;
    if(convertView==null)
        vi = inflater.inflate(R.layout.list_item, null);

    TextView title = (TextView)vi.findViewById(R.id.pid); // title
    final TextView artist = (TextView)vi.findViewById(R.id.name); // artist name
    TextView duration = (TextView)vi.findViewById(R.id.price); // duration
    final TextView fileurl = (TextView)vi.findViewById(R.id.furl); // fileurl
    ImageView thumb_image=(ImageView)vi.findViewById(R.id.image); // thumb image

    final TextView refrenceid = (TextView)vi.findViewById(R.id.dmrefrence); // refrence id

    HashMap<String, String> song = new HashMap<String, String>();
    song = data.get(position);

    // Setting all values in listview
    title.setText(song.get(AllProductsActivity.TAG_PID));
    artist.setText(song.get(AllProductsActivity.TAG_NAME));
    duration.setText(song.get(AllProductsActivity.TAG_PRICE));
    fileurl.setText(song.get(AllProductsActivity.TAG_FILEURL));
    imageLoader.DisplayImage(song.get(AllProductsActivity.TAG_DESCRIPTION), thumb_image);

    final ImageButton pauseButton=(ImageButton)vi.findViewById(R.id.cancelButton); // image button

    final ImageButton imageButton=(ImageButton)vi.findViewById(R.id.imageButton1); // image button
    imageButton.setOnClickListener(new View.OnClickListener() {     
        @Override
        public void onClick(View arg0) {
            // starting background task to download product
            final String dfileurl = fileurl.getText().toString();
            final String fname = artist.getText().toString();

            imageButton.setVisibility( View.GONE );
            pauseButton.setVisibility( View.VISIBLE );
            HomeFragment x = new HomeFragment();
            //x.new DownloadFileFromURL().doInBackground(dfileurl);
            //DownlmActivity x = new DownlmActivity();
            long id = x.myClickdwnl(fname,dfileurl,pauseButton,activity.getApplicationContext());
            refrenceid.setText(Long.toString(id));

            //Log.d("id",Long.toString(id));
       }
    });
    /* Cancel Download */
    pauseButton.setOnClickListener(new View.OnClickListener() {     
        @Override
        public void onClick(View arg0) {
            // starting background task to download product
            final String dnid = refrenceid.getText().toString();
            pauseButton.setVisibility( View.GONE );
            imageButton.setVisibility( View.VISIBLE );
            HomeFragment x = new HomeFragment();

            x.Canceldwnl(dnid,activity.getApplicationContext());

       }
    });

    return vi;
}

}

1 个答案:

答案 0 :(得分:0)

当您开始下载时,您会从以下说明中获得下载ID:

long id = x.myClickdwnl(fname,dfileurl,pauseButton,activity.getApplicationContext());



您需要跟踪哪个下载对应于给定位置(如果有)以及下载完成的项目(行)。为此,请将这2个成员添加到BaseAdapter

/** This associates your download_id to the position of the item in the ListView */
private LongSparseArray<int> downloadIdToPositionMap = new LongSparseArray();

/** This keeps track of the position of item which download is finished */
private ArrayList<Integer> finishedDownloadPositions = new ArrayList<Integer>();


现在位于imageButton OnClickListener中,而不是将download_id存储在TextView(这不是它的目的),您可以将其存储在downloadIdToPositionMap imageButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { // starting background task to download product final String dfileurl = fileurl.getText().toString(); final String fname = artist.getText().toString(); imageButton.setVisibility( View.GONE ); pauseButton.setVisibility( View.VISIBLE ); HomeFragment x = new HomeFragment(); //x.new DownloadFileFromURL().doInBackground(dfileurl); //DownlmActivity x = new DownlmActivity(); long id = x.myClickdwnl(fname,dfileurl,pauseButton,activity.getApplicationContext()); downloadIdToPositionMap.put(id, position); //Log.d("id",Long.toString(id)); } }); 中。 {1}}:

BroadcastReceiver


Adapter,您必须通知您的BaseAdapter下载已完成。您需要在/** * Keep the position of the item associated to the {@code downloadId} in the list of finished downloads * @param downloadId the download unique identifier * @throws IllegalStateException if there is no entry matching {@code downloadId} in {@code this.downloadIdToPositionMap} */ public void setDownloadFinished(long downloadId) throws IllegalStateException{ int position = this.downloadIdToPositionMap.get(downloadId, -1); if(position == -1) throw new IllegalStateException(String.format("Unknown finished download with id = %d", downloadId)); this.finishedDownloadPositions.add(position); } 中添加另一种方法来执行此操作:

BroadcastReceiver


并将您的onReceive() @Override public void onReceive(Context context, Intent intent){ long referenceId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1); final BaseAdapter adapter = getListView().getAdapter(); adapter.setDownloadFinished(referenceId); // Ask the adapter to refresh the ListView adapter.notifyDataSetChanged(); } 方法更改为:

ListView


现在您知道在给定download_id的情况下,完成下载所对应的View项。唯一缺少的是更新行的BaseAdapter。您需要更改getView() @Override public View getView(final int position, View convertView, ViewGroup parent){ View vi = convertView; if(convertView == null) vi = inflater.inflate(R.layout.list_item, null); TextView title = (TextView)vi.findViewById(R.id.pid); // title final TextView artist = (TextView)vi.findViewById(R.id.name); // artist name TextView duration = (TextView)vi.findViewById(R.id.price); // duration final TextView fileurl = (TextView)vi.findViewById(R.id.furl); // fileurl ImageView thumb_image = (ImageView)vi.findViewById(R.id.image); // thumb image final TextView refrenceid = (TextView)vi.findViewById(R.id.dmrefrence); // refrence id HashMap<String, String> song = new HashMap<String, String>(); song = data.get(position); // Setting all values in listview title.setText(song.get(AllProductsActivity.TAG_PID)); artist.setText(song.get(AllProductsActivity.TAG_NAME)); duration.setText(song.get(AllProductsActivity.TAG_PRICE)); fileurl.setText(song.get(AllProductsActivity.TAG_FILEURL)); imageLoader.DisplayImage(song.get(AllProductsActivity.TAG_DESCRIPTION), thumb_image); if(this.isDownloadFinished(position)){ final ImageButton pauseButton=(ImageButton)vi.findViewById(R.id.cancelButton); // image button final ImageButton imageButton=(ImageButton)vi.findViewById(R.id.imageButton1); // image button imageButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { // starting background task to download product final String dfileurl = fileurl.getText().toString(); final String fname = artist.getText().toString(); imageButton.setVisibility( View.GONE ); pauseButton.setVisibility( View.VISIBLE ); HomeFragment x = new HomeFragment(); //x.new DownloadFileFromURL().doInBackground(dfileurl); //DownlmActivity x = new DownlmActivity(); long id = x.myClickdwnl(fname,dfileurl,pauseButton,activity.getApplicationContext()); refrenceid.setText(Long.toString(id)); downloadIdToPositionMap.put(id, position); //Log.d("id",Long.toString(id)); } }); /* Cancel Download */ pauseButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { // starting background task to download product final String dnid = refrenceid.getText().toString(); pauseButton.setVisibility( View.GONE ); imageButton.setVisibility( View.VISIBLE ); HomeFragment x = new HomeFragment(); x.Canceldwnl(dnid,activity.getApplicationContext()); } }); } return vi; } 方法:

BaseAdapter



最后,添加此方法(到/** * Return wether the given position corresponds to an item which download is finished * @param position the position of the item * @return {@code true} if the download associated with the item at position is finished, {@code false} otherwise */ private boolean isDownloadFinished(int position){ return this.finishedDownloadPositions.contains(position); } )以检查下载是否已完成,给定位置:

getItem()

<小时/> 请注意,我还没有对代码进行测试,因此可能包含一些错误,但如果你掌握了逻辑,你应该可以修复它们。

另一方面,您在ListView方法中做得太多了。请记住,当您滚动OnClickListener时,每次项目可见时都会调用它。为避免滞后,您应考虑实施ViewHolder pattern

同时避免对pauseButton.setOnClickListener(new View.OnClickListener() {// Stripped method body for readability});使用匿名声明。 在您的代码中,OnClickListener会为ListView中的每个可见项创建一个新的BaseAdapter。你可以通过将你的听众定义为private View.OnClickListener pauseListener = new new View.OnClickListener() { @Override public void onClick(View arg0) { // Stripped method body for readability } }); public View getView(int position, View convertView, ViewGroup parent) { // Stripped method body for readability pauseButton.setOnClickListener(this.pauseListener); } 中的新成员来避免这种情况:

{{1}}