接上篇,我們已經實現了短震,長震的功能了~
現在我們需要實現點擊后一直震動的功能
開始我的想法是再循環中不斷執行write方法,然而這個辦法行不通。
系統會報錯。
那要如何實現這個想法呢?其實很簡單,使用service實現輪詢就行
那想到了解決方案就着手實現方法吧!!
寫個服務:

package com.wbnq.ryadie.service; import android.app.AlarmManager; import android.app.IntentService; import android.app.PendingIntent; import android.app.Service; import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGattCharacteristic; import android.content.Intent; import android.os.IBinder; import android.os.SystemClock; import android.util.Log; import com.wbnq.ryadie.HexUtil; import com.wbnq.ryadie.OfflineApplication; import com.wbnq.ryadie.R; import com.wbnq.ryadie.StaticData; import com.wbnq.ryadie.broadcast.AlarmReceiver; import java.util.Date; import static com.wbnq.ryadie.StaticData.GATDATA; import static com.wbnq.ryadie.StaticData.GATPOWER; /** * Created by guwei on 16-9-20. */ public class ReadData extends Service { BluetoothGatt bluetoothGatt; BluetoothGattCharacteristic bleGattCharacteristic; OfflineApplication application; boolean isrunning; public static final String TAG = "ReadData_service"; // @Nullable @Override public IBinder onBind(Intent intent) { return null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { application = (OfflineApplication) getApplication(); isrunning = application.getIsthreadrunning(); //這里開辟一條線程,用來執行具體的邏輯操作: new Thread(new Runnable() { @Override public void run() { Log.d("BackService", new Date().toString()); bleGattCharacteristic = application.getCharacteristic(); bluetoothGatt = application.getBluetoothGatt(); if (isrunning) { Log.e(TAG, "run: 開始輪詢服務"); //向設備發送獲取數據的命令 write(GATDATA); try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } //向設備發送獲取電量的命令 write(GATPOWER); } else { Log.e(TAG, "run: 停止輪詢服務"); } } }).start(); AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE); //這里是定時的,這里設置的是每隔兩秒打印一次時間=-=,自己改 int anHour = 20 * 1000; long triggerAtTime = SystemClock.elapsedRealtime() + anHour; Intent i = new Intent(this, AlarmReceiver.class); PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0); manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pi); return super.onStartCommand(intent, flags, startId); } //向設備寫入命令方法 private void write(String commond) { Log.i(TAG, "write: in write \t " + bluetoothGatt + "\t" + bleGattCharacteristic); if (bleGattCharacteristic != null && bluetoothGatt != null) { bleGattCharacteristic.setValue(HexUtil.hexStringToBytes(commond)); bluetoothGatt.writeCharacteristic(bleGattCharacteristic); commond = null; } } @Override public void onDestroy() { super.onDestroy(); Log.e(TAG, "onDestroy: "); } }
不過服務里面想要執行寫方法需要獲取到主Activity下獲取過的兩個數據:
bleGattCharacteristic
和
bluetoothGatt
這個要怎么傳遞過來呢?
其實方法很多,我這里用個簡單的
全局變量Application 方法就行。

package com.wbnq.ryadie; import android.app.Application; import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGattCharacteristic; /** * Created by guwei on 16-9-20. */ public class OfflineApplication extends Application { private BluetoothGatt bluetoothGatt; private BluetoothGattCharacteristic characteristic; private Boolean isthreadrunning ; @Override public void onCreate() { super.onCreate(); setBluetoothGatt(null); setCharacteristic(null); setIsthreadrunning(false); } public Boolean getIsthreadrunning() { return isthreadrunning; } public void setIsthreadrunning(Boolean isthreadrunning) { this.isthreadrunning = isthreadrunning; } public BluetoothGatt getBluetoothGatt() { return bluetoothGatt; } public void setBluetoothGatt(BluetoothGatt bluetoothGatt) { this.bluetoothGatt = bluetoothGatt; } public BluetoothGattCharacteristic getCharacteristic() { return characteristic; } public void setCharacteristic(BluetoothGattCharacteristic characteristic) { this.characteristic = characteristic; } }
名字我隨便取的
大家可以起個好理解的。
如何設置全局變量呢?也很簡單。
首先獲取到application:
myapplication = (OfflineApplication) getApplication();
然后設置相應的值:
//設置全局變量的值 myapplication.setCharacteristic(bleGattCharacteristic); myapplication.setBluetoothGatt(bluetoothGatt);
這就是設置。
獲取呢?
也很簡單:
bleGattCharacteristic = application.getCharacteristic();
bluetoothGatt = application.getBluetoothGatt();
很簡單對吧?
那么我如何開啟服務呢?方法也很多。在這里我就使用廣播的方式:
廣播接收器:
package com.wbnq.ryadie.broadcast; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.util.Log; import com.wbnq.ryadie.service.ReadData; /** * Created by guwei on 16-9-20. */ public class AlarmReceiver extends BroadcastReceiver { String TAG = "AlarmReceiver"; @Override public void onReceive(Context context, Intent intent ) { Intent i = new Intent(context, ReadData.class); context.startService(i); context.stopService(i); Log.e(TAG, "onReceive: onReceive"); } }
接收到廣播后就調用start方法就好了!很簡單對吧~
別忘了想要使用廣播,全局變量,服務都是需要注冊的。
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.wbnq.ryadie"> <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <!-- Android6.0 藍牙掃描才需要--> <uses-permission-sdk-23 android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <application android:name=".OfflineApplication" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name="com.wbnq.ryadie.service.ReadData" /> <receiver android:name=".broadcast.AlarmReceiver"> <intent-filter> <action android:name="com.guwei.READDATA"/> </intent-filter> </receiver> </application> </manifest>
最后一步,找對地方發送廣播~
sendBroadcast(new Intent("com.guwei.READDATA"));
恭喜你啦,現在你已經可以讓你的手環震動到停不下來!~~
哈哈
下節我們來分析下服務的代碼吧!
本節寫的很倉促,有錯的地方歡迎指正!~~