0

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

但是,当单击按钮时,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;
    }
}
4

1 回答 1

2

尝试将其添加到应用程序标记内的 XML 清单中,在其他任何内容之外:

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

让我知道这是否有帮助。

于 2016-03-26T07:41:12.400 回答