編輯:關於Android編程
請支持原創,尊重原創,轉載請注明出處:http://blog.csdn.net/kangweijian(來自kangweijian的csdn博客)
前四個效果圖可通過左右滑動或者點擊頂層四個控件切換得,點擊連接按鈕得到查找藍牙設備的效果圖
主Activity(MainActivity.java)
設定MainActivity的視圖,該視圖頂層4個Button,底層2個Button,中間一個fragment碎片,設定fragment碎片為ViewPager視圖
BluetoothAdapter.getDefaultAdapter()獲取本地藍牙設備,如果本地藍牙設備為空,則提示信息,並結束程序
.enable(),打開本地藍牙適配器。
連接按鈕實例化,並設置點擊監聽器。該監聽器函數中,如果.isEnabled()本地藍牙未啟用,則提示信息,本返回。如果BluetoothSocket為null,則使用startActivityFZ喎?/kf/ware/vc/" target="_blank" class="keylink">vclJlc3VsdCguLinM+Neqtb3AttHAyeixuLLp1dJBY3Rpdml0eaOst/HU8su1w/dTb2NrZXTS0cGsvdOjrLTLyrHU8tKqts+/qlNvY2tldMGsvdOhozxicj4Kzcuz9rC0xaXKtcD9u6+jrLKiyejWw7Xju/e84Mz9xveho9K7tam147v3vLTNy7P2s8zQ8qGjPGJyPgpvbkFjdGl2aXR5UmVzdWx0KKGtKbqvyv3W0KOs0ru1qURldmljZUxpc3RBY3Rpdml0ebe1u9i94bn7zqpBY3Rpdml0eS5SRVNVTFRfT0ujrNTy08lJbnRlbnQuZ2V0RXh0cmFzKCkuZ2V0U3RyaW5nKCm6r8r9tcO1vURldmljZUxpc3RBY3Rpdml0ebSrtd25/cC0tcTUtrPMwLbRwMnosbi12Na3o6zTyUJsdWV0b290aERldmljZS5nZXRSZW1vdGVEZXZpY2UoYWRkcmVzcym1w7W91LazzMC20cDJ6LG4o6zTyUJsdWV0b290aERldmljZS5jcmVhdGVSZmNvbW1Tb2NrZXRUb1NlcnZpY2VSZWNvcmQoVVVJRC5mcm9tU3RyaW5nKFVVSUQpKbqvyv21w7W9Qmx1ZXRvb3RoU29ja2V0o6zX7rrz08lCbHVldG9vdGhTb2NrZXQKIGNvbm5lY3QoKbqvyv3BrL3Tsb612MC20cDJ6LG4us3UtrPMwLbRwMnosbihozxicj4K1+6687zHtcPU2kFjdGl2aXR5yfrD/Nbcxtq1xG9uRGVzdHJveSgp1tCjrC5jbG9zZSgpudix1UJsdWV0b290aFNvY2tldMGsvdMsLmRpc2FibGUoKbnYsdVCbHVldG9vdGhBZGFwdGVywLbRwLf+zvGho9LRsaPWpNTas8zQ8s3Ls/a686Osys23xbXXsuPJ6LG4vuSx+qGjPGJyPgqyubPky7XD96O6yrnTw3N0YXJ0QWN0aXZpdHlGb3JSZXN1bHQoLi4pzPjXqkFjdGl2aXR5tcTX99PDysdNYWluQWN0aXZpdHnQ6NKq1NpEZXZpY2VMaXN0QWN0aXZpdHnW0Na00NDIzs7xo6xEZXZpY2VMaXN0QWN0aXZpdHnWtNDQyM7O8c3qsc+687e1u9i94bn7uPhNYWluQWN0aXZpdHmjrE1haW5BY3Rpdml0edTab25BY3Rpdml0eVJlc3VsdCihrSnW0LXDtb3L+dDotcS94bn7oaNvbkFjdGl2aXR5UmVzdWx0KKGtKdbQ09DI/bj2ss7K/aOstdrSu7j2ss7K/crHx+vH87T6wutyZXF1ZXN0Q29kZaOsysfTyU1haW5BY3Rpdml0ebeis/ajrLXatv649rLOyv3Kx73hyvi0+sLrcmVzdWx0Q29kZaOsysfTyURldmljZUxpc3RBY3Rpdml0ebe1u9ijrNfuuvPSu7j2ss7K/crHSW50ZW50oaO5ytTab25BY3Rpdml0eVJlc3VsdCihrSm6r8r91tCjrMrXz8jF0LbPcmVxdWVzdENvZGWjrLy0xdC2z01haW5BY3Rpdml0ecfrx/PExLj2QWN0aXZpdHnWtNDQyM7O8aOsxuS0ztTZxdC2z3Jlc3VsdENvZGWjrLy0xdC2z8THuPZBY3Rpdml0eda00NDIzs7xuvO3tbvYwcu6ztbWveG5+6GjPGJyPgpwYWNrYWdlIGNvbS5leGFtcGxlLnRpbWVyYmx1ZXRvb3RoMi5BY3Rpdml0eTs8YnI+CjxwcmUgY2xhc3M9"brush:java;">
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
import com.example.timerbluetooth2.R;
import com.example.timerbluetooth2.Fragment.ViewPagerFragment;
public class MainActivity extends FragmentActivity {
private final static int REQUEST_CONNECT_DEVICE = 1; //宏定義查詢設備句柄
private final static String MY_UUID = "00001101-0000-1000-8000-00805F9B34FB"; //SPP服務UUID號
private BluetoothAdapter _bluetooth = BluetoothAdapter.getDefaultAdapter(); //獲取本地藍牙適配器,即藍牙設備
private InputStream is; //輸入流,用來接收藍牙數據
private OutputStream os; //輸出流,用來發送藍牙數據
BluetoothDevice _device = null; //藍牙設備
public BluetoothSocket _socket = null; //藍牙通信socket
private Button connectButton,quitButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
//設置MainActivity視圖
setContentView(R.layout.activity_main);
//設置fragment碎片為ViewPager視圖
FragmentManager fm = getSupportFragmentManager();
android.support.v4.app.Fragment fragment= fm.findFragmentById(R.id.fragmentContainer);
if (fragment==null) {
fragment = new ViewPagerFragment();
fm.beginTransaction().add(R.id.fragmentContainer, fragment).commit();
}
//如果本地藍牙設備為空,提示信息,結束程序
if (_bluetooth == null){
Toast.makeText(this, "無法打開手機藍牙,請確認手機是否有藍牙功能!", Toast.LENGTH_LONG).show();
finish();
return;
}
//設置設備可以被搜索
new Thread(){
public void run(){
if(_bluetooth.isEnabled()==false){
_bluetooth.enable();
}
}
}.start();
connectButton = (Button) findViewById(R.id.ConnectButton);
quitButton = (Button) findViewById(R.id.QuitButton);
connectButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
//如果藍牙服務不可用則提示
if(_bluetooth.isEnabled()==false){
Toast.makeText(MainActivity.this, " 打開藍牙中...", Toast.LENGTH_LONG).show();
return;
}
//如未連接設備則打開DeviceListActivity進行設備搜索
if(_socket==null){
Intent serverIntent = new Intent(MainActivity.this, DeviceListActivity.class); //跳轉程序設置
startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE); //設置返回宏定義
}
else{
//關閉連接socket
try{
is.close();
_socket.close();
_socket = null;
connectButton.setText("連接");
}catch(IOException e){}
}
}
});
quitButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
finish();
}
});
}
//接收活動結果,響應startActivityForResult()
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch(requestCode){
// 響應返回結果//連接結果,由DeviceListActivity設置返回
case REQUEST_CONNECT_DEVICE:
//連接成功,由DeviceListActivity設置返回
if (resultCode == Activity.RESULT_OK) {
// MAC地址,由DeviceListActivity設置返回
String address = data.getExtras().getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
// 得到遠程藍牙設備句柄
_device = _bluetooth.getRemoteDevice(address);
// 用服務號得到socket
try{
_socket = _device.createRfcommSocketToServiceRecord(UUID.fromString(MY_UUID));
}catch(IOException e){
Toast.makeText(this, "連接失敗!", Toast.LENGTH_SHORT).show();
}
//連接socket
try{
_socket.connect();
Toast.makeText(this, "連接"+_device.getName()+"成功!", Toast.LENGTH_SHORT).show();
connectButton.setText("斷開");
}catch(IOException e){
try{
Toast.makeText(this, "連接失敗!", Toast.LENGTH_SHORT).show();
_socket.close();
_socket = null;
}catch(IOException ee){
Toast.makeText(this, "連接失敗!", Toast.LENGTH_SHORT).show();
}
return;
}
// //打開接收線程
// try{
// is = _socket.getInputStream(); //得到藍牙數據輸入流
// ReadThread.start();
// }catch(IOException e){
// Toast.makeText(this, "接收數據失敗!", Toast.LENGTH_SHORT).show();
// return;
// }
}
break;
default:break;
}
}
//接收數據線程
// Thread ReadThread=new Thread(){
//
// public void run(){
//
// try {
//
// while (!Thread.interrupted()) {
//
// // the number of bytes that can be read from the input stream without blocking.
// // 返回輸入流中可被讀取的字節數
// int count = is.available();
// if (count <= 0) {
// Thread.sleep(10);
// continue;//等待有效數據讀取
// }
//
// // create buffer
// byte[] buf = new byte[count];
//
// // read data into buffer
// is.read(buf);
//
//
//
//
// }
// } catch (IOException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// } catch (NullPointerException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// } catch (Exception e) {
// // TODO: handle exception
// }
// }
// };
//關閉程序掉用處理部分
public void onDestroy(){
super.onDestroy();
//如果Socket不為空,則關閉連接Socket
if(_socket!=null)
try{
_socket.close();
}catch(IOException e){}
//關閉藍牙服務
_bluetooth.disable();
}
}
藍牙設備查找Activity(DeviceListActivity.java)
設定DeviceListActivity的視圖,使用LinearLayout布局,從上到下,已配對設備的TextView和ListView、未配對設備的TextView和ListView,最後一個查找設備Button和一個取消Button。除了兩個Button,其他的可見性都為隱藏。
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS)設定Activity應用程序窗口顯示特性為:不確定的進度
設定startActivityForResult的默認返回值為Activity.RESULT_CANCELED
掃描按鈕實例化,並設置點擊監聽器。該監聽器函數中,設置按鈕可見性為隱藏,並開始服務和設備的查找。首先設置在Activity窗口的標題欄顯示進度條的效果,設置標題欄的標題為”查找設備中”,以及設置未配對設備的可見性為可見。BluetoothAdapter.getDefaultAdapter()獲取本地藍牙設備,然後由.startDiscovery()函數開始對遠程設備進行查找。
取消按鈕實例化,並設置點擊監聽器。一旦點擊即退出程序。
已配對設備適配器和已配對設備視圖實例化,已配對視圖添加已配對適配器,並設置點擊監聽器OnItemClickListener()。該監聽器函數中,首先由BluetoothAdapter調用.cancelDiscovery()函數取消當前的設備發現查找進程。然後由OnItemClickListener()的第二個參數((TextView)View).getText().toString()得到遠程藍牙設備地址字符串,如果該地址等於NO_FOUND_DEVICE “沒有找到新設備”,則提示消息,並返回。如果不是,則取出該String.substring(s.length()
- 17)字符串的最後17個字符,返回程序,設定startActivityForResult的默認返回值為Activity.RESULT_OK。
未配對設備適配器和未配對設備視圖同上。
注冊查找到設備action的廣播接收器IntentFilter filter = newIntentFilter(BluetoothDevice.ACTION_FOUND); this.registerReceiver(mReceiver,filter);注冊查找結束action的廣播接收器filter = new IntentFilter(BluetoothAdapter. ACTION_DISCOVERY_FINISHED);this.registerReceiver(mReceiver, filter);
廣播接收器中,監聽查找到設備和查找結束action。。。
最後記得在Activity生命周期的onDestroy()中,BluetoothAdapter.cancelDiscovery()取消當前的設備發現查找進程。注銷action接收器 this.unregisterReceiver(mReceiver);
package com.example.timerbluetooth2.Activity;
import com.example.timerbluetooth2.*; import android.app.Activity; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.Window; import android.view.View.OnClickListener; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.ListView; import android.widget.TextView; import android.widget.AdapterView.OnItemClickListener; import android.widget.Toast; public class DeviceListActivity extends Activity { // 返回時數據標簽 public static String EXTRA_DEVICE_ADDRESS = "設備地址"; public final static String NO_FOUND_DEVICE = "沒有找到新設備"; // 本地的藍牙適配器設備,BluetoothAdapter類讓用戶能執行基本的藍牙任務 private BluetoothAdapter mBtAdapter; // 數組適配器,存入String集合,代表已配對和未配對的藍牙設備的地址 private ArrayAdaptermPairedDevicesArrayAdapter; private ArrayAdapter mNewDevicesArrayAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Android應用程序的窗體顯示,設置其特性為:不確定的進度 requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); setContentView(R.layout.device_list); // 設定startActivityForResult的默認返回值為取消 setResult(Activity.RESULT_CANCELED); // 掃描按鈕實例化 Button scanButton = (Button) findViewById(R.id.button_scan); // 設置掃描按鈕點擊監聽器 scanButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { //開始服務和設備查找 doDiscovery(); //設置按鈕可見性為隱藏 v.setVisibility(View.GONE); } }); // 取消按鈕實例化 Button cancelButton = (Button) findViewById(R.id.button_cancel); // 設置取消按鈕點擊監聽器 cancelButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // TODO Auto-generated method stub finish(); } }); // 已配對設備適配器實例化 mPairedDevicesArrayAdapter = new ArrayAdapter (this, R.layout.device_name); // 新的未配對過的設備適配器實例化 mNewDevicesArrayAdapter = new ArrayAdapter (this, R.layout.device_name); // 已配對視圖實例化 ListView pairedListView = (ListView) findViewById(R.id.paired_devices); // 已配對視圖添加適配器 pairedListView.setAdapter(mPairedDevicesArrayAdapter); // 已配對視圖設置點擊監聽器 pairedListView.setOnItemClickListener(mDeviceClickListener); // 新的未配對過的視圖實例化 ListView newDevicesListView = (ListView) findViewById(R.id.new_devices); // 新的未配對過的視圖添加適配器 newDevicesListView.setAdapter(mNewDevicesArrayAdapter); // 新的未配對過的視圖設置點擊監聽器 newDevicesListView.setOnItemClickListener(mDeviceClickListener); // 注冊接收查找到設備action接收器 IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); this.registerReceiver(mReceiver, filter); // 注冊查找結束action接收器 filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); this.registerReceiver(mReceiver, filter); // 獲取默認本地藍牙適配器的操作權限 mBtAdapter = BluetoothAdapter.getDefaultAdapter(); } /*************************************************************************** * * Activity銷毀時 * */ @Override protected void onDestroy() { super.onDestroy(); // 關閉服務查找 if (mBtAdapter != null) { mBtAdapter.cancelDiscovery(); } // 注銷action接收器 this.unregisterReceiver(mReceiver); } /**************************************************************************** * * 開始服務和設備查找 * */ private void doDiscovery() { // 設置在Activity的窗口的標題欄顯示進度條的效果 setProgressBarIndeterminateVisibility(true); setTitle("查找設備中..."); // 設定其它設備(未配對設備)列表的能見度為:可見的 findViewById(R.id.title_new_devices).setVisibility(View.VISIBLE); // 如果當前藍牙適配器正處於設備發現查找進程中,則返回真 if (mBtAdapter.isDiscovering()) { // 取消當前的設備發現查找進程 mBtAdapter.cancelDiscovery(); } // 開始對遠程設備進行查找的進程 mBtAdapter.startDiscovery(); } /***************************************************************************** * * 視圖點擊選擇設備連接函數 * */ private OnItemClickListener mDeviceClickListener = new OnItemClickListener() { public void onItemClick(AdapterView> av, View v, int arg2, long arg3) { // 取消當前的設備發現查找進程 mBtAdapter.cancelDiscovery(); // 得到mac地址 String info = ((TextView) v).getText().toString(); if (info.equals(NO_FOUND_DEVICE)) { Toast.makeText(DeviceListActivity.this, "沒有找到藍牙設備,無法連接", Toast.LENGTH_LONG).show(); return ; } String address = info.substring(info.length() - 17); // 設置返回數據 Intent intent = new Intent(); intent.putExtra(EXTRA_DEVICE_ADDRESS, address); // 設置連接成功返回值 setResult(Activity.RESULT_OK, intent); // 結束程序 finish(); } }; // 廣播接收器,監聽查找到設備和搜索完成action private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); // 查找到設備action if (BluetoothDevice.ACTION_FOUND.equals(action)) { // 得到藍牙設備 BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); // 如果是已配對的則略過,已得到顯示,其余的在添加到列表中進行顯示 if (device.getBondState() != BluetoothDevice.BOND_BONDED) { mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress()); }else{ //添加到已配對設備列表 mPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress()); } // 搜索完成action } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) { // 取消在Activity的窗口的標題欄顯示進度條的效果 setProgressBarIndeterminateVisibility(false); setTitle("選擇要連接的設備"); //如果沒有找到新設備,則添加"沒有找到新設備"到新設備適配器列表 if (mNewDevicesArrayAdapter.getCount() == 0) { mNewDevicesArrayAdapter.add(NO_FOUND_DEVICE); } // if(mPairedDevicesArrayAdapter.getCount() > 0) // findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE); } } }; }
package com.example.timerbluetooth2.Other; public class Communications_Protocol { public final static byte Timer=(byte) 0xf0; public final static byte OpenClock=(byte) 0xf1; public final static byte CloseClock=(byte) 0xf2; public final static byte OpenMonitor=(byte) 0xf3; public final static byte CloseMonitor=(byte) 0xf4; public final static byte Adjustment=(byte) 0xf5; }
package com.example.timerbluetooth2.Fragment; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager.OnPageChangeListener; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.Button; import com.example.timerbluetooth2.R; public class ViewPagerFragment extends Fragment { public Button []TextButton=new Button[4]; private ViewPager mViewPager; @Override public void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO Auto-generated method stub //實例化TextButton TextButton[0] = (Button) getActivity().findViewById(R.id.TextButton1); TextButton[1] = (Button) getActivity().findViewById(R.id.TextButton2); TextButton[2] = (Button) getActivity().findViewById(R.id.TextButton3); TextButton[3] = (Button) getActivity().findViewById(R.id.TextButton4); //創建ViewPager實例 mViewPager=new ViewPager(getActivity()); //創建資源ID(res/values/ids.xml),並配置mViewPager mViewPager.setId(R.id.viewPager); //獲取Activity的FragmentManager實例 FragmentManager fm = getActivity().getSupportFragmentManager(); //設置adapter為FagmentStatePagerAdapter的一個匿名實例 //FragmentStatePagerAdapter負責管理與ViewPager的對話並協同工作。 mViewPager.setAdapter(new FragmentPagerAdapter(fm) { //getCount()返回mViewPager包含的列表項數目 @Override public int getCount() { // TODO Auto-generated method stub //return mCrimes.size(); return 4; } //根據列表項ID,返回一個有效配置的Fragment @Override public Fragment getItem(int pos) { // TODO Auto-generated method stub switch (pos) { case 0: return TimerFragment.newInstance(); case 1: return TimeMonitorFragment.newInstance(); case 2: return ClockFragment.newInstance(); case 3: return AdjustmentFragment.newInstance(); default: return TimerFragment.newInstance(); } } }); //設置當前要顯示的列表項 mViewPager.setCurrentItem(0); LightUpSingleButton(0); //設置監聽器,監聽ViewPager當前顯示頁面的狀態變化 mViewPager.setOnPageChangeListener(new OnPageChangeListener() { //onPageSelected()方法告知我們當前哪個頁面會被選中 @Override public void onPageSelected(int pos) { // TODO Auto-generated method stub LightUpSingleButton(pos); } //onPageScrolled()方法告知我們頁面將會滑向哪裡 @Override public void onPageScrolled(int arg0, float arg1, int arg2) { // TODO Auto-generated method stub } //onPageScrollStateChanged()方法告知我們當前頁面所處的行為狀態,如正在被用戶滑動,頁面滑動入位到完全靜止以及頁面切換完成後的閒置狀態 @Override public void onPageScrollStateChanged(int arg0) { // TODO Auto-generated method stub } }); //設置ViewPager為activity的內容視圖 return mViewPager; } @Override public void onActivityCreated(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onActivityCreated(savedInstanceState); TextButton[0].setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // TODO Auto-generated method stub mViewPager.setCurrentItem(0); LightUpSingleButton(0); } }); TextButton[1].setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // TODO Auto-generated method stub mViewPager.setCurrentItem(1); LightUpSingleButton(1); } }); TextButton[2].setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // TODO Auto-generated method stub mViewPager.setCurrentItem(2); LightUpSingleButton(2); } }); TextButton[3].setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // TODO Auto-generated method stub mViewPager.setCurrentItem(3); LightUpSingleButton(3); } }); } public void LightUpSingleButton(int num){ for (int i = 0; i < TextButton.length; i++) { if (num==i) { TextButton[i].setTextColor(0xFFDB7093); }else { TextButton[i].setTextColor(0xFFA9A9A9); } } } }
package com.example.timerbluetooth2.Fragment; import java.io.IOException; import java.io.OutputStream; import com.example.timerbluetooth2.*; import com.example.timerbluetooth2.Activity.MainActivity; import com.example.timerbluetooth2.Other.Communications_Protocol; import android.bluetooth.BluetoothSocket; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.Button; import android.widget.TimePicker; import android.widget.Toast; public class TimerFragment extends Fragment { private Button TimerUpdateButton; private TimePicker mTimerPicker; /********************************* * * 1、onCreate(Bundle)是公共方法,因此可以被托管fragment的任何activity調用 * 2、類似activity,fragment同樣具有保存及獲取狀態的bundle,可以根據需要覆蓋Fragment.onSaveInstanceState(Bundle) * 3、onCreate(Bundle)中,沒有生成fragment視圖。 */ @Override public void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); } /************************************* * * 通過該方法生成fragment視圖的布局,然後將生成的View返回給托管activity。 * LayoutInflater及ViewGroup是用來生成布局的必要參數。 * Bundle包含了該方法的保存狀態下重建視圖所使用的數據。 */ @Override public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) { // TODO Auto-generated method stub // 調用LayoutInflater.inflate(...)方法並傳入布局的資源ID生成的。第二個參數是視圖的父視圖,通過父視圖來正確配置組件。 // 第三個參數告知布局生成器是否將生成的視圖添加給父視圖。這裡我們傳入了false,因為我們將通過activity代碼的方式添加視圖。 View v = inflater.inflate(R.layout.fragment_timer, parent, false); //mTimerPicker實例化 mTimerPicker = (TimePicker) v.findViewById(R.id.Timer_Picker); //mTimerPicker是否使用24小時制 mTimerPicker.setIs24HourView(true); TimerUpdateButton = (Button) v.findViewById(R.id.Timer_UpdateButton); TimerUpdateButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // TODO Auto-generated method stub byte []buf =new byte[5]; int h=mTimerPicker.getCurrentHour(); int m=mTimerPicker.getCurrentMinute(); buf[0] = Communications_Protocol.Timer; buf[1] = (byte)((h/10)*16+(h%10)); buf[2] = (byte)((m/10)*16+(m%10)); buf[3] = 0; buf[4] = (byte) 0xff; BluetoothSocket socket = ((MainActivity)getActivity())._socket; if (socket == null) { Toast.makeText(getActivity(), "請先連接藍牙設備",Toast.LENGTH_SHORT).show(); }else { try { OutputStream os=socket.getOutputStream(); os.write(buf); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }); return v; } /************************************** * 目的:附加argument bundle給Fragment,需要調用Fragment.setArguments(Bundle)方法。 * 要求:該任務必須在fragment創建後,添加給activity前完成 * 方法:使用newInstance()方法,完成Fragment實例及bundle對象的創建,然後將argument放入bundle中,最後附加給Fragment * 其他:托管activity需要fragment實例時,需要調用newInstance()方法,而非直接調用其構造方法。而且,為滿足fragment創建argument的要求,activity可傳入 * 任何需要的參數給newInstance()方法。 * * @param crimeID * @return */ public static TimerFragment newInstance(){ Bundle args = new Bundle(); TimerFragment fragment=new TimerFragment(); fragment.setArguments(args); return fragment; } }
package com.example.timerbluetooth2.Fragment; import java.io.IOException; import java.io.OutputStream; import com.example.timerbluetooth2.*; import com.example.timerbluetooth2.Activity.MainActivity; import com.example.timerbluetooth2.Other.Communications_Protocol; import android.bluetooth.BluetoothSocket; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.Button; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.Switch; import android.widget.TimePicker; import android.widget.Toast; public class TimeMonitorFragment extends Fragment { private TimePicker TimeMonitorPicker1,TimeMonitorPicker2; private Switch TimeMonitorSwitch; /********************************* * * 1、onCreate(Bundle)是公共方法,因此可以被托管fragment的任何activity調用 * 2、類似activity,fragment同樣具有保存及獲取狀態的bundle,可以根據需要覆蓋Fragment.onSaveInstanceState(Bundle) * 3、onCreate(Bundle)中,沒有生成fragment視圖。 */ @Override public void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); } /************************************* * * 通過該方法生成fragment視圖的布局,然後將生成的View返回給托管activity。 * LayoutInflater及ViewGroup是用來生成布局的必要參數。 * Bundle包含了該方法的保存狀態下重建視圖所使用的數據。 */ @Override public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) { // TODO Auto-generated method stub // 調用LayoutInflater.inflate(...)方法並傳入布局的資源ID生成的。第二個參數是視圖的父視圖,通過父視圖來正確配置組件。 // 第三個參數告知布局生成器是否將生成的視圖添加給父視圖。這裡我們傳入了false,因為我們將通過activity代碼的方式添加視圖。 View v = inflater.inflate(R.layout.fragment_time_monitor, parent, false); //TimeMonitorSwitch實例化 TimeMonitorSwitch = (Switch) v.findViewById(R.id.TimeMonitor_Switch); //TimeMonitorPicker1實例化 TimeMonitorPicker1 = (TimePicker) v.findViewById(R.id.TimeMonitor_Picker1); //TimeMonitorPicker1是否使用24小時制 TimeMonitorPicker1.setIs24HourView(true); //TimeMonitorPicker2實例化 TimeMonitorPicker2 = (TimePicker) v.findViewById(R.id.TimeMonitor_Picker2); //mTimerPicker是否使用24小時制 TimeMonitorPicker2.setIs24HourView(true); TimeMonitorSwitch.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton arg0, boolean arg1) { // TODO Auto-generated method stub byte []buf =new byte[6]; int h1=TimeMonitorPicker1.getCurrentHour(); int m1=TimeMonitorPicker1.getCurrentMinute(); int h2=TimeMonitorPicker2.getCurrentHour(); int m2=TimeMonitorPicker2.getCurrentMinute(); if (TimeMonitorSwitch.isChecked()) { buf[0] = Communications_Protocol.OpenMonitor; }else { buf[0] = Communications_Protocol.CloseMonitor; } buf[1] = (byte)((h1/10)*16+(h1%10)); buf[2] = (byte)((m1/10)*16+(m1%10)); buf[3] = (byte)((h2/10)*16+(h2%10)); buf[4] = (byte)((m2/10)*16+(m2%10)); buf[5] = (byte) 0xff; BluetoothSocket socket = ((MainActivity)getActivity())._socket; if (socket == null) { Toast.makeText(getActivity(), "請先連接藍牙設備",Toast.LENGTH_SHORT).show(); }else { try { OutputStream os=socket.getOutputStream(); os.write(buf); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }); return v; } /************************************** * 目的:附加argument bundle給Fragment,需要調用Fragment.setArguments(Bundle)方法。 * 要求:該任務必須在fragment創建後,添加給activity前完成 * 方法:使用newInstance()方法,完成Fragment實例及bundle對象的創建,然後將argument放入bundle中,最後附加給Fragment * 其他:托管activity需要fragment實例時,需要調用newInstance()方法,而非直接調用其構造方法。而且,為滿足fragment創建argument的要求,activity可傳入 * 任何需要的參數給newInstance()方法。 * * @param crimeID * @return */ public static TimeMonitorFragment newInstance(){ Bundle args = new Bundle(); TimeMonitorFragment fragment=new TimeMonitorFragment(); fragment.setArguments(args); return fragment; } }
package com.example.timerbluetooth2.Fragment; import java.io.IOException; import java.io.OutputStream; import com.example.timerbluetooth2.*; import com.example.timerbluetooth2.Activity.MainActivity; import com.example.timerbluetooth2.Other.Communications_Protocol; import android.bluetooth.BluetoothSocket; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.Switch; import android.widget.TimePicker; import android.widget.Toast; public class ClockFragment extends Fragment { private Button Clock_UpdateButton; private TimePicker mTimePicker; private Switch mSwitch; /********************************* * * 1、onCreate(Bundle)是公共方法,因此可以被托管fragment的任何activity調用 * 2、類似activity,fragment同樣具有保存及獲取狀態的bundle,可以根據需要覆蓋Fragment.onSaveInstanceState(Bundle) * 3、onCreate(Bundle)中,沒有生成fragment視圖。 */ @Override public void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); } /************************************* * * 通過該方法生成fragment視圖的布局,然後將生成的View返回給托管activity。 * LayoutInflater及ViewGroup是用來生成布局的必要參數。 * Bundle包含了該方法的保存狀態下重建視圖所使用的數據。 */ @Override public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) { // TODO Auto-generated method stub // 調用LayoutInflater.inflate(...)方法並傳入布局的資源ID生成的。第二個參數是視圖的父視圖,通過父視圖來正確配置組件。 // 第三個參數告知布局生成器是否將生成的視圖添加給父視圖。這裡我們傳入了false,因為我們將通過activity代碼的方式添加視圖。 View v = inflater.inflate(R.layout.fragment_clock, parent, false); //mSwitch實例化 mSwitch = (Switch) v.findViewById(R.id.Clock_Switch); //mTimePicker實例化 mTimePicker = (TimePicker) v.findViewById(R.id.Clock_Picker); //mTimePicker是否使用24小時制 mTimePicker.setIs24HourView(true); mSwitch.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton arg0, boolean arg1) { // TODO Auto-generated method stub byte []buf =new byte[4]; int h=mTimePicker.getCurrentHour(); int m=mTimePicker.getCurrentMinute(); if (mSwitch.isChecked()) { buf[0] = Communications_Protocol.OpenClock; }else { buf[0] = Communications_Protocol.CloseClock; } buf[1] = (byte)((h/10)*16+(h%10)); buf[2] = (byte)((m/10)*16+(m%10)); buf[3] = (byte) 0xff; BluetoothSocket socket = ((MainActivity)getActivity())._socket; if (socket == null) { Toast.makeText(getActivity(), "請先連接藍牙設備",Toast.LENGTH_SHORT).show(); }else { try { OutputStream os=socket.getOutputStream(); os.write(buf); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }); return v; } /************************************** * 目的:附加argument bundle給Fragment,需要調用Fragment.setArguments(Bundle)方法。 * 要求:該任務必須在fragment創建後,添加給activity前完成 * 方法:使用newInstance()方法,完成Fragment實例及bundle對象的創建,然後將argument放入bundle中,最後附加給Fragment * 其他:托管activity需要fragment實例時,需要調用newInstance()方法,而非直接調用其構造方法。而且,為滿足fragment創建argument的要求,activity可傳入 * 任何需要的參數給newInstance()方法。 * * @param crimeID * @return */ public static ClockFragment newInstance(){ Bundle args = new Bundle(); ClockFragment fragment=new ClockFragment(); fragment.setArguments(args); return fragment; } }
package com.example.timerbluetooth2.Fragment; import java.io.IOException; import java.io.OutputStream; import com.example.timerbluetooth2.*; import com.example.timerbluetooth2.Activity.MainActivity; import com.example.timerbluetooth2.Other.Communications_Protocol; import android.bluetooth.BluetoothSocket; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.webkit.WebView.FindListener; import android.widget.Button; import android.widget.ScrollView; import android.widget.TimePicker; import android.widget.Toast; public class AdjustmentFragment extends Fragment { private TimePicker mTimePicker; private Button Adjustment_Button; /********************************* * * 1、onCreate(Bundle)是公共方法,因此可以被托管fragment的任何activity調用 * 2、類似activity,fragment同樣具有保存及獲取狀態的bundle,可以根據需要覆蓋Fragment.onSaveInstanceState(Bundle) * 3、onCreate(Bundle)中,沒有生成fragment視圖。 */ @Override public void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); } /************************************* * * 通過該方法生成fragment視圖的布局,然後將生成的View返回給托管activity。 * LayoutInflater及ViewGroup是用來生成布局的必要參數。 * Bundle包含了該方法的保存狀態下重建視圖所使用的數據。 */ @Override public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) { // TODO Auto-generated method stub // 調用LayoutInflater.inflate(...)方法並傳入布局的資源ID生成的。第二個參數是視圖的父視圖,通過父視圖來正確配置組件。 // 第三個參數告知布局生成器是否將生成的視圖添加給父視圖。這裡我們傳入了false,因為我們將通過activity代碼的方式添加視圖。 View v = inflater.inflate(R.layout.fragment_adjustment, parent, false); //mTimePicker實例化 mTimePicker = (TimePicker) v.findViewById(R.id.Adjustment_Picker); //mTimePicker是否使用24小時制 mTimePicker.setIs24HourView(true); //mTimePicker設置當前時間為0 mTimePicker.setCurrentHour(0); mTimePicker.setCurrentMinute(0); Adjustment_Button = (Button) v.findViewById(R.id.Adjustment_UpdateButton); Adjustment_Button.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // TODO Auto-generated method stub byte []buf =new byte[4]; int h=mTimePicker.getCurrentHour(); int m=mTimePicker.getCurrentMinute(); buf[0] = Communications_Protocol.Adjustment; buf[1] = (byte)h; buf[2] = (byte)m; buf[3] = (byte) 0xff; BluetoothSocket socket = ((MainActivity)getActivity())._socket; if (socket == null) { Toast.makeText(getActivity(), "請先連接藍牙設備",Toast.LENGTH_SHORT).show(); }else { try { OutputStream os=socket.getOutputStream(); os.write(buf); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }); return v; } /************************************** * 目的:附加argument bundle給Fragment,需要調用Fragment.setArguments(Bundle)方法。 * 要求:該任務必須在fragment創建後,添加給activity前完成 * 方法:使用newInstance()方法,完成Fragment實例及bundle對象的創建,然後將argument放入bundle中,最後附加給Fragment * 其他:托管activity需要fragment實例時,需要調用newInstance()方法,而非直接調用其構造方法。而且,為滿足fragment創建argument的要求,activity可傳入 * 任何需要的參數給newInstance()方法。 * * @param crimeID * @return */ public static AdjustmentFragment newInstance(){ Bundle args = new Bundle(); AdjustmentFragment fragment=new AdjustmentFragment(); fragment.setArguments(args); return fragment; } }
<frameLayout android:id="@+id/fragmentContainer" android:layout_width="fill_parent" android:layout_height="match_parent" android:layout_weight="1" />
創建第三個列表項的布局文件(fragment_clock.xml)
AndroidManifest.xml添加權限和activity清單
示波器是在大學的時候老師教的,但是出來工作一直沒有用到過,漸漸的也就忘記了,現在重新學習一下。來看看效果圖:這裡是一個自定義的柱狀圖,然後有一個按鈕,點擊按鈕的時候,這裡
效果: 代碼:https://github.com/ldb-github/Layout_Tab1、布局:使用LinearLayout布置標簽;再使用FrameL
移動端開發時,我們常使用chrome自帶的模擬器,模擬各種手機設備。 但模擬畢竟是模擬,當開發完畢,使用真機訪問頁面出現問題時如何調試呢?下面介紹一種針對android機
現在的移動端應用幾乎都會通過網絡請求來和服務器交互,通過抓包來診斷和網絡相關的bug是程序員的重要技能之一。抓包的手段有很多:針對http和https可以使用Charle