他用了四個imagebutton
private ImageButton mimageButton1;//upprivate ImageButton mimageButton2;//downprivate ImageButton mimageButton3;//rightprivate ImageButton mimageButton4;//left
代表上面那四個button
先來看 onCreate()
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if(D) Log.e(TAG, "+++ ON CREATE +++"); // Set up the window layout requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); setContentView(R.layout.main); getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_title); // Set up the custom title mTitle = (TextView) findViewById(R.id.title_left_text); mTitle.setText(R.string.app_name); mTitle = (TextView) findViewById(R.id.title_right_text); // Get local Bluetooth adapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); // If the adapter is null, then Bluetooth is not supported if (mBluetoothAdapter == null) { Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).show(); finish(); return; } mimageButton1 = (ImageButton)findViewById(R.id.imageButton1); //up mimageButton2 = (ImageButton)findViewById(R.id.imageButton2); //down mimageButton3 = (ImageButton)findViewById(R.id.imageButton3); //right mimageButton4 = (ImageButton)findViewById(R.id.imageButton4); //left
// set listener 的function... 就是把 Init_send_val 設成相對的value mimageButton1.setOnTouchListener(new ImageButton.OnTouchListener(){ @Override public boolean onTouch(View v, MotionEvent event) { if(event.getAction() == MotionEvent.ACTION_DOWN){ Init_send_val = KEY_UP ; Log.v(TAG,"User press the button"); }else if(event.getAction() == MotionEvent.ACTION_UP){ Init_send_val = KEY_NOTHING; Log.v(TAG,"User release the button"); } return false; } }); mimageButton2.setOnTouchListener(new ImageButton.OnTouchListener(){ @Override public boolean onTouch(View v, MotionEvent event) { if(event.getAction() == MotionEvent.ACTION_DOWN){ Init_send_val = KEY_DOWN ; Log.v(TAG,"User press the button"); }else if(event.getAction() == MotionEvent.ACTION_UP){ Init_send_val = KEY_NOTHING; Log.v(TAG,"User release the button"); } return false; } }); mimageButton3.setOnTouchListener(new ImageButton.OnTouchListener(){ @Override public boolean onTouch(View v, MotionEvent event) { if(event.getAction() == MotionEvent.ACTION_DOWN){ Init_send_val = KEY_RIGHT ; Log.v(TAG,"User press the button"); }else if(event.getAction() == MotionEvent.ACTION_UP){ Init_send_val = KEY_NOTHING; Log.v(TAG,"User release the button"); } return false; } }); mimageButton4.setOnTouchListener(new ImageButton.OnTouchListener(){ @Override public boolean onTouch(View v, MotionEvent event) { if(event.getAction() == MotionEvent.ACTION_DOWN){ Init_send_val = KEY_LEFT ; Log.v(TAG,"User press the button"); }else if(event.getAction() == MotionEvent.ACTION_UP){ Init_send_val = KEY_NOTHING; Log.v(TAG,"User release the button"); } return false; } }); 然後在onResume() 的時候...去判斷 mChatService是不是null..
如果是null... 就呼叫mChatService.start();
@Overridepublic synchronized void onResume() { super.onResume(); if(D) Log.e(TAG, "+ ON RESUME +"); // Performing this check in onResume() covers the case in which BT was // not enabled during onStart(), so we were paused to enable it... // onResume() will be called when ACTION_REQUEST_ENABLE activity returns. if (mChatService != null) { // Only if the state is STATE_NONE, do we know that we haven't started already if (mChatService.getState() == BluetoothChatService.STATE_NONE) { // Start the Bluetooth chat services mChatService.start(); } } }start()的實作如下:啟動了 mSecureAcceptThread 和 mInsecureAcceptThread 這兩種 AcceptThread 的threadpublic synchronized void start() { if (D) Log.d(TAG, "start"); // Cancel any thread attempting to make a connection if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;} // Cancel any thread currently running a connection if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;} setState(STATE_LISTEN); // Start the thread to listen on a BluetoothServerSocket if (mSecureAcceptThread == null) { mSecureAcceptThread = new AcceptThread(true); mSecureAcceptThread.start(); } if (mInsecureAcceptThread == null) { mInsecureAcceptThread = new AcceptThread(false); mInsecureAcceptThread.start(); } }宣告一個執行緒 mHandlerTime.removeCallbacks(car_timer); mHandlerTime.postDelayed(car_timer, 400); }
car_timer 的實作如下
其實就是定期的去check mChatService.getState()
如果已經連線....就把 Init_send_val 的 value 送出去...
透過 mChatService.write(send);
然後每400ms 執行一次 mHandlerTime.postDelayed(this, 400);
private final Runnable car_timer = new Runnable() { public void run() { if (mChatService.getState() == BluetoothChatService.STATE_CONNECTED) { if(Init_send_val == KEY_NOTHING) { // Get the message bytes and tell the BluetoothChatService to write byte[] send = new byte[] {(byte) 0xAA, (byte) 0xBB, 0x02, 0x00,0x02}; mChatService.write(send); // Reset out string buffer to zero and clear the edit text field mOutStringBuffer.setLength(0); } else if(Init_send_val == KEY_UP ) { // Get the message bytes and tell the BluetoothChatService to write byte[] send = new byte[] {(byte) 0xAA, (byte) 0xBB, 0x02, (byte) 0xF1, 0x03}; mChatService.write(send); // Reset out string buffer to zero and clear the edit text field mOutStringBuffer.setLength(0); } else if(Init_send_val== KEY_DOWN ) { // Get the message bytes and tell the BluetoothChatService to write byte[] send = new byte[] {(byte) 0xAA, (byte) 0xBB, 0x02, (byte) 0xF2, 0x00}; mChatService.write(send); // Reset out string buffer to zero and clear the edit text field mOutStringBuffer.setLength(0); } else if(Init_send_val == KEY_RIGHT ) { // Get the message bytes and tell the BluetoothChatService to write byte[] send = new byte[] {(byte) 0xAA, (byte) 0xBB, 0x02, (byte) 0xF4, 0x06}; mChatService.write(send); // Reset out string buffer to zero and clear the edit text field mOutStringBuffer.setLength(0); } else if(Init_send_val == KEY_LEFT ) { // Get the message bytes and tell the BluetoothChatService to write byte[] send = new byte[] {(byte) 0xAA, (byte) 0xBB, 0x02, (byte) 0xF8, 0x0A}; mChatService.write(send); // Reset out string buffer to zero and clear the edit text field mOutStringBuffer.setLength(0); } } mHandlerTime.postDelayed(this, 400); } };
當按下menu ...就會執行下面的code
@Overridepublic boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.option_menu, menu); return true; }
這個會去讀 menu/option_menu.xml
裡面的內容如下: 就是上面那3個 item....
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/secure_connect_scan" android:icon="@android:drawable/ic_menu_search" android:title="@string/secure_connect" /> <item android:id="@+id/insecure_connect_scan" android:icon="@android:drawable/ic_menu_search" android:title="@string/insecure_connect" /> <item android:id="@+id/discoverable" android:icon="@android:drawable/ic_menu_mylocation" android:title="@string/discoverable" /> </menu>
// 就是上面螢幕顯示的3個 item....
@Overridepublic boolean onOptionsItemSelected(MenuItem item) { Intent serverIntent = null; switch (item.getItemId()) { case R.id.secure_connect_scan: // Launch the DeviceListActivity to see devices and do scan serverIntent = new Intent(this, DeviceListActivity.class); startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE_SECURE); return true; case R.id.insecure_connect_scan: // Launch the DeviceListActivity to see devices and do scan serverIntent = new Intent(this, DeviceListActivity.class); startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE_INSECURE); return true; case R.id.discoverable: // Ensure this device is discoverable by others ensureDiscoverable(); return true; } return false; }
這時候如果我們按下 secure_connect_scan...
就會去執行 DeviceListActivity 這個class
先來看onCreate()
// Member fieldsprivate BluetoothAdapter mBtAdapter;
這裡分兩個 ArayAdapter...
一個還沒有配對的.... 一個是已經配對的...
private ArrayAdapter<String> mPairedDevicesArrayAdapter; private ArrayAdapter<String> mNewDevicesArrayAdapter;
@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Setup the window requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); setContentView(R.layout.device_list); // Set result CANCELED incase the user backs out setResult(Activity.RESULT_CANCELED); // Initialize the button to perform device discovery Button scanButton = (Button) findViewById(R.id.button_scan); scanButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { doDiscovery(); v.setVisibility(View.GONE); } }); // Initialize array adapters. One for already paired devices and // one for newly discovered devices mPairedDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name); mNewDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name); // Find and set up the ListView for paired devices ListView pairedListView = (ListView) findViewById(R.id.paired_devices); pairedListView.setAdapter(mPairedDevicesArrayAdapter); pairedListView.setOnItemClickListener(mDeviceClickListener); // Find and set up the ListView for newly discovered devices ListView newDevicesListView = (ListView) findViewById(R.id.new_devices); newDevicesListView.setAdapter(mNewDevicesArrayAdapter); newDevicesListView.setOnItemClickListener(mDeviceClickListener); // Register for broadcasts when a device is discovered IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); this.registerReceiver(mReceiver, filter); // Register for broadcasts when discovery has finished filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); this.registerReceiver(mReceiver, filter); // Get the local Bluetooth adapter mBtAdapter = BluetoothAdapter.getDefaultAdapter(); // Get a set of currently paired devices Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices(); // If there are paired devices, add each one to the ArrayAdapter if (pairedDevices.size() > 0) { findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE); for (BluetoothDevice device : pairedDevices) { mPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress()); } } else { String noDevices = getResources().getText(R.string.none_paired).toString(); mPairedDevicesArrayAdapter.add(noDevices); } }
可以看到上面的畫面
從 layout/device_list.xml
其實就是用一個垂直的LinearLayout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:id="@+id/title_paired_devices" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/title_paired_devices" android:visibility="gone" android:background="#666" android:textColor="#fff" android:paddingLeft="5dp" /> <ListView android:id="@+id/paired_devices" android:layout_width="match_parent" android:layout_height="wrap_content" android:stackFromBottom="true" android:layout_weight="1" /> <TextView android:id="@+id/title_new_devices" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/title_other_devices" android:visibility="gone" android:background="#666" android:textColor="#fff" android:paddingLeft="5dp" /> <ListView android:id="@+id/new_devices" android:layout_width="match_parent" android:layout_height="wrap_content" android:stackFromBottom="true" android:layout_weight="2" /> <Button android:id="@+id/button_scan" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/button_scan" />
從這個 xml 可以看出
Paired Device 是 TextView
下面就是接一個Listview.... 會把所有掃到的blue-tooth 列出來
然後再一個 TextView ...秀出 "Other Available Devices"
下面就是接一個Listview.... 會把所有掃到的其他的已經有的blue-tooth 列出來
最後再一個button... 去scan device
這個button 的執行程式如下:
Button scanButton = (Button) findViewById(R.id.button_scan); scanButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { doDiscovery(); v.setVisibility(View.GONE); } });
會呼叫 doDiscovery()... 會呼叫一個progressbar()
最後會呼叫
mBtAdapter.startDiscovery();
private void doDiscovery() { if (D) Log.d(TAG, "doDiscovery()"); // Indicate scanning in the title setProgressBarIndeterminateVisibility(true); setTitle(R.string.scanning); // Turn on sub-title for new devices findViewById(R.id.title_new_devices).setVisibility(View.VISIBLE); // If we're already discovering, stop it if (mBtAdapter.isDiscovering()) { mBtAdapter.cancelDiscovery(); } // Request discover from BluetoothAdapter mBtAdapter.startDiscovery(); }
當在某個項目上按下去....就會跳來執行這個function
因為 pairedListView.setOnItemClickListener(mDeviceClickListener);
newDevicesListView.setOnItemClickListener(mDeviceClickListener);
這兩行設定的
秀出 這個device 的字串和MAC address.. 然後就切換回去剛剛的intent()
因為呼叫了
setResult(Activity.RESULT_OK, intent);
finish()....
// The on-click listener for all devices in the ListViewsprivate OnItemClickListener mDeviceClickListener = new OnItemClickListener() { public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3) { // Cancel discovery because it's costly and we're about to connect mBtAdapter.cancelDiscovery(); // Get the device MAC address, which is the last 17 chars in the View String info = ((TextView) v).getText().toString(); String address = info.substring(info.length() - 17); // Create the result Intent and include the MAC address Intent intent = new Intent(); intent.putExtra(EXTRA_DEVICE_ADDRESS, address); // Set result and finish this Activity setResult(Activity.RESULT_OK, intent); finish(); } };
就會去執行這個function.....
首先會先判斷 requestCode... 因為我們是選 REQUEST_CONNECT_DEVICE_SECURE
所以會去跑到這裡
if (resultCode == Activity.RESULT_OK) { connectDevice(data, true); }
然後會再看 resultCode... 由於剛剛傳回來的 RESULT_OK
所以將會去執行 connectDevice(data, true);
public void onActivityResult(int requestCode, int resultCode, Intent data) { if(D) Log.d(TAG, "onActivityResult " + resultCode); switch (requestCode) { case REQUEST_CONNECT_DEVICE_SECURE: // When DeviceListActivity returns with a device to connect if (resultCode == Activity.RESULT_OK) { connectDevice(data, true); } break; case REQUEST_CONNECT_DEVICE_INSECURE: // When DeviceListActivity returns with a device to connect if (resultCode == Activity.RESULT_OK) { connectDevice(data, false); } break; case REQUEST_ENABLE_BT: // When the request to enable Bluetooth returns if (resultCode == Activity.RESULT_OK) { // Bluetooth is now enabled, so set up a chat session setupChat(); } else { // User did not enable Bluetooth or an error occured Log.d(TAG, "BT not enabled"); Toast.makeText(this, R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show(); finish(); } } }
connectDevice()的實作如下:String address = data.getExtras() .getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);這個會得到剛剛放進去的 device_address -> String address = info.substring(info.length() - 17);
然後呼叫 mBluetoothAdapter.getRemoteDevice(address)
得到 BluetoothDevice device 這個device...
最後再呼叫 mChatService.connect(device, secure) 去進行連線...
private void connectDevice(Intent data, boolean secure) { // Get the device MAC address String address = data.getExtras() .getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS); // Get the BLuetoothDevice object BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address); // Attempt to connect to the device mChatService.connect(device, secure); }接下來看 connect()....其實就是啟動了 mConnectThread thread...
public synchronized void connect(BluetoothDevice device, boolean secure) { if (D) Log.d(TAG, "connect to: " + device); // Cancel any thread attempting to make a connection if (mState == STATE_CONNECTING) { if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;} } // Cancel any thread currently running a connection if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;} // Start the thread to connect with the given device mConnectThread = new ConnectThread(device, secure); mConnectThread.start(); setState(STATE_CONNECTING); }這邊的code 就跟blue-tooth chat 的範例一樣了
沒有留言:
張貼留言