0

5秒ごとにWiFiの状態を更新するアプリを作成しました。これが主なアクティビティです

public class WiFiList extends Activity {
/** Called when the activity is first created. */

private String screen;
private ListView nets;
private WifiManager wifi;
private NetAdapter nAdap;
SharedPreferences getPrefs;
Updater skaner;
List<ScanResult> scan;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getPrefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
    String screen = getPrefs.getString("start", "list");
    wifi = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
    if(screen.equals("list")){
        setContentView(R.layout.main);
        nets = (ListView) findViewById(R.id.lvNets);
        wifi.startScan();
        scan = new ArrayList<ScanResult>();
        nAdap = new NetAdapter(getApplicationContext(), scan);
        nets.setAdapter(nAdap);
        nAdap.notifyDataSetChanged();
    }
    skaner = new Updater();
    skaner.execute();
}

public void refresh(){
    nAdap.notifyDataSetChanged();
}

class Updater extends AsyncTask<Void, Void, Void>{
    @Override
    protected Void doInBackground(Void... params) {
       // doSomething();
        while(wifi.isWifiEnabled()){
            int waiter = getPrefs.getInt("intervals", 5) * 1000;
            wifi.startScan();
            scan = wifi.getScanResults();
            publishProgress();
            try {
                Thread.sleep(waiter);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            if(isCancelled()){
                break;
            }
        }
        return null;
    }

    @Override
    protected void onProgressUpdate(Void... values) {
        // TODO Auto-generated method stub
        super.onProgressUpdate(values);
        refresh();
    }
}

@Override
public void onBackPressed() {
    // TODO Auto-generated method stub
    skaner.cancel(true);
    super.onBackPressed();
}

ただし、ListViewは更新されません。デバッガーを実行すると、それrefresh()が呼び出され、リストの値が毎回異なることがわかります。何がそれをリフレッシュするのを妨げますか?でネットワークをスキャンonCreate()すると、リストに表示されるので、アダプターは正しいと思いますが、とにかくコードは次のとおりです。

public class NetAdapter extends BaseAdapter{

private LayoutInflater mInflater;
List<ScanResult> res;

public NetAdapter(Context context, List<ScanResult> l){
    mInflater = LayoutInflater.from(context);
    res = l;
}

@Override
public int getCount() {
    // TODO Auto-generated method stub
    return res.size();
}

@Override
public Object getItem(int arg0) {
    // TODO Auto-generated method stub
    return res.get(arg0);
}

@Override
public long getItemId(int arg0) {
    // TODO Auto-generated method stub
    return arg0;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // TODO Auto-generated method stub
    ViewHolder holder;
    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.netitem, null);
        holder = new ViewHolder();
        holder.tvName = (TextView) convertView.findViewById(R.id.tvName);
        holder.tvFreq = (TextView) convertView.findViewById(R.id.tvFreq);
        holder.tvRssi = (TextView) convertView.findViewById(R.id.tvRssi);
        holder.ivState = (ImageView) convertView.findViewById(R.id.ivSignal);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }   
    holder.tvName.setText(res.get(position).SSID +" (" + res.get(position).BSSID + ")");
    holder.tvFreq.setText(Integer.toString(res.get(position).frequency)+"MHz");
    holder.tvRssi.setText(Integer.toString(res.get(position).level)+"dBm");
    holder.ivState.setImageResource(R.drawable.ic_launcher);
    return convertView;
}

static class ViewHolder{
    TextView tvName;
    TextView tvFreq;
    TextView tvRssi;
    ImageView ivState;
}
4

3 に答える 3

0

startScan()すぐに返され、結果が利用可能になると、結果の可用性が非同期的に通知されることに注意してください。したがって、結果の呼び出しの直後にスキャン結果を読み取ると、startscan()そこにない可能性が高いため、アダプターに空白の情報を送信しています。

したがって、これは、ビューが更新されない理由をカバーしています。では、結果が利用可能な場合にのみ結果を読み取るようにするにはどうすればよいでしょうか。以下の推奨事項を参照してください。

BroadcastReceiverを使用してスキャン結果を受信することをお勧めします。登録しますSCAN_RESULTS_AVAILABLE_ACTION

したがって、非同期でスキャンを実行しますが、そこから更新は行わず、ループを実行し続けるために使用します。必要に応じて、そのためのスレッドだけを使用することもできます。

更新するには、受信者からスキャン結果を読み取るアクティビティにコールバックするだけです。

また、非同期タスクを作成して同じことを再度実行した直後に、あなたが電話startscan()をかけてきたことにも気づきました。onCreateそれをする意味は何ですか。

于 2012-06-08T10:14:54.267 に答える
0

あなたの問題を正しく理解していれば。

前提: 1.アダプターの値を更新している

解決:

リスト ビューを更新するには、次の手順を実行する必要があります。

your_list_adapter.notifyDataSetChanged();

これが役立つことを願っています..

于 2012-06-08T12:33:19.737 に答える
0

List ビューを更新するには、以下の AsyncTask メソッドを使用する必要があります。

protected void onPostExecute(Long result) {
         showDialog("Downloaded " + result + " bytes");
     }
于 2012-06-08T09:56:25.270 に答える