首页 > 解决方案 > 如何通过使用 API 级别上 27 的前台服务检测抖动来启动我的 Android 应用程序?

问题描述

我在我的应用程序中使用前台服务来检测从任何地方到 MainActivity 的摇动和启动应用程序,现在在执行一些代码之后,我遇到了这个问题。我希望有人能提出解决方案或建议我如何完成这项工作。是的,我确实运行了该应用程序,每当我摇晃手机时都会运行该服务,因此该应用程序会自动关闭。我的服务代码如下

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

和 MainActivity 代码:

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);

    }

}

我在实现这一目标的正确道路上吗?如果不建议我如何解决它

标签: androidandroid-studioandroid-serviceforeground-serviceshake

解决方案


onBind 方法是 android 服务生命周期的一部分。这不是显式调用,操作系统会自动为您调用它。该方法在某些特定用例(称为绑定服务)中很有用。在最简单的情况下,您可以只返回一个空活页夹。所以你应该更换:

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

经过:

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

推荐阅读