Как сканировать устройство BLE в фоновом режиме без библиотеки?

Я пытаюсь подключить устройство BLE к приложению Android. Я получаю имя устройства, адрес Mac и значение rssi на переднем плане. Я не знаю, как сканировать устройство в фоновом режиме и получать сведения об этом конкретном устройстве, например MAC-адрес, значение rssi.


person S.Sathya Priya    schedule 01.10.2015    source источник
comment
Что вы имеете в виду, что вы получаете имя устройства, адрес Mac и значение rssi на переднем плане? Если вы выполняете трудоемкую операцию, такую ​​как сканирование Bluetooth в потоке пользовательского интерфейса, это блокирует поток пользовательского интерфейса. И большую часть времени метод сканирования будет выполнять это в рабочем потоке внутри. Можете ли вы опубликовать код?   -  person ifeegoo    schedule 01.10.2015


Ответы (2)


Вы должны сделать все в фоновом режиме, чтобы запустить липкую службу, и в onStartCommand этой службы начать сканирование.

package com.myapp.services;

import java.util.List;

import android.annotation.TargetApi;
import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.preference.PreferenceManager;
import android.support.v4.content.LocalBroadcastManager;
import android.text.TextUtils;
import android.widget.Toast;

import com.myapp.R;

/**Both RX and RSSI (Received Signal Strength Indication) are indications of the power level being received 
 * by an antenna
 * The difference between RX and RSSI is that RX is measured in milliWatts (mW) or decibel-milliwatts (dBm) 
 * whereas RSSI is a signal strength percentage—the higher the RSSI number, the stronger the signal
 *
 */

@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
public class BeaconService extends Service implements BluetoothAdapter.LeScanCallback{
    private static final String TAG = BeaconService.class.getSimpleName();

    private BluetoothGatt btGatt;
    private BluetoothAdapter mBluetoothAdapter;

    @Override
    public void onCreate() {
        super.onCreate();
        writeLine("Automate service created...");
        getBTService();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        writeLine("Automate service start...");
        if (!isBluetoothSupported()) {
            Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
            stopSelf();
        }else{
            if(mBluetoothAdapter!=null && mBluetoothAdapter.isEnabled()){
                startBLEscan();                     
            }else{
                stopSelf();
            }
        }
        return START_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onDestroy() {
        writeLine("Automate service destroyed...");
        stopBLEscan();
        super.onDestroy();

        if(btGatt!=null){
            btGatt.disconnect();
            btGatt.close();
            btGatt = null;
        }
    }

    @Override
    public boolean stopService(Intent name) {
        writeLine("Automate service stop...");
        stopSelf();
        return super.stopService(name);
    }

    // Initializes a Bluetooth adapter.  For API level 18 and above, get a reference to
    // BluetoothAdapter through BluetoothManager.
    public BluetoothAdapter getBTService(){
        BluetoothManager btManager = (BluetoothManager) getApplicationContext().getSystemService(Context.BLUETOOTH_SERVICE);
        mBluetoothAdapter = (BluetoothAdapter) btManager.getAdapter();
        return mBluetoothAdapter;
    }

    public boolean isBluetoothSupported() {
        return this.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE);
    }

    public void startBLEscan(){
        mBluetoothAdapter.startLeScan(this);
    }

    public void stopBLEscan(){
        mBluetoothAdapter.stopLeScan(this);
    }

    /**
     * 
     * @param enable
     */
    public void scanLeDevice(final boolean enable) {
        if (enable) {
            startBLEscan();
        } else {
            stopBLEscan();
        }
    }

    public static void enableDisableBluetooth(boolean enable){
        BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (bluetoothAdapter != null) {
            if(enable) {
                bluetoothAdapter.enable();
            }else{
                bluetoothAdapter.disable();
            }
        }
    }

