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 \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: ");
    }
}
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"));

恭喜你啦,現在你已經可以讓你的手環震動到停不下來!~~

哈哈

下節我們來分析下服務的代碼吧!

本節寫的很倉促,有錯的地方歡迎指正!~~

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM