How can I launch my Android app by detecting shake using foreground service for API level upper 27?

241 Views Asked by At

I am using foreground service in my App to detect shake and launch app from anywhere to MainActivity, After doing on some code now I'm stucked with the problem. I hope someone will come up with the solution or suggest me how to make this work. Yes, I did run the app, after I run whenever I shake my phone the service thus the app gets closed automatically. My service code has been given below

public class ExampleService extends Service {
    private SensorManager sensorManager;
    private float acelVal;
    private float acelLast;
    private float shake;

    public ExampleService() {
    }

    @Override
    public void onCreate() {
        super.onCreate();




    }


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




        Intent notificationIntent=new Intent(this,MainActivity.class);
        PendingIntent pendingIntent=PendingIntent.getActivity(this,0,notificationIntent,0);

        Notification notification=new NotificationCompat.Builder(this,CHANNEL_ID)
                .setContentTitle("Example service")
                .setContentText("Example for shaking")
                .setSmallIcon(R.drawable.ic_android)
                .setContentIntent(pendingIntent)
                .build();



        sensorManager=(SensorManager)getSystemService(Context.SENSOR_SERVICE);
        sensorManager.registerListener(sensorListener,sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),SensorManager.SENSOR_DELAY_NORMAL);
        acelVal=SensorManager.GRAVITY_EARTH;
        acelLast=SensorManager.GRAVITY_EARTH;
        shake=0.00f;

        startForeground(1,notification);

        return START_NOT_STICKY;
    }

    public final SensorEventListener sensorListener= new SensorEventListener() {
        @Override
        public void onSensorChanged(SensorEvent sensorEvent) {
            float x=sensorEvent.values[0];
            float y=sensorEvent.values[1];
            float z=sensorEvent.values[2];

            acelLast=acelVal;
            acelVal=(float)Math.sqrt((double)(x*x+y*y+z*z));
            float delta=acelVal-acelLast;
            shake=shake*0.9f+delta;

            if(shake>12)
            {
                Intent intent= new Intent(ExampleService.this,MainActivity.class);
                startActivity(intent);
            }

        }

        @Override
        public void onAccuracyChanged(Sensor sensor, int i) {

        }
    };

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

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }
}

And the MainActivity code:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);



        Intent intent=new Intent(this,ExampleService.class);
        startForegroundService(intent);

    }

}

Am I on the right path to achieve this? If not suggest me how to solve it

1

There are 1 best solutions below

0
Rémy On

The onBind method is part of the android service lifecycle. It's not an explicit call, the OS automatically calls it for you. The method is useful in some specific use cases (called bound services). In the most simple cases, you can just return a null binder. So you should replace:

@Override
public IBinder onBind(Intent intent) {
    // TODO: Return the communication channel to the service.
    throw new UnsupportedOperationException("Not yet implemented");
}

by:

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