    @Override
    public void onLeScan(final BluetoothDevice device, final int rssi, byte[] scanRecord) {
        if(device!=null && device.getName()!=null){
            //Log.d(TAG + " onLeScan: ", "Name: "+device.getName() + "Address: "+device.getAddress()+ "RSSI: "+rssi);
            if(rssi > -90 && rssi <-1){
                writeLine("Automate service BLE device in range: "+ device.getName()+ " "+rssi);
                if (device.getName().equalsIgnoreCase("NCS_Beacon") || device.getName().equalsIgnoreCase("estimote")) {
                    //This Main looper thread is main for connect gatt, don't remove it
                    // Although you need to pass an appropriate context getApplicationContext(),
                    //Here if you use Looper.getMainLooper() it will stop getting callback and give internal exception fail to register //callback
                    new Handler(getApplicationContext().getMainLooper()).post(new Runnable() {
                        @Override
                        public void run() {
                            btGatt = device.connectGatt(getApplicationContext(), false, bleGattCallback);
                            Log.e(TAG, "onLeScan btGatt value returning from connectGatt "+btGatt);
                        }
                    });
                }
                stopBLEscan();  
            }else{
                //Log.v("Device Scan Activity", device.getAddress()+" "+"BT device is still too far - not connecting");
            }
        }
    }

    BluetoothGattCallback bleGattCallback = new BluetoothGattCallback() {

        @Override
        public void onConnectionStateChange(final BluetoothGatt gatt, int status, int newState) {
            super.onConnectionStateChange(gatt, status, newState);
            writeLine("Automate service connection state: "+ newState);
            if (newState == android.bluetooth.BluetoothProfile.STATE_CONNECTED){
                writeLine("Automate service connection state: STATE_CONNECTED");
                Log.v("BLEService", "BLE Connected now discover services");
                Log.v("BLEService", "BLE Connected");
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        writeLine("Automate service go for discover services");
                        gatt.discoverServices();
                    }
                }).start();
            }else if (newState == android.bluetooth.BluetoothProfile.STATE_DISCONNECTED){
                writeLine("Automate service connection state: STATE_DISCONNECTED");
                Log.v("BLEService", "BLE Disconnected");
            }
        }

        @Override
        public void onServicesDiscovered(final BluetoothGatt gatt, int status) {
            super.onServicesDiscovered(gatt, status);
            if (status == BluetoothGatt.GATT_SUCCESS) {
                writeLine("Automate service discover service: GATT_SUCCESS");
                Log.v("BLEService", "BLE Services onServicesDiscovered");
                //Get service
                List<BluetoothGattService> services = gatt.getServices();
                writeLine("Automate service discover service imei: " +imei);
            }
        }

        @Override
        public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic,  int status) {
            super.onCharacteristicRead(gatt, characteristic, status);
        }

        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
            super.onCharacteristicChanged(gatt, characteristic);
        }
    };

    private void writeLine(final String message) {
        Handler h = new Handler(getApplicationContext().getMainLooper());
        // Although you need to pass an appropriate context
        h.post(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(getApplicationContext(),message,Toast.LENGTH_SHORT).show();
            }
        });
    }

}

В манифесте.xml

<uses-feature
        android:name="android.hardware.bluetooth_le"
        android:required="true" />

    <!-- Permission for bluetooth -->
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />

 <service
            android:name="com.myapp.services.BeaconService"
            android:enabled="true"
            android:exported="false" />
person Ready Android    schedule 16.09.2016
comment
ты лучший. - person LEMUEL ADANE; 10.03.2019
comment
Это не работает. Не могли бы вы помочь??. У меня есть клиентское приложение и серверное приложение, в котором код фоновой службы написан вами. Но клиент не может сканировать приложение серверного устройства. - person Priyanka Singhal; 01.05.2019
comment
@priyankasinghal, вы уверены, что ваш сервис запускается должным образом? Какова ваша целевая версия SDK в build.gradle? - person Ready Android; 02.05.2019

Используйте сервис для сканирования и подключения устройств ble, когда приложение находится в фоновом режиме в Android.

package com.example.tracker.service;

import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanSettings;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.Log;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.SeekBar;
import android.widget.Toast;

import com.google.firebase.auth.FirebaseAuth;
import com.example.tracker.R;
import com.example.tracker.utils.SampleGattAttributes;
import com.example.tracker.utils.SharedPreferencesUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;

import static com.example.tracker.constant.SharedFreferencesConstant.KEY_SP_MOBILE_NUMBER;

/**
 * Created by Jprashant on 12/9/17.
 */

public class BackgroundService extends Service{

    private int scanPeriod;

    Context context;
    String TAG="BackgroundService";
    private BluetoothAdapter mBluetoothAdapter;
    private boolean mScanning;
    private Handler mHandler;
    public String[] advDataTypes = new String[256];

