Ошибка как ниже, я пытаюсь запустить эту службу для обеспечения текущих обновлений датчика, цель состоит в том, чтобы регистрировать события датчика, пока я не остановлю службу, мне просто нужно иметь возможность запустить эту службу, собирать данные пока я не остановлю службу:
android.app.RemoteServiceException: Bad notification for startForeground: java.lang.RuntimeException: invalid channel for service notification: Notification(channel=null pri=0 contentView=null vibrate=null sound=null defaults=0x0 flags=0x40 color=0x00000000 vis=PRIVATE)
Служба, которая запускается:
public class SensorService extends Service implements SensorEventListener {
private static final String TAG = "SensorService";
private static final int SCREEN_OFF_RECEIVER_DELAY = 100;
//10ms minimum due to Android/hardware limitations 9 gives more accurate 10ms intervals
private final short POLL_FREQUENCY = 9;
private long lastUpdate = -1;
private long curTime;
public static long fps;
public Messenger messageHandler;
private SensorManager sensorManager = null;
private WakeLock wakeLock = null;
private ExecutorService executor;
private Sensor sensor;
private Sensor accelerometer;
private Sensor gyroscope;
private Sensor pressure;
private Sensor magnetic;
private float[] accelerometerMatrix = new float[3];
private float[] gyroscopeMatrix = new float[3];
private float[] pressureMatrix = new float[1];
private float[] magneticMatrix = new float[3];
private void registerListener() {
sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_FASTEST);
sensorManager.registerListener(this, gyroscope, SensorManager.SENSOR_DELAY_FASTEST);
sensorManager.registerListener(this, pressure, SensorManager.SENSOR_DELAY_FASTEST);
sensorManager.registerListener(this, magnetic, SensorManager.SENSOR_DELAY_FASTEST);
}
private void unregisterListener() {
sensorManager.unregisterListener(this);
}
private final BroadcastReceiver receiver = new BroadcastReceiver() {
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override
public void onReceive(Context context, Intent intent) {
Log.i(TAG, "onReceive(" + intent + ")");
if (!Objects.equals(intent.getAction(), Intent.ACTION_SCREEN_OFF)) {
return;
}
Runnable runnable = new Runnable() {
public void run() {
Log.i(TAG, "Runnable executing...");
unregisterListener();
registerListener();
}
};
new Handler().postDelayed(runnable, SCREEN_OFF_RECEIVER_DELAY);
}
};
/* private void sendMessage(String state) {
Message message = Message.obtain();
switch (state) {
case "HIDE" :
message.arg1 = 0;
break;
case "SHOW":
message.arg1 = 1;
break;
}
try {
messageHandler.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}*/
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
public void onSensorChanged(SensorEvent event) {
sensor = event.sensor;
//Store data
int i = sensor.getType();
if (i == MainActivity.TYPE_ACCELEROMETER) {
accelerometerMatrix = event.values;
}else if (i == MainActivity.TYPE_GYROSCOPE) {
gyroscopeMatrix = event.values;
}else if (i == MainActivity.TYPE_PRESSURE) {
pressureMatrix = event.values;
}
else if (i == MainActivity.TYPE_MAGNETIC) {
magneticMatrix = event.values;
}
curTime = event.timestamp; // nanoseconds
// One update every POLL_FREQUENCY converted to nano
if((curTime - lastUpdate) > POLL_FREQUENCY*1000000) {
fps = ((curTime-lastUpdate)/1000000);
lastUpdate = curTime;
Log.d(TAG, "The data " + accelerometerMatrix[0]+
accelerometerMatrix[0]+
accelerometerMatrix[1]+
accelerometerMatrix[2]+
gyroscopeMatrix[0]+
gyroscopeMatrix[1]+
gyroscopeMatrix[2]+
magneticMatrix[0]+
accelerometerMatrix[1]+
magneticMatrix[2]
);
}
}
@Override
public void onCreate() {
super.onCreate();
startForeground(1, new Notification());
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
assert sensorManager != null;
accelerometer = sensorManager.getDefaultSensor(MainActivity.TYPE_ACCELEROMETER);
gyroscope = sensorManager.getDefaultSensor(MainActivity.TYPE_GYROSCOPE);
pressure = sensorManager.getDefaultSensor(MainActivity.TYPE_PRESSURE);
magnetic = sensorManager.getDefaultSensor(MainActivity.TYPE_MAGNETIC);
PowerManager wManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
assert wManager != null;
wakeLock = wManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Application:TAG");
registerReceiver(receiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));
executor = Executors.newSingleThreadExecutor();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
startForeground(Process.myPid(), new Notification());
registerListener();
wakeLock.acquire();
//Message handler for progress dialog
Bundle extras = intent.getExtras();
assert extras != null;
//messageHandler = (Messenger) extras.get("MESSENGER");
return START_STICKY;
}
@Override
public void onDestroy() {
//Show dialog
//sendMessage("SHOW");
//Unregister receiver and listener prior to executor shutdown
unregisterReceiver(receiver);
unregisterListener();
//Prevent new tasks from being added to thread
executor.shutdown();
Log.d(TAG, "Executor shutdown is called");
//Create new thread to wait for executor to clear queue and wait for termination
new Thread(new Runnable() {
public void run() {
try {
//Wait for all tasks to finish before we proceed
while (!executor.awaitTermination(1, TimeUnit.SECONDS)) {
Log.i(TAG, "Waiting for current tasks to finish");
}
Log.i(TAG, "No queue to clear");
} catch (InterruptedException e) {
Log.e(TAG, "Exception caught while waiting for finishing executor tasks");
executor.shutdownNow();
Thread.currentThread().interrupt();
}
if (executor.isTerminated()) {
//Stop everything else once the task queue is clear
// wakeLock.release();
stopForeground(true);
//Dismiss progress dialog
//sendMessage("HIDE");
}
}
}).start();
}
}
Я надеюсь, что кто-то увидит очевидную ошибку, которую я, вероятно, делаю. Спасибо.