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