Android BLE 蓝牙编程(四)
接上篇,我们已经实现了短震,长震的功能了~
现在我们需要实现点击后一直震动的功能
开始我的想法是再循环中不断执行write方法,然而这个办法行不通。
系统会报错。
那要如何实现这个想法呢?其实很简单,使用service实现轮询就行
那想到了解决方案就着手实现方法吧!!
写个服务:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 方法就行。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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"));
恭喜你啦,现在你已经可以让你的手环震动到停不下来!~~
哈哈
下节我们来分析下服务的代码吧!
本节写的很仓促,有错的地方欢迎指正!~~