<span style="font-family: Arial, Helvetica, sans-serif;">一:进来Settings之后因为是shardprefrence的控件每一个是一个fragment所以它没有把点击事件写在蓝牙界面而写在了主界面上,进入蓝牙界面会点击左软件,进入一个新的界面流程是:</span>
public boolean dispatchKeyEvent(KeyEvent event) {
// TODO Auto-generated method stub
if((select == 3)&&(event.getKeyCode() == 1)&&(BluetoothSettings.bluetooth_key_lsk)
&&((mLocalAdapter.getBluetoothState() == BluetoothAdapter.STATE_ON))){
Intent iintent = new Intent("settings.bluetooth.RadgerWheelActivity");
startActivity(iintent);
return true;
}
if(event.getKeyCode() == 1){
return true;
}
return super.dispatchKeyEvent(event);
}
二:分析RadgerWheelActivity,也就是这个新的界面
直接定位OnCreate( )方法setContentView(R.layout.main);
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="@+id/linearLayout"
android:visibility="gone">
<TextView
android:id="@+id/conncet"
android:layout_width="match_parent"
android:layout_height="35sp"
android:layout_margin="6sp"
android:textSize="20sp"
/>
<TextView
android:id="@+id/conncet_address"
android:layout_width="match_parent"
android:layout_height="35sp"
android:layout_margin="6sp"
android:textSize="15sp"
/>
</LinearLayout>
<ListView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/list">
</ListView>
</LinearLayout>
就是说有2个布局第一个布局是2个TextView,下面的布局是一个listView,而且第一个是隐藏的显示不可见的。
VISIBLE:0 意思是可见的
INVISIBILITY:4 意思是不可见的,但还占着原来的空间
GONE:8 意思是不可见的,不占用原来的布局空间</p>
getActionBar().setTitle(R.string.title_devices);------------------------------------------------------最上面的导航条上设置内容为BLE Device Scan
mHandler = new Handler();----------------------------------------------------------------------一个handler对象
mListView = (ListView)findViewById(R.id.list);-----------------------------------------实例化listView对象
conncet = (TextView)findViewById(R.id.conncet);----------------------------------------实例化第一个TextView的connect
linearLayout = (LinearLayout)findViewById(R.id.linearLayout);--------------------------实例化隐藏的linearLayout
conncet_address = (TextView)findViewById(R.id.conncet_address);------------------------实例化第二个TextView的connect_address
sharedpreferences=getSharedPreferences(saveInfo, MODE);------------------------->SharedPreferences是以键值对来存储应用程序的配置信息的一种方式,它只能存储基本数据类型。一个程序的配置文件仅可以在本应用程序中使用,或者说只能在同一个包内使用,不能在不同的包之间使用。 实际上SharedPreferences是采用了XML格式将数据存储到设备中,在DDMS中的File Explorer中的/data/data/<package name>/shares_prefs下。为本组件的配置文件名(如果想要与本应用程序的其他组件共享此配置文件,可以用这个名字来检索到这个配置文件)。如果要读取配置文件信息,只需要直接使用SharedPreferences对象的getXXX()方法即可,而如果要写入配置信息,则必须先调用SharedPreferences对象的edit()方法,使其处于可编辑状态,然后再调用putXXX()方法写入配置信息,最后调用commit()方法提交更改后的配置文件。为操作模式,默认的模式为0或MODE_PRIVATE,还可以使用MODE_WORLD_READABLE和MODE_WORLD_WRITEABLE。</p> editor=sharedpreferences.edit();
linearLayout.setFocusable(true);
linearLayout.setBackgroundResource(R.drawable.item_background);
<span style="font-family: Arial, Helvetica, sans-serif;">---------------------------------------------------------------------------------------------------------------------------------------------------------MODE=0是默认的,name=saveInfo</span></span>
这个是隐藏的linearLayout
linearLayout.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
---------------------------------------------------------------------------------------------------------------------------------mScanning默认是false,但这个条件是true的时候才执行
if (mScanning) {
mBluetoothAdapter.stopLeScan(mLeScanCallback);---------------------------------------------------------应该是停止扫描设备(里面传的值是?)
mScanning = false;
}
//mmHandler_delayed.sendEmptyMessageDelayed(0,2000);
//final Intent iintent = new Intent(RadgerWheelActivity.this,BluetoothCODAService.class);
//stopService(iintent);
final Intent iintent = new Intent("BluetoothDisconnect");
sendBroadcast(iintent);
---------------------------------------------------------------------------------------------------------------------------------点击的时候发送一个广播
editor.putString("RadgerWheel_Connect_Address", "null");
editor.putString("RadgerWheel_Connect_Address_old", "null");
editor.commit();
mListView.setEnabled(true);
--------------------------------------------------------------------------------------------------------------------------------保存值,listView设置可以编辑状态
final Intent mintent = new Intent("com.android.intent.action.bluetooth.state");
mintent.putExtra("state", 1);
sendBroadcast(mintent);
--------------------------------------------------------------------------------------------------------------------------------再次发送一个广播
}
});
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
//Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
finish();
}
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
---------------------------------------------------------------------------------------------------------------------------------------------------------------------通过服务拿到manager对象,通过manager对象拿到blutetoothAdapter对象
// Checks if Bluetooth is supported on the device.
if (mBluetoothAdapter == null) {
//Toast.makeText(this, R.string.error_bluetooth_not_supported, Toast.LENGTH_SHORT).show();
finish();
return;
}
<span style="font-family: Arial, Helvetica, sans-serif;">--------------------------------------------------------------------------------------------------------------------------------------------------------------------------是空就finish</span></span>
mListView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View v, int count,
long arg3) {
final BluetoothDevice device = mLeDeviceListAdapter.getDevice((int)arg3);
if (device == null) return;
if (mScanning) {
mBluetoothAdapter.stopLeScan(mLeScanCallback);
mScanning = false;
invalidateOptionsMenu();
}
String address=sharedpreferences.getString("RadgerWheel_Connect_Address","null");
if(!(address.equals("null"))){
return;
}
mListView.setEnabled(false);
conncet_address.setEnabled(false);
//mHandler_delayed.sendEmptyMessageDelayed(0,2000);
//TextView text = (TextView)v.findViewById(R.id.tv2);
//editor.putString("RadgerWheel_Connect_Address", mBluetoothDevice.getAddress());
//editor.putString("RadgerWheel_Connect_Address_old", device.getAddress());
//editor.commit();
//final Intent iintent = new Intent(RadgerWheelActivity.this,BluetoothCODAService.class);
final Intent iintent = new Intent("BluetoothConnect");
Bundle bundle = new Bundle();
bundle.putParcelable("BlutoothDevice", device);
iintent.putExtras(bundle);
sendBroadcast(iintent);
//text.setText(R.string.connected);
mLeDeviceListAdapter.deleteDevice(device);
mLeDeviceListAdapter.notifyDataSetChanged();
linearLayout.setVisibility(0);
conncet.setText(device.getAddress());
conncet_address.setText(R.string.connected);
}
});
}
总结:设置最上面标题,实例化每一个控件,获取键值,给隐藏的linearLayout设置点击事件,拿到blutetoothAdapter对象,给listView设置点击事件,因为点击事件是onresume()里面实例化了再点击也行不用非得在oncreate中实例化
三:定位到onResume()方法中</span>
protected void onResume() {
super.onResume();
// Ensures Bluetooth is enabled on the device. If Bluetooth is not currently enabled,
// fire an intent to display a dialog asking the user to grant permission to enable it.
if (!mBluetoothAdapter.isEnabled()) {
if (!mBluetoothAdapter.isEnabled()) {
//Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
//startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
finish();
}
}
// Initializes list view adapter.
mLeDeviceListAdapter = new LeDeviceListAdapter();--------------------------------------------------------------------设置适配器
mListView.setAdapter(mLeDeviceListAdapter);--------------------------------------------------------------------------
mac_address=sharedpreferences.getString("RadgerWheel_Connect_Address","null");
scanLeDevice(true);
Handler_delayed.sendEmptyMessage(0);
}
private void scanLeDevice(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);
invalidateOptionsMenu();
}
}, SCAN_PERIOD);
mScanning = true;
final Intent iintent = new Intent("BluetoothScan");
sendBroadcast(iintent);
mBluetoothAdapter.startLeScan(mLeScanCallback);
} else {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
invalidateOptionsMenu();
四:现在分析一下原理流程:
--进来进入OnResume()然后走一遍流程
--1:if (!mBluetoothAdapter.isEnabled()) 蓝牙适配器是不可编辑的时候finish();
--2:否则的话:
-------mLeDeviceListAdapter = new LeDeviceListAdapter();
mListView.setAdapter(mLeDeviceListAdapter);给listView设置适配器---------------------------------一会分析适配器的内容
---3:scanLeDevice(true);扫描那个设备
private void scanLeDevice(final boolean enable) {
if (enable) {
// Stops scanning after a pre-defined scan period.
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mScanning = false;
Log.d("lwn","zhaohaiyun stop scan 1....");
mBluetoothAdapter.stopLeScan(mLeScanCallback);
invalidateOptionsMenu();
}
}, SCAN_PERIOD);
//handler.postDelayed(runnable, 2000);就是一个定时的功能这个的意思是2秒定时后执行runnable,--------------------------------------------------------------------------这个的功能就是一进来走下面的发送广播,查询那个设备,一会分析那个设备。10秒之后走runnable方法就是停止查询这个设备
mScanning = true;
Log.d("lwn","zhaohaiyun start scan....");
final Intent iintent = new Intent("BluetoothScan");
sendBroadcast(iintent);
mBluetoothAdapter.startLeScan(mLeScanCallback);
} else {
mScanning = false;
Log.d(TAG,"zhaohaiyun stop scan 2....");
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
invalidateOptionsMenu();
--------------------------------------------------------------------------------------------------------------------------------------
----4:Handler_delayed.sendEmptyMessage(0);发送一个消息,没有延迟的发送0是这个消息的ID,其实是循环来更新1秒的时间循环来
private Handler Handler_delayed = new Handler() {
@Override
public void handleMessage(Message msg) {
mac_address=sharedpreferences.getString("RadgerWheel_Connect_Address","null");
if(!(mac_address.equals("null"))){
linearLayout.setVisibility(0);//显示这个布局
conncet.setText(mac_address);
conncet_address.setText(R.string.connected);
}else{
linearLayout.setVisibility(8);//这个布局隐藏了
mListView.setEnabled(true);
}
sendEmptyMessageDelayed(0,1000);//给自己延迟1秒来发送消息-----------------------------
}
};
---总结-综合下来就是一进入resume()方法:给listView设置适配器,然后扫描那个设备,10秒的时间,先走发送广播,这个广播就是重点,蓝牙适配器来查询mLeScanCallback这个设备,10秒之后就停止查询。然后就是每1秒给自己发送消息一次(用来处理listView可编辑,或设置Text)