    ArrayList<BluetoothDevice> bluetoothDeviceArrayList=new ArrayList<>();
    ArrayList<BluetoothDevice> bluetoothDeviceArrayListTwo=new ArrayList<>();
    private static final int REQUEST_ENABLE_BT = 1;
    // Stops scanning after 10 seconds.
    private static final long SCAN_PERIOD = 10000;


    /*Connect Ble Device*/



    String deviceId;
    public static String arrayDidOpnSec2;

    BluetoothGattService gattService4;
    public static ArrayList<BluetoothGattCharacteristic> lastCharacteristic;


    //    AlertDialog.Builder alertDialog;
    private float avgRssi = 0.0f;
    // private Dialog dialog;
    private BluetoothLeService mBluetoothLeService;
    private boolean mConnected = false;
    private ArrayList<ArrayList<BluetoothGattCharacteristic>> mGattCharacteristics = new ArrayList();

    //service and char uuid
    private static final int TRACKER_ON_OFF = 2;
    private static final UUID TRACER_TRIPPLE_PRESS_SERVICE=UUID.fromString("edfec62e-9910-0bac-5241-d8bda6932a2f");
    private static final UUID TRACKER_TRIPPLE_PRESS_CHAR=UUID.fromString("772ae377-b3d2-4f8e-4042-5481d1e0098c");
    private static final UUID IMMEDIATE_ALERT_UUID = UUID.fromString("00001802-0000-1000-8000-00805f9b34fb");
    private static final UUID ALERT_LEVEL_UUID = UUID.fromString("00002a06-0000-1000-8000-00805f9b34fb");

    private Button btnSMS;
    public static String mDeviceName,mDeviceAddress,connectionStatus;

    /*-------------------------------------------------------------------------------*/

    public static final String PREFS_NAME = "PreferencesFile";

    public int deviceCount = 0;

    public String[] mData = new String[400];
    private Handler mHandler1;

    private ListView listItems;


    /*--------for > 21--------------*/
    private BluetoothLeScanner mLEScanner;
    private ScanSettings settings;
    private List<ScanFilter> filters;
    private BluetoothGatt mGatt;




    public BackgroundService() {

    }

