0

У меня есть основное действие с ящиком nav, который вызывает разные страницы как фрагменты. В одном из фрагментов есть кнопка, которая при нажатии вызывает запуск службы датчика и сохранение информации о датчике в базу данных в фоновом режиме, даже когда экран выключается (блокировка от бодрствования).Android не может запустить класс обслуживания датчиков из фрагмента

Однако, когда нажимается кнопка метод 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; 
    } 
} 
+0

Вы добавили свою службу в манифест? – mmcoder10

+0

Попробуйте добавить Log.d ("test", "onClick"); команды внутри метода onClick внутри if, чтобы увидеть, вызвана ли она. Однако я не вижу там никакой ошибки. Это правильный способ запуска службы из фрагмента. – mmcoder10

+0

Просто попробовал, и это кажется прекрасным. Поэтому, по крайней мере, проблема не в 'onClick', когда ее проверки'! Started' – Simon

ответ

1

Попробуйте добавить это в XML Manifest внутри тега приложения, вне что-нибудь еще:

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

Сообщите мне, если это поможет.

+0

Где в манифесте должно быть добавлено? В блоке ? Или вне его? – Simon

+0

Внутри приложения, за пределами любых видов деятельности – mmcoder10

+0

Это сработало, спасибо! – Simon