Как исправить дублированные значения из BroadcastReceiver? - PullRequest
0 голосов
/ 30 января 2019

Я использую BroadcastReceiver для получения состояния батареи, например, процента заряда батареи и т. Д. Я также использую «бесконечный» сервис, который продолжает работать, даже если клиент закрывает приложение.Моя проблема заключается в том, что когда клиент открывает приложение во второй раз, значения (в процентах от батареи) дублируются в BroadcastReceiver.

Пример из logcat ( 1-й запуск ): Процент батареи:80%, на переднем плане: true

Пример из logcat ( приложение закрыто с первого запуска ): Процент батареи: 80%, на переднем плане: false

Пример из logcat ( 2-й запуск ): Процент батареи: 80%, На переднем плане: ложь, Процент батареи: 80%, На переднем плане: правда

Пример из logcat (приложение закрыто со 2-го запуска ): Процент батареи: 80%, На переднем плане: ложь, Процент батареи: 80%, На переднем плане: ложь

Как вы видите, все в BroadcastReceiver повторяется после второго открытия приложения.

Я попытался отменить регистрацию BroadcastReceiver, но проблема все еще возникла.

MainActivity class

public class MainActivity extends AppCompatActivity {

public boolean inForeground = true;

Intent mServiceIntent;
Context context;

public Context getContext() {
    return context;
}

private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {

    @Override
    public void onReceive(Context context, Intent intent) {

        int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
        int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);

        float batteryPct = (level / (float)scale);
        int batteryPercentage = (int)((batteryPct)*100);

        Log.i("Battery percent", ""+batteryPercentage+"%!");
        Log.i("In foreground", String.valueOf(inForeground));
    }
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    context = this;
    SensorService mSensorService = new SensorService(getContext());
    mServiceIntent = new Intent(getContext(), mSensorService.getClass());
    if (!isMyServiceRunning(mSensorService.getClass())) {
        startService(mServiceIntent);
    }

    IntentFilter iFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
    Context mContext = getApplicationContext();
    mContext.registerReceiver(mBroadcastReceiver, iFilter);
}

@Override
protected void onResume() {
    super.onResume();
    inForeground = true;
}

@Override
protected void onPause() {
    inForeground = false;
    super.onPause();
}

// Services
private boolean isMyServiceRunning(Class<?> serviceClass) {
    ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
    for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
        if (serviceClass.getName().equals(service.service.getClassName())) {
            Log.i ("Running Service", true+"!");
            return true;
        }
    }
    Log.i ("Running Service", false+"!");
    return false;
}

@Override
protected void onDestroy() {
    stopService(mServiceIntent);
    Log.i("Main", "onDestroy!");
    super.onDestroy();
}
}

SensorService class

public class SensorService extends Service {
public SensorService(Context applicationContext) {
    super();
    Log.i("Called", "SensorService!");
}

public SensorService() {
}

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

@Override
public void onDestroy() {
    super.onDestroy();
    Log.i("Exit", "onDestroy!");
    Intent broadcastIntent = new Intent(this, SensorRestarterBroadcastReceiver.class);
    sendBroadcast(broadcastIntent);
}

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

SensorRestarterBroadcastReceiver class

public class SensorRestarterBroadcastReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
    Log.i(SensorRestarterBroadcastReceiver.class.getSimpleName(), "Ongoing Service!");
    context.startService(new Intent(context, SensorService.class));
}
}

Ожидаемый выходной сигнал должен быть Процент батареи: 80%, На переднем плане: true , но фактическийвыход дублируется и выглядит как Процент батареи: 80%, на переднем плане: ложь, Процент батареи: 80%, на переднем плане: правда .

РЕДАКТИРОВАТЬ

Я уже пробовал это, используя его в onCreate и onResume:

Context mContext = getApplicationContext();
SensorService mSensorService = new SensorService(getContext());
mServiceIntent = new Intent(getContext(), mSensorService.getClass());
    if (isMyServiceRunning(mSensorService.getClass())) {
        mContext.unregisterReceiver(mBroadcastReceiver);
    }

EDIT 2

Я изменил onDestroy () на это:

@Override
protected void onDestroy() {

    Context mContext = getApplicationContext();
    SensorService mSensorService = new SensorService(getContext());
    mServiceIntent = new Intent(getContext(), mSensorService.getClass());
    if (isMyServiceRunning(mSensorService.getClass())) {
        mContext.unregisterReceiver(mBroadcastReceiver);
    }

    stopService(mServiceIntent);
    Log.i("Main", "onDestroy!");
    inForeground = false;
    super.onDestroy();
}

Код теперь работает нормально на переднем плане, но я не получаю никаких показаний, когда приложение находится в фоновом режиме.

...