Android BLE 蓝牙编程(四)

接上篇,我们已经实现了短震,长震的功能了~

现在我们需要实现点击后一直震动的功能

开始我的想法是再循环中不断执行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 	 " + bluetoothGatt + "	" + 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: ");
    }
}
View Code

不过服务里面想要执行写方法需要获取到主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;
    }
}
View Code

名字我随便取的

大家可以起个好理解的。

如何设置全局变量呢?也很简单。

首先获取到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"));

恭喜你啦,现在你已经可以让你的手环震动到停不下来!~~

哈哈

下节我们来分析下服务的代码吧!

本节写的很仓促,有错的地方欢迎指正!~~

原文地址:https://www.cnblogs.com/wobeinianqing/p/5886756.html