Android无法从片段启动传感器服务类

时间:2016-03-26 07:24:08

标签: android android-fragments android-activity android-sensors android-powermanager

我有一个导航抽屉的主要活动,它将不同的页面作为片段显示出来。在其中一个片段中有一个按钮,单击此按钮将启动传感器服务并将传感器信息存储在后台的数据库中,即使屏幕关闭(唤醒锁定)。

然而,当单击按钮时,onStartCommand方法似乎没有被调用(它没有记录任何东西到logcat)

我不确定为什么服务没有启动。我已经看过很多关于此的教程/问题,但它们都使用了活动,但在我的情况下,我试图从MainActivity中的片段启动传感器服务类。我的很多困惑源于混合片段和活动,以及如何从片段正确启动服务

这是带按钮的片段:

public class StartFragment extends Fragment implements View.OnClickListener {
    Button startButton;
    Boolean started = false;
    CoordinatorLayout coordinatorLayout;
    MainActivity mainActivity;

    public StartFragment() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_start, container, false);

        coordinatorLayout = (CoordinatorLayout) getActivity().findViewById(R.id.coordinator_layout);

        //Set the nav drawer item highlight
        mainActivity = (MainActivity)getActivity();
        mainActivity.navigationView.setCheckedItem(R.id.nav_start);

        //Set actionbar title
        mainActivity.setTitle("Start");

        //Set onclick listener for save button
        startButton = (Button) view.findViewById(R.id.startButton);
        startButton.setOnClickListener(this);

        // Inflate the layout for this fragment
        return view;
    }

    @Override
    public void onClick(View v) {
        if (!started){
            mainActivity.startService(new Intent(mainActivity, SensorService.class));
            startButton.setText(getResources().getString(R.string.start_button_label_stop));
            Snackbar.make(coordinatorLayout, "Recording...", Snackbar.LENGTH_SHORT).show();
        } else {
            mainActivity.stopService(new Intent(mainActivity, SensorService.class));
            startButton.setText(getResources().getString(R.string.start_button_label_start));
            Snackbar.make(coordinatorLayout, "Recording stopped.", Snackbar.LENGTH_SHORT).show();
        }

        started = !started;
    }
}

这是SensorService类,它应该在按钮点击时运行:

public class SensorService extends Service implements SensorEventListener {

    public static final String TAG = SensorService.class.getName();
    public static final int SCREEN_OFF_RECEIVER_DELAY = 500;

    private SensorManager sensorManager = null;
    private WakeLock wakeLock = null;
    private Sensor sensor;
    Sensor accelerometer;
    Sensor gyroscope;
    Sensor gravity;
    Sensor magnetic;

    private void registerListener() {
        sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_FASTEST);
        sensorManager.registerListener(this, gyroscope, SensorManager.SENSOR_DELAY_FASTEST);
        sensorManager.registerListener(this, gravity, SensorManager.SENSOR_DELAY_FASTEST);
        sensorManager.registerListener(this, magnetic, SensorManager.SENSOR_DELAY_FASTEST);
    }

    private void unregisterListener() {
        sensorManager.unregisterListener(this);
    }

    public BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.i(TAG, "onReceive("+intent+")");

            if (!intent.getAction().equals(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);
        }
    };

    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        //Safe not to implement
    }


    public void onSensorChanged(SensorEvent event) {
        //TODO add async task to insert to DB
    }

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

        sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        accelerometer = sensorManager.getDefaultSensor(MainActivity.TYPE_ACCELEROMETER);
        gyroscope = sensorManager.getDefaultSensor(MainActivity.TYPE_GYROSCOPE);
        gravity = sensorManager.getDefaultSensor(MainActivity.TYPE_GRAVITY);
        magnetic = sensorManager.getDefaultSensor(MainActivity.TYPE_MAGNETIC);

        PowerManager manager =
                (PowerManager) getSystemService(Context.POWER_SERVICE);
        wakeLock = manager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);

        registerReceiver(receiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));
    }

    @Override
    public void onDestroy() {
        unregisterReceiver(receiver);
        unregisterListener();
        wakeLock.release();
        stopForeground(true);
    }

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

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

        Log.d(TAG, "onStartCommand");

        startForeground(Process.myPid(), new Notification());
        registerListener();
        wakeLock.acquire();

        return START_STICKY;
    }
}

1 个答案:

答案 0 :(得分:2)

尝试在应用程序标记内的XML Manifest中添加此内容,除此之外:

<service android:name=".SensorService" />

如果这有帮助,请告诉我。