我开发了一款能够检测BLE信号和其他参数的应用程序。我使用BaseAdapter开发ListView来显示每个项目。问题是我想在扫描完成后(在我建立一段时间后)将这些数据保存在xml文件中,但我不知道该怎么做。
在这个课程中,我会对BLE进行扫描,并且是我想要在扫描时间过后保存List的过程:
public class ScanBleActivity extends ScanBaseActivity {
private BluetoothAdapter mBluetoothAdapter;
private boolean mScanning;
private Handler mHandler = new Handler();
//private List<BluetoothDevice> mydata;
// Stops scanning after 10 seconds.
private static final long SCAN_PERIOD = 20000;
/* (non-Javadoc)
* @see com.zishao.bletest.ScanBaseActivity#initScanBluetooth()
*/
protected void initScanBluetooth() {
BluetoothManager manager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = manager.getAdapter();
startScanLen(true);
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mScanning) {
startScanLen(false);
}
}
/**
*
* @param enable
*/
private void startScanLen(final boolean enable) {
if (enable) {
// Stops scanning after a pre-defined scan period.
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
try {
savedata(true);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, SCAN_PERIOD);
mScanning = true;
mBluetoothAdapter.startLeScan(mLeScanCallback);
} else {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
}
这是我的适配器:
public class LeDeviceListAdapter extends BaseAdapter {
public List<BluetoothDevice> data;
private Activity context;
private final HashMap<BluetoothDevice, Integer> rssiMap = new HashMap<BluetoothDevice, Integer>();
public LeDeviceListAdapter(Activity context, List<BluetoothDevice> data) {
this.data = data;
this.context = context;
}
//public static List<BluetoothDevice> getAllData() {
// return data;
//}
public synchronized void addDevice(BluetoothDevice device, int rssi) {
if(!data.contains(device) ){
data.add(device);
}
rssiMap.put(device, rssi);
}
@Override
public int getCount() {
return data.size();
}
@Override
public Object getItem(int position) {
return data.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (null == convertView) {
LayoutInflater mInflater =
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.leaf_devices_list_item, null);
convertView.setTag(new DeviceView(convertView));
}
DeviceView view = (DeviceView) convertView.getTag();
view.init((BluetoothDevice) getItem(position));
return convertView;
}
public class DeviceView {
private TextView title;
private TextView status;
private TextView type;
private TextView address;
private TextView rssivalue;
public DeviceView(View view) {
title = (TextView) view.findViewById(R.id.device_name);
status = (TextView) view.findViewById(R.id.device_status_txt);
type = (TextView) view.findViewById(R.id.device_type_txt);
address = (TextView) view.findViewById(R.id.device_address_txt);
rssivalue = (TextView) view.findViewById(id.signal_intensity_txt);
}
public void init(BluetoothDevice device) {
title.setText(device.getName());
address.setText(device.getAddress());
setType(device.getType());
setStatus(device.getBondState());
rssivalue.setText(""+rssiMap.get(device)+" dBm");
}
public void setType(int status) {
switch(status) {
case BluetoothDevice.DEVICE_TYPE_CLASSIC:
type.setText("Bluetooth Signal");
break;
case BluetoothDevice.DEVICE_TYPE_LE:
type.setText("BLE Signal");
break;
case BluetoothDevice.DEVICE_TYPE_DUAL:
type.setText("Dual Mode - BR/EDR/LE");
break;
case BluetoothDevice.DEVICE_TYPE_UNKNOWN:
type.setText("Device Unknown");
break;
}
}
public void setStatus(int s) {
switch(s) {
case BluetoothDevice.BOND_NONE:
status.setText("Not Bonded");
break;
case BluetoothDevice.BOND_BONDED:
status.setText("Bonded");
break;
case BluetoothDevice.BOND_BONDING:
status.setText("Bonding");
break;
}
}
}
我想保存扫描期间找到的每个BLE信号的标题,地址,类型,状态和rssivalue(如上面的代码所示),以保存在xml文件中。我只提供了项目的一部分,但如果有必要,我将编辑并放置缺少的代码。
有谁知道怎么做?请帮忙!!!!!
新代码:这对应于ScanBaseActivity类:
abstract public class ScanBaseActivity extends ListActivity {
protected LeDeviceListAdapter mLeDeviceListAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_devices_scan);
mLeDeviceListAdapter = new LeDeviceListAdapter(this, new ArrayList<BluetoothDevice>());
this.setListAdapter(mLeDeviceListAdapter);
initScanBluetooth();
}
/**
* Start Scan Bluetooth
*
*/
abstract protected void initScanBluetooth();
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
BluetoothDevice device = (BluetoothDevice) mLeDeviceListAdapter.getItem(position);
ParcelUuid[] uuids = device.getUuids();
String uuidString = "Getting UUID's from " + device.getName() + ";UUID:";
if (null != uuids && uuids.length > 0) {
uuidString += uuids[0].getUuid().toString();
} else {
uuidString += "empty";
}
Toast.makeText(this, uuidString, Toast.LENGTH_LONG).show();
}
/**
* @param device
*/
protected synchronized void addDevice(final BluetoothDevice device, final int rssi) {
runOnUiThread(new Runnable() {
@Override
public void run() {
mLeDeviceListAdapter.addDevice(device, rssi);
mLeDeviceListAdapter.notifyDataSetChanged();
}
});
}
protected void savedata(boolean enable) throws FileNotFoundException{
String filename = "file.txt";
FileOutputStream fos;
Bundle extras = getIntent().getExtras();
long timestamp = extras.getLong("currentTime");
try {
fos= openFileOutput(filename, Context.MODE_PRIVATE);
ObjectOutputStream out = new ObjectOutputStream(fos);
out.write((int) timestamp);
out.writeObject(mLeDeviceListAdapter);
out.write(null);
out.close();
Toast.makeText(this, R.string.list_saved, Toast.LENGTH_SHORT).show();
savedata(false);
} catch (FileNotFoundException e){
e.printStackTrace();
} catch (IOException e){
e.printStackTrace();
}
}
}
新!!:我已经编辑了ScanBaseActivity和ScanBleActivity来引入xml保存但是当我运行应用程序时,当扫描停止时会导致错误(列表必须保存在sml文件中的时刻)。有谁知道如何解决或纠正它?!!!
答案 0 :(得分:0)
嗯,并不是说你要从适配器中保存它,而是adater将“调整”你将放入首选项的数据集。
作为一个领域:
private SharedPreferences saveHash;
在onCreate中:
saveHash = getSharedPreferences( getString( R.string.save_hash ), MODE_PRIVATE );
然后:
public void onFinishedLoading(){
super.onPause();
SharedPreferences.Editor editor = saveHash.edit();
editor.clear();
for( String s: myData){
editor.putString(x, s);
}
editor.commit();
}
编辑:意识到你想从列表中创建哈希;你想要什么作为关键?
答案 1 :(得分:0)
好的,首先,您需要重新调整处理适配器的方式,之后,一切都应该落实到位。
所以为此,我将外包给vogella,这是好的Android设计模式的基础 http://www.vogella.com/tutorials/AndroidListView/article.html
你可以通过第3部分阅读,吃一些copypasta并回到这里,但你每次额外的行都是好事=]
现在你有一个包含数据列表的活动,以及一个接受该列表的适配器 - 与你的代码相比有些愚蠢 - 将它应用于某种类型的视图。当您想要更新该数据时,可以通过某个获取Bluetooth设备列表的方法修改 activity 中的List对象来实现 - 我将使用AsyncTask将该过程从线程中移除
由于您将List传递给适配器,因此您可以等到活动中填充数据,然后执行adapter.notifyDataSetChanged。你不想要adapter.add
然后你在活动中有一个很好的数据列表;你不需要担心它是否是正确的列表,因为 - 鉴于更新模式 - 它是唯一的列表!
然后按照Merleverde发布的链接将该数据序列化为xml,可能在实用程序类中,但在您的活动中没问题。
编辑: 这是一个非常好的适配器,这是显示动态变化数据的较大模式的一部分:
public class AnchorListAdapter extends ArrayAdapter<String>
{
private final List<String> anchorNames;
public AnchorListAdapter(Context context, int textviewId, List<String> anchors){
super(context, textviewId, anchors);
anchorNames = anchors;
}
@Override
public String getItem( int i ) {
return anchorNames.get(i).toString();
}
}