    public BackgroundService(Context context) {
        this.context = context;
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

//        getting systems default ringtone

        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(getApplicationContext(),"CALL YOUR METHOD",Toast.LENGTH_LONG).show();

                mHandler = new Handler();

                // Use this check to determine whether BLE is supported on the device.  Then you can
                // selectively disable BLE-related features.
                if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
                    Toast.makeText(context, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
                }

                // Initializes a Bluetooth adapter.  For API level 18 and above, get a reference to
                // BluetoothAdapter through BluetoothManager.
                final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
                mBluetoothAdapter = bluetoothManager.getAdapter();

                // Checks if Bluetooth is supported on the device.
                if (mBluetoothAdapter == null) {
                    Toast.makeText(context, R.string.error_bluetooth_not_supported, Toast.LENGTH_SHORT).show();
                    return;
                }


                for (int i = 0; i < 256; i += REQUEST_ENABLE_BT) {
                    advDataTypes[i] = "Unknown Data Type";
                }
                advDataTypes[REQUEST_ENABLE_BT] = "Flags";
                advDataTypes[2] = "Incomplete List of 16-bit Service Class UUIDs";
                advDataTypes[3] = "Complete List of 16-bit Service Class UUIDs";
                advDataTypes[4] = "Incomplete List of 32-bit Service Class UUIDs";
                advDataTypes[5] = "Complete List of 32-bit Service Class UUIDs";
                advDataTypes[6] = "Incomplete List of 128-bit Service Class UUIDs";
                advDataTypes[7] = "Complete List of 128-bit Service Class UUIDs";
                advDataTypes[8] = "Shortened Local Name";
                advDataTypes[9] = "Complete Local Name";
                advDataTypes[10] = "Tx Power Level";
                advDataTypes[13] = "Class of LocalDevice";
                advDataTypes[14] = "Simple Pairing Hash";
                advDataTypes[15] = "Simple Pairing Randomizer R";
                advDataTypes[16] = "LocalDevice ID";
                advDataTypes[17] = "Security Manager Out of Band Flags";
                advDataTypes[18] = "Slave Connection Interval Range";
                advDataTypes[20] = "List of 16-bit Solicitaion UUIDs";
                advDataTypes[21] = "List of 128-bit Solicitaion UUIDs";
                advDataTypes[22] = "Service Data";
                advDataTypes[23] = "Public Target Address";
                advDataTypes[24] = "Random Target Address";
                advDataTypes[25] = "Appearance";
                advDataTypes[26] = "Advertising Interval";
                advDataTypes[61] = "3D Information Data";
                advDataTypes[255] = "Manufacturer Specific Data";
                scanPeriod = getApplicationContext().getSharedPreferences(PREFS_NAME, 0).getInt("scan_interval", 6000);
                scanTrackerDevices();
            }
        }, 10000);




        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    public void scanTrackerDevices(){
        Log.e(TAG,"scanTrackerDevices");

        if (!mBluetoothAdapter.isEnabled()) {
            if (!mBluetoothAdapter.isEnabled()) {
                Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            }
        }
        scanLeDevice(true);
    }


    private void scanLeDevice(final boolean enable) {
        bluetoothDeviceArrayList.clear();
        if (enable) {
            // Stops scanning after a pre-defined scan period.
            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    mScanning = false;
                    mBluetoothAdapter.stopLeScan(mLeScanCallback);

                    int arraySize=bluetoothDeviceArrayListTwo.size();
                    Log.e(TAG,"bluetoothDeviceArrayListTwo Size in scan :"+arraySize);

                     for (int i=0;i<bluetoothDeviceArrayListTwo.size();i++){
                        BluetoothDevice bluetoothDevice=bluetoothDeviceArrayListTwo.get(i);
                        Log.e(TAG,"Device Name in scan :"+bluetoothDevice.getName());
                        Log.e(TAG,"Device Address in scan :"+bluetoothDevice.getAddress());

                         if (i==0){
                             mBluetoothLeService.connect(bluetoothDevice.getAddress());
                         }
                        }
                }
            }, scanPeriod);

            mScanning = true;
            mBluetoothAdapter.startLeScan(mLeScanCallback);
        } else {
            mScanning = false;
            mBluetoothAdapter.stopLeScan(mLeScanCallback);
        }
    }




    private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
        public void onLeScan(final BluetoothDevice device, final int rssi, final byte[] scanRecord) {

                    String d = "";
                    String rd = "";
                    String h = "0123456789ABCDEF";
                    int ln = 0;
                    int i = 0;
                    while (i < scanRecord.length) {
                        int x = scanRecord[i] & 255;
                        rd = new StringBuilder(String.valueOf(rd)).append(h.substring(x / 16, (x / 16) + REQUEST_ENABLE_BT)).append(h.substring(x % 16, (x % 16) +REQUEST_ENABLE_BT)).toString();
                        if (i == ln) {
                            ln = (i + x) + REQUEST_ENABLE_BT;
                            if (x == 0) {
                                break;
                            }
                            d = new StringBuilder(String.valueOf(d)).append("\r\n     Length: ").append(h.substring(x / 16, (x / 16) + REQUEST_ENABLE_BT)).append(h.substring(x % 16, (x % 16) +REQUEST_ENABLE_BT)).toString();
                            i += REQUEST_ENABLE_BT;
                            x = scanRecord[i] & 255;
                            d = new StringBuilder(String.valueOf(d)).append(",   Type :").append(h.substring(x / 16, (x / 16) + REQUEST_ENABLE_BT)).append(h.substring(x % 16, (x % 16) + REQUEST_ENABLE_BT)).append(" = ").append(advDataTypes[x]).append(",   Value: ").toString();
                            rd = new StringBuilder(String.valueOf(rd)).append(h.substring(x / 16, (x / 16) + REQUEST_ENABLE_BT)).append(h.substring(x % 16, (x % 16) + REQUEST_ENABLE_BT)).toString();

                        } else {
                            d = new StringBuilder(String.valueOf(d)).append(" ").append(h.substring(x / 16, (x / 16) + REQUEST_ENABLE_BT)).append(h.substring(x % 16, (x % 16) +REQUEST_ENABLE_BT)).toString();
                        }
                        i += REQUEST_ENABLE_BT;
                    }


                    Log.e(TAG,"UUID : "+device.getUuids());
                    String[] arrayDeviceName=String.valueOf(device.getName()).split(" ");
                    String deviceName0=arrayDeviceName[0];
                        bluetoothDeviceArrayListTwo.add(device);


        }
    };



    /*-------------------Connect BLE---------------------------------------------*/

        private Handler mHandler2;


        public final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {

        public void onReceive(Context context, Intent intent)
        {
            String action = intent.getAction();


            if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action))
            {
                numberOfRssi = 0;
                avgRssi = 0.0f;
                mConnected = true;
                updateConnectionState(R.string.connected);
                mHandler2.postDelayed(startRssi, 300);
                Log.e(TAG,"ACTION_GATT_CONNECTED");

            }


            else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
                mConnected = false;
                updateConnectionState(R.string.disconnected);
                Log.e(TAG,"ACTION_GATT_DISCONNECTED");


            } else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
                displayGattServicesForDimmer(mBluetoothLeService.getSupportedGattServices());// For dimmer

                Log.e(TAG,"ACTION_GATT_SERVICES_DISCOVERED");


            } else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {
                Log.e(TAG,"ACTION_DATA_AVAILABLE");
                String unknownServiceString = context.getResources().getString(R.string.unknown_service);
                displayDimmerData("<<" + SampleGattAttributes.lookup(intent.getStringExtra(BluetoothLeService.CHARACTERISTIC_UUID), unknownServiceString) + ">> Value: " + intent.getStringExtra(BluetoothLeService.EXTRA_DATA) + "]");
                displayDimmer2(intent.getStringExtra(BluetoothLeService.EXTRA_DATA));


            } else if (BluetoothLeService.ACTION_GATT_RSSI_UPDATE.equals(action)) {
                updateRssi(intent.getIntExtra(BluetoothLeService.EXTRA_DATA, -400));

            } else if (BluetoothLeService.ACTION_GATT_WRITE_FAILED.equals(action)) {
                Log.e(TAG,"ACTION_GATT_WRITE_FAILED");

            }

        }
    };







    /*------------------------------------------------------------------------*/

    @Override
    public void onCreate() {
        super.onCreate();
//    -------------------Connect Ble--------------------------------------

        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED);
        intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED);
        intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED);
        intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE);
        intentFilter.addAction(BluetoothLeService.ACTION_GATT_RSSI_UPDATE);
        intentFilter.addAction(BluetoothLeService.ACTION_GATT_WRITE_FAILED);

        Log.e(TAG,"OnResume()");

        getApplicationContext().registerReceiver(mGattUpdateReceiver, intentFilter);
        getApplicationContext().bindService(new Intent(getApplicationContext(), BluetoothLeService.class), mServiceConnection, 1);

        mHandler2=new Handler();
    }





    private BluetoothGattCharacteristic mNotifyCharacteristic;
    private final ServiceConnection mServiceConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName componentName, IBinder service) {
            mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService();
            if (!mBluetoothLeService.initialize()) {
                Log.e(TAG, "Unable to initialize Bluetooth");

            }
        }
        public void onServiceDisconnected(ComponentName componentName) {
            mBluetoothLeService = null;
        }
    };
    private boolean notificationActive = true;
    private int numberOfRssi = 0;


    private Runnable startRssi = new Runnable() {
        public void run() {
            if (mConnected) {
                mBluetoothLeService.readRemoteRssi();
                mHandler2.postDelayed(startRssi, 200);
            }
        }
    };



    public BluetoothGatt getmGatt() {
        return mGatt;
    }

    //code from DeviceControlActivity
    private void updateConnectionState(final int resourceId) {
        connectionStatus= String.valueOf(resourceId);
        Log.e(TAG,"Resource ID"+resourceId);

    }

    private void displayDimmerData(String data){
        Log.e(TAG,"Display Data :"+data);


    }

    private void displayDimmer2(String data){
        Log.e(TAG,"display Dimmer2"+data);


        String sosString = data.substring(0, Math.min(data.length(), 3));
        Log.e(TAG,"SOS String :"+sosString);
        if (sosString.equals("SOS")){
            Intent callIntent = new Intent(Intent.ACTION_CALL);
                callIntent.setData(Uri.parse("tel:"+ SharedPreferencesUtils.getStringFromSharedPreferences(KEY_SP_MOBILE_NUMBER,getApplicationContext())));
                callIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                getApplicationContext().startActivity(callIntent);
        }

    }

    private void updateRssi(int data) {
        if (data > -400) {
            if (this.numberOfRssi > 10) {
                this.avgRssi = ((9.0f * this.avgRssi) + ((float) data)) / 10.0f;
            } else {
                this.avgRssi = (this.avgRssi + ((float) data)) / 2.0f;
                this.numberOfRssi++;
            }
            connectionStatus="Connected, RSSI:" + data + ",  Avg:" + Math.round(this.avgRssi);

        }
    }

    /*-------------------------disaplay gatt service for dimmer----------------------*/
    private void displayGattServicesForDimmer(List<BluetoothGattService> gattServices) {

        if (gattServices != null) {

            String unknownServiceString = getResources().getString(R.string.unknown_service);
            String unknownCharaString = getResources().getString(R.string.unknown_characteristic);
            ArrayList<HashMap<String, String>> gattServiceData = new ArrayList();
            ArrayList<ArrayList<HashMap<String, String>>> gattCharacteristicData = new ArrayList();
            this.mGattCharacteristics = new ArrayList();


            for (BluetoothGattService gattService : gattServices) {
                HashMap<String, String> currentServiceData = new HashMap();
                String uuid = gattService.getUuid().toString();
                currentServiceData.put("NAME", SampleGattAttributes.lookup(uuid, unknownServiceString));
                currentServiceData.put("UUID", uuid);
                gattServiceData.add(currentServiceData);
                ArrayList<HashMap<String, String>> gattCharacteristicGroupData = new ArrayList();
                List<BluetoothGattCharacteristic> gattCharacteristics = gattService.getCharacteristics();
                ArrayList<BluetoothGattCharacteristic> charas = new ArrayList();


                for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
                    charas.add(gattCharacteristic);
                    HashMap<String, String> currentCharaData = new HashMap();
                    uuid = gattCharacteristic.getUuid().toString();
                    currentCharaData.put("NAME", "\t\t\t<<" + SampleGattAttributes.lookup(uuid, unknownCharaString) + ">>");
                    currentCharaData.put("UUID", "\t\t\tUUID: 0x" + uuid.substring(4, 8) + ", Properties: " + translateProperties(gattCharacteristic.getProperties()));
                    gattCharacteristicGroupData.add(currentCharaData);

                    Log.i(TAG,"CUrrent CHARACTERISTIC DATA"+currentCharaData);
                    Log.i(TAG,"UUID : "+uuid.substring(4, 8));
                    Log.i(TAG,"Proprties : "+gattCharacteristic.getProperties());
                    Log.i(TAG,"Translate Proprties : "+translateProperties(gattCharacteristic.getProperties()));
                    Log.i(TAG,"char list"+gattCharacteristicData.toString());

                }
                gattService4=gattService;
                this.mGattCharacteristics.add(charas);
            }

            if (mGattCharacteristics.get(3)!=null) {
                lastCharacteristic = new ArrayList<>(mGattCharacteristics.get(3));
                enableNotifyOfCharcteristicForDimmer(lastCharacteristic);

            }


        }
    }

    private String translateProperties(int properties) {
        String s = "";
        if ((properties & 1) > 0) {
            s = new StringBuilder(String.valueOf(s)).append("/Broadcast").toString();
        }
        if ((properties & 2) > 0) {
            s = new StringBuilder(String.valueOf(s)).append("/Read").toString();
        }
        if ((properties & 4) > 0) {
            s = new StringBuilder(String.valueOf(s)).append("/WriteWithoutResponse").toString();
        }
        if ((properties & 8) > 0) {
            s = new StringBuilder(String.valueOf(s)).append("/Write").toString();
        }
        if ((properties & 16) > 0) {
            s = new StringBuilder(String.valueOf(s)).append("/Notify").toString();
        }
        if ((properties & 32) > 0) {
            s = new StringBuilder(String.valueOf(s)).append("/Indicate").toString();
        }
        if ((properties & 64) > 0) {
            s = new StringBuilder(String.valueOf(s)).append("/SignedWrite").toString();
        }
        if ((properties & 128) > 0) {
            s = new StringBuilder(String.valueOf(s)).append("/ExtendedProperties").toString();
        }
        if (s.length() > 1) {
            return s.substring(1);
        }
        return s;
    }


    //    Enable Characteristic for dimmer
    public void enableNotifyOfCharcteristicForDimmer(ArrayList<BluetoothGattCharacteristic> lastCharacteristic){

        if(mGattCharacteristics!=null) {

            checkCharacteristicPresent(lastCharacteristic.get(0));
            mBluetoothLeService.setCharacteristicNotification(lastCharacteristic.get(0), true);
            notificationActive = true;
            Log.e(TAG,"Characteristic index : "+0+":\nM GATT CHARACTERISTIC AT "+"Service 4 : CHAR"+ 0 +" :" +lastCharacteristic.get(0).toString());

            checkCharacteristicPresent(lastCharacteristic.get(1));
            mBluetoothLeService.setCharacteristicNotification(lastCharacteristic.get(1), true);
            notificationActive = true;
            Log.e(TAG,"Characteristic index : "+1+":\nM GATT CHARACTERISTIC AT "+"Service 4 : CHAR"+ 1 +" :" +lastCharacteristic.get(1).toString());

            checkCharacteristicPresent(lastCharacteristic.get(2));
            mBluetoothLeService.setCharacteristicNotification(lastCharacteristic.get(2), true);
            notificationActive = true;
            Log.e(TAG,"Characteristic index : "+2+":\nM GATT CHARACTERISTIC AT "+"Service 4 : CHAR"+ 2 +" :" +lastCharacteristic.get(2).toString());

            checkCharacteristicPresent(lastCharacteristic.get(3));
            mBluetoothLeService.setCharacteristicNotification(lastCharacteristic.get(3), true);
            notificationActive = true;
            Log.e(TAG,"Characteristic index : "+3+":\nM GATT CHARACTERISTIC AT "+"Service 4 : CHAR"+ 3 +" :" +lastCharacteristic.get(3).toString());

            checkCharacteristicPresent(lastCharacteristic.get(4));
            mBluetoothLeService.setCharacteristicNotification(lastCharacteristic.get(4), true);
            notificationActive = true;
            Log.e(TAG,"Characteristic index : "+4+":\nM GATT CHARACTERISTIC AT "+"Service 4 : CHAR"+ 4 +" :" +lastCharacteristic.get(4).toString());

            checkCharacteristicPresent(lastCharacteristic.get(5));
            mBluetoothLeService.setCharacteristicNotification(lastCharacteristic.get(5), true);
            notificationActive = true;
            Log.e(TAG,"Characteristic index : "+5+":\nM GATT CHARACTERISTIC AT "+"Service 4 : CHAR"+ 5 +" :" +lastCharacteristic.get(5).toString());

            checkCharacteristicPresent(lastCharacteristic.get(2));
            mBluetoothLeService.setCharacteristicNotification(lastCharacteristic.get(2), true);
            notificationActive = true;
            Log.e(TAG,"Characteristic index : "+2+":\nM GATT CHARACTERISTIC AT "+"Service 4 : CHAR"+ 2 +" :" +lastCharacteristic.get(2).toString());

        }
    }

    //  Check the type of characteristic i.e READ/WRITE/NOTIFY
    public void checkCharacteristicPresent(BluetoothGattCharacteristic characteristic) {


        int charaProp = characteristic.getProperties();
        Log.e(TAG, "checkCharacteristicPresent Prop : " + charaProp);
        mBluetoothLeService.setCurrentCharacteristic(characteristic);

        if ((charaProp & 2) > 0) {
            Log.e(TAG, "CharProp & 2 : " + charaProp);
            mBluetoothLeService.readCharacteristic(characteristic);
        } 
        if ((charaProp & 16) > 0) {
            Log.e(TAG, "CharProp & 16 : " + charaProp);
            mNotifyCharacteristic = characteristic;

        } else {
            if (mNotifyCharacteristic != null) {
                mBluetoothLeService.setCharacteristicNotification(mNotifyCharacteristic, false);
                mNotifyCharacteristic = null;
            }
        }

        if ((charaProp & 8) > 0 || (charaProp & 4) > 0) {
            Log.e(TAG, "CharProp & 4 : " + charaProp);
        } else {
            Log.e(TAG, "Else : " + charaProp);

        }
    }


}

Напишите этот код в manifest.xml

<service android:name=".service.BackgroundService" />
person j.prashant    schedule 03.11.2017