无法使用警报从Android中的前景服务访问数据

时间:2018-08-14 15:27:07

标签: java android service broadcastreceiver alarmmanager

我的Android应用是计步器应用。我有一个MainActivity.java类,其中包含一个用于启动计数步骤的服务的按钮。该服务位于Service.java类中,并且是前台服务,因此即使关闭应用程序也可以运行。

MainActivity类包含一个BroadcastReceiver,它从Service接收更新。这样,每当我打开MainActivity时,我都会看到最新的步骤计数。

MainActivity还包含一个用于触发AlarmManager警报的按钮。警报响起时(每天),它将当天执行的步骤数存储在本地数据库中。

我的问题是:警报是否可以访问服务中的最新数据(无需使用BroadcastReceiver?)

当我关闭MainActivity时,即使该服务仍在后台运行,BroadcastReceiver也会泄漏,因此MainActivity类中的步数整数将停止更新。

我尝试实例化Service类并在那里访问step count变量,但无法识别该变量。

编辑:MainActivity代码是这样的:

public class MainActivity extends AppCompatActivity {
    static int countedSteps;
    private static final String TAG = "SensorEvent";
    DatabaseHelper myDb;
    public static TextView stepview;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
           super.onCreate(savedInstanceState);
           stepview = (TextView) findViewById(R.id.steptext);
           setContentView(R.layout.activity_main);

           startServiceBtn = (Button) findViewById(R.id.startmonitoring);
           startServiceBtn.setOnClickListener(new View.OnClickListener() {
               @Override
               public void onClick(View view) { 
                   insertData(view); //sets the alarm for data insertion
               }
           });
           stopServiceBtn = (Button) findViewById(R.id.stopmonitoring);
           stopServiceBtn.setOnClickListener(new View.OnClickListener() {
               @Override
               public void onClick(View view) {
                   if (serviceOn) {
                       unregisterReceiver(broadcastReceiver);
                       stopService(new Intent(getBaseContext(), TheService.class));
                   }
               }
           });
    }

    //code to set the alarm, etc.

    protected void onResume() {
         super.onResume();
         stepview.setText(String.valueOf(countedSteps));
    }

    public void startStepCount(){
        Intent intent = new Intent(MainActivity.this,TheService.class);
        MainActivity.this.startService(intent);
        registerReceiver(broadcastReceiver, new IntentFilter(TheService.BROADCAST_ACTION));
    }

    private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
        updateinfo(intent);
        }
    };

    private void updateinfo(Intent intent) {
        if (intent.getStringExtra("Counted_Step") != null) {
            countedSteps = Integer.parseInt(intent.getStringExtra("Counted_Step"));
        }
        else {
             Log.v("counted int value", "null");
        }
    }

服务代码为:

private SensorManager mSensorManager;
private Sensor mSensor;
private Sensor pedcount;
private int numSteps;
public String startmessage = "Service has started";

private final static int NOTIFICATION_ID = 50;

public static int oldstepcount;
public static int stepcount;
public static int newstepcount;

boolean servicestatus;

NotificationManager notificationManager;

Intent intent;

boolean setForeground;

private static final String TAG = "StepService";
public static final String BROADCAST_ACTION = "mybroadcast";

private final Handler handler = new Handler();

int counter = 0;
Context context;

public void onCreate() {
    super.onCreate();
    intent = new Intent(BROADCAST_ACTION);
    stepcount = 0;
}

public int onStartCommand(Intent intent, int flags, int startId) {
    context = getApplicationContext();
    showNotification();

    mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
    if (mSensorManager.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR) != null) {
        pedcount = mSensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
    } else {
        //Toast.makeText(this, "Your device has no pedometer!", Toast.LENGTH_LONG).show();
    }

    mSensorManager.registerListener(this, peddetect, 0);
    servicestatus = false;

    handler.removeCallbacks(updateBroadcastData);
    handler.post(updateBroadcastData);

    return START_STICKY;
}

public void onDestroy() {
    servicestatus = true;
    dismissNotification();
}

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

@Override
public void onSensorChanged(SensorEvent event) {
    if (event.sensor.getType() == Sensor.TYPE_STEP_COUNTER) {
        int countSteps = (int) event.values[0];
        if (stepcount == 0) {
            stepcount = (int) event.values[0];
        }
        newstepcount = countSteps - stepcount;
    }
}

private Runnable updateBroadcastData = new Runnable() {
    public void run() {
        if (!servicestatus) {
            // Call the method that broadcasts data to the Activity
            broadcastSensorValue();
            // Call "handler.postDelayed" again, after a specified delay.
            handler.postDelayed(this, 1000);
        }
    }
};

@Override
public void onAccuracyChanged(Sensor sensor, int i) {
}

private void broadcastSensorValue() {
    //Log.d(TAG, "Data to Activity");
    intent.putExtra("Counted_Step_Int", newstepcount);
    intent.putExtra("Counted_Step", String.valueOf(newstepcount + oldstepcount));
    sendBroadcast(intent);
}

private void showNotification() {
    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this);
    notificationBuilder.setContentTitle("Pedometer is working!");
    notificationBuilder.setContentText("The app is running in the background");
    notificationBuilder.setSmallIcon(R.mipmap.ic_launcher);
    notificationBuilder.setPriority(Notification.PRIORITY_HIGH);
    notificationBuilder.setOngoing(true);
    PendingIntent resultPendingIntent = PendingIntent.getActivity(this, 0, new Intent(), 0);
    notificationBuilder.setContentIntent(resultPendingIntent);
    notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    startForeground(NOTIFICATION_ID, notificationBuilder.build());
}

private void dismissNotification() {
    notificationManager.cancel(NOTIFICATION_ID);
}

0 个答案:

没有答案