Я строю ИнтерСервис. Эта служба получает данные с устройства Bluetooth.
import android.annotation.SuppressLint;
import android.app.IntentService;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
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.BluetoothProfile;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationCompat;
import android.util.Log;
import android.widget.Toast;
import com.example.dcubeandroid.dietcontrol.MyDialog;
import com.example.dcubeandroid.dietcontrol.R;
import com.example.dcubeandroid.dietcontrol.apiRequest.iotrequests.DosimeterDataRequest;
import com.example.dcubeandroid.dietcontrol.datasyncingjobs.DosimeterSyncingJob;
import com.example.dcubeandroid.dietcontrol.dosimeter.protocol.BLEUtils;
import com.example.dcubeandroid.dietcontrol.dosimeter.protocol.CRC8Calculator;
import com.example.dcubeandroid.dietcontrol.dosimeter.protocol.MeasurementConverter;
import com.example.dcubeandroid.dietcontrol.dosimeter.protocol.PolismartConstants;
import com.example.dcubeandroid.dietcontrol.utils.AppConstants;
import com.example.dcubeandroid.dietcontrol.utils.Global;
import com.example.dcubeandroid.dietcontrol.utils.PreferenceHandler;
import com.example.dcubeandroid.dietcontrol.utils.Utilities;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
import java.util.UUID;
public class DosimeterDataSensingService extends IntentService {
private static final String TAG = "DosimeterDataSensingService";
public static boolean isStarted = false;
private MeasurementConverter measurementConvertor;
private Context mContext;
private int mStatus;
private BluetoothDevice mDevice;
private BluetoothGatt mConnGatt;
private boolean notificationsEnabled;
private long dosimeterScanningTime;
private boolean isThreadStarted = false;
private List<DosimeterDataRequest.DataBean> dosimeterDataList;
private DosimeterDataRequest dosimeterDataRequest;
private String macAddress;
private boolean isRecordingEnabled = false;
private String dose = "";
private int battery = -1;
/**
* Creates an IntentService. Invoked by your subclass's constructor.
*
* @param name Used to name the worker thread, important only for debugging.
*/
public DosimeterDataSensingService(String name) {
super(name);
}
public DosimeterDataSensingService() {
super(null);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
protected void onHandleIntent(@Nullable Intent intent) {
dosimeterDataRequest = new DosimeterDataRequest();
dosimeterDataList = new ArrayList<>();
mContext = this;
measurementConvertor = new MeasurementConverter(this);
String scanningTime = PreferenceHandler.readString(this, PreferenceHandler.DOSIMETER_SCANNING_TIME, null);
Log.i("SCANNINGTIME", scanningTime);
if (scanningTime == null) {
dosimeterScanningTime = 0;
} else {
dosimeterScanningTime = Long.parseLong(scanningTime);
}
String mac = PreferenceHandler.readString(this, PreferenceHandler.DM_MAC, null);
if (mac != null) {
connectDosimeter(mac);
}
}
@Override
public void onCreate() {
super.onCreate();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = createNotificationChannel();
}
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, getString(R.string.default_notification_channel_id))
.setSmallIcon(R.drawable.logoxhdpi)
.setCategory(Notification.CATEGORY_SERVICE)
.setContentTitle("Cardio App")
.setContentText("Getting data from Dosimeter")
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
Notification notification = mBuilder.build();
startForeground((int) (System.currentTimeMillis() + 1), notification);
isStarted = true;
if (PreferenceHandler.readString(this, PreferenceHandler.TYPE_USER, null).equals("2")) {
checkDosage();
}
checkBattery();
}
Intent isBatteryLow = new Intent(AppConstants.ACTION_LOW_BATTERY_RECEIVED);
@Override
public void onDestroy() {
isStarted = false;
disconnectDosimeter();
super.onDestroy();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
/**
* connect dosimeter
*
* @param mac mac address of dosimeter
*/
@SuppressLint("LongLogTag")
private void connectDosimeter(String mac) {
macAddress = mac;
// Toast.makeText(getApplicationContext(), "Dosimeter connected", Toast.LENGTH_LONG).show();
Log.d("Global:: ", "Dosimeter Service Started");
mStatus = BluetoothProfile.STATE_DISCONNECTED;
BluetoothAdapter adapter = com.example.dcubeandroid.dietcontrol.zephyerble.BLEUtils.getAdapter();
isRecordingEnabled = true;
mDevice = adapter.getRemoteDevice(mac);
if (mDevice == null) {
mContext.sendBroadcast(new Intent(DosimeterConstants.ACTION_DOSIMETER_DISCONNECTED));
} else
// connect to Gatt
if ((mConnGatt == null) && (mStatus == BluetoothProfile.STATE_DISCONNECTED)) {
// try to connect
/*if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
mConnGatt = mDevice.connectGatt(mContext, false, mBluetoothGattCallback, 2);
} else {*/
mConnGatt = mDevice.connectGatt(mContext, false, mBluetoothGattCallback);
//}
mStatus = BluetoothProfile.STATE_CONNECTING;
//Toast.makeText(this, "Dosimeter connected", Toast.LENGTH_LONG).show();
} else {
if (mConnGatt != null) {
// re-connect and re-discover Services
mConnGatt.connect();
mConnGatt.discoverServices();
//mContext.sendBroadcast(new Intent(DosimeterConstants.ACTION_DOSIMETER_DISCONNECTED));
} else {
Log.e(TAG, "state error");
disconnectionHandler.postDelayed(disconnectionRunnable, dosimeterScanningTime);
// Toast.makeText(this, "Dosimeter connection error", Toast.LENGTH_LONG).show();
}
}
}
private BluetoothGattCharacteristic infoCharacteristic;
/**
* bluetooth gatt callback
*/
private BluetoothGattCallback mBluetoothGattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
if (newState == BluetoothProfile.STATE_CONNECTED) {
mStatus = newState;
mConnGatt.discoverServices();
//broadcast about connection
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
mStatus = newState;
}
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
int i = 0;
for (BluetoothGattService service : gatt.getServices()) {
if ((service == null) || (service.getUuid() == null)) {
continue;
}
if (DosimeterConstants.SERVICE_IMMEDIATE_ALERT.equalsIgnoreCase(service.getUuid().toString())) {
infoCharacteristic = service.getCharacteristic(UUID.fromString(DosimeterConstants.CHAR_ALERT_LEVEL));
}
//get charactersticks of third service...............
if (i == 2)
getCharacterSticsOfLastService(service, gatt, i);
i++;
}
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
if (DosimeterConstants.READ_DATA_INSTRUMENT.equalsIgnoreCase(characteristic.getUuid().toString())) {
byte[] value = characteristic.getValue();
if (CRC8Calculator.getCRC8(value, value.length) == value[0]) {
readStatusPacket(value);
//send notify write command
boolean submitted = BLEUtils.SetNotificationForCharacteristic(gatt, characteristic, notificationsEnabled ? BLEUtils.Notifications.DISABLED : BLEUtils.Notifications.NOTIFY);
if (submitted) {
notificationsEnabled = !notificationsEnabled;
}
}
}
}
}
@SuppressLint("LongLogTag")
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
Log.i(TAG, "on characteristicChanged=" + characteristic.getUuid().toString());
if (DosimeterConstants.READ_DATA_INSTRUMENT.equalsIgnoreCase(characteristic.getUuid().toString())) {
byte[] value = characteristic.getValue();
if (CRC8Calculator.getCRC8(value, value.length) == value[0]) {
readStatusPacket(value);
}
}
}
};
private void getCharacterSticsOfLastService(BluetoothGattService service, BluetoothGatt gatt, int i) {
BluetoothGattService blueToothGattService = service == null ? gatt.getServices().get(i) : gatt.getService(service.getUuid());
List<BluetoothGattCharacteristic> characteristics = blueToothGattService.getCharacteristics();
for (BluetoothGattCharacteristic bluetoothGattCharacteristic : characteristics) {
gatt.readCharacteristic(bluetoothGattCharacteristic);
// the engine parses through the data of the btgattcharac and returns a wrapper characteristic
// the wrapper characteristic is matched with accepted bt gatt profiles, provides field types/values/units
// Characteristic charact = Engine.getInstance().getCharacteristic(bluetoothGattCharacteristic.getUuid());
}
}
/**
* read packet data for status
*
* @param paramArrayOfByte packet data in form of byte array
*/
private void readStatusPacket(byte[] paramArrayOfByte) {
}
@SuppressLint("LongLogTag")
public void disconnectDosimeter() {
Log.v("Dosimeter", "isRecordingEnabled" + isRecordingEnabled);
Log.v("Dosimeter", "Disconnecteddd");
}
}
Теперь этот IntentService использует эту переменную:
String scanningTime = PreferenceHandler.readString(this, PreferenceHandler.DOSIMETER_SCANNING_TIME, null);
Теперь, когда служба запущена, я хочу изменить значения этого «scanTime» ». Поэтому я создаю этот код в другом классе:
String dosimeterScanningTime = "newValue";
PreferenceHandler.writeString(getApplicationContext(), PreferenceHandler.DOSIMETER_SCANNING_TIME, dosimeterScanningTime!=null ? dosimeterScanningTime.toString() : null);
if (Build.VERSION.SDK_INT >= 26) {
stopService(new Intent(this, DosimeterDataSensingService.class));
startForegroundService(new Intent(this, DosimeterDataSensingService.class));
} else {
stopService(new Intent(this, DosimeterDataSensingService.class));
startService(new Intent(getApplicationContext(), DosimeterDataSensingService.class));
}
Теперь код работает без проблем или исключений, но если я не перезапущу свое приложение, значение «scanTime» в моем IntentService не изменится.
Если я перезапустил приложение, scanTime = newValue.
Как я могу их исправить?