Я устанавливаю будильник каждые 15 минут, но он все равно отправляет данные в случайные моменты времени, не показывая, когда приложение закрыто

#android

#Android

Вопрос:

Всякий раз, когда я начинаю свою основную деятельность, время идет. Я хочу, чтобы это происходило каждые 15 минут.

для запуска службы

     Intent intent = new Intent();
    intent.setAction("MyBroadcast");
    sendBroadcast(intent);
    Log.d("hasNetwork", "inside");
  

после этого я пытаюсь устанавливать будильник каждые 15 минут

 public class ConnectivityReceiver extends WakefulBroadcastReceiver
{

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

        Log.d("hasNetwork","inside");
        final AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        final PendingIntent wakeupIntent = PendingIntent.getService(context, 0, new Intent(context, LocationUpdaterService.class), PendingIntent.FLAG_UPDATE_CURRENT);
        final boolean hasNetwork = !intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
        if (hasNetwork)
        {
  

// здесь я устанавливаю время для повторения через одну минуту для целей тестирования
AlarmManager.setExact(AlarmManager.RTC_WAKEUP, 60000, wakeupIntent);

         }
        else
        {
            Log.d("hasNetwork","NO");
            alarmManager.cancel(wakeupIntent);
        }
    }

}
  

это класс, который извлекает текущее местоположение и отправляет на сервер

 public class LocationUpdaterService extends Service  implements

 GoogleApiClient.ConnectionCallbacks, 

GoogleApiClient.OnConnectionFailedListener,
        com.google.android.gms.location.LocationListener




{


    LocationRequest mLocationRequest;
    GoogleApiClient mGoogleApiClient;
    ProgressDialog progressDialog;
    String lat="",lng="";
    SharedPreferences sp;
    SharedPreferences.Editor editor;


    protected synchronized void buildGoogleApiClient()
    {
        Toast.makeText(this, "buildGoogleApiClient", Toast.LENGTH_SHORT).show();
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
    }
    @Override
    public void onLocationChanged(Location location)
    {
        Log.d("hasNetw1ork", "onlocation???");
        Geocoder geocoder;
        List<Address> addresses;
        geocoder = new Geocoder(this, Locale.getDefault());
        double latitude = location.getLatitude();
        double longitude = location.getLongitude();
        Log.e("latitude", "latitude--"   latitude "longitude=" longitude);
        lat= String.valueOf(latitude);
        lng= String.valueOf(longitude);
        try
        {
            Log.e("latitude", "inside latitude--"   latitude);
            addresses = geocoder.getFromLocation(latitude, longitude, 1);

        }
        catch (IOException e)
        {
            e.printStackTrace();
        }


        Log.d("hasNetwork",location.getLatitude() "  " location.getLongitude());
            sendToServer();

    }

    @Override
    public void onConnected(@Nullable Bundle bundle)
    {
      //  Toast.makeText(this, "onConnected", Toast.LENGTH_SHORT).show();
        if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED amp;amp; ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
          Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);

          mLocationRequest = new LocationRequest();
          mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);

          LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,mLocationRequest,this);

    }

    @Override
    public void onConnectionSuspended(int i)
    {

    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {


    }

    private enum State
    {
        IDLE, WORKING;
    }


    private static State state;

    private PowerManager.WakeLock wakeLock;

    static
    {
        state = State.IDLE;
    }

    @Override
    public void onCreate()
    {
        super.onCreate();
        final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        this.wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "LocationUpdaterService");
        Log.d("hasNetwork", "oncreate");
        buildGoogleApiClient();
        mGoogleApiClient.connect();

        sp= PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
        editor=sp.edit();
    }

    @Override
    public IBinder onBind(Intent arg0)
    {
        Log.d("hasNetwork", "onBind");

        return null;
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
    {
        if (state == State.IDLE)
        {
            state = State.WORKING;
            this.wakeLock.acquire();
            // register location updates, not gonna code it you know
            Log.d("hasNetwork", "onStartCommand");
        }

        return START_NOT_STICKY;
    }

    @Override
    public void onDestroy()
    {
        super.onDestroy();
        state = State.IDLE;
        if (this.wakeLock.isHeld())
        {
            Log.d("hasNetwork", "onDestroy");
            this.wakeLock.release();
        }
    }
    private void sendToServer()
    {
        // send to server in background thread. you might want to start AsyncTask here
        vollyRequest_Add_Latlong();

    }

    private void onSendingFinished()
    {
        // call this after sending finished to stop the service
        this.stopSelf(); 
   }
  

Комментарии:

1. Что именно вы подразумеваете под закрытым? Закрыто с помощью «Принудительного закрытия» из настроек?

Ответ №1:

Вы столкнулись с двумя разными проблемами:

Во-первых, вы используете setInexactRepeating() . Как следует из названия и в документации явно указано, эти сигналы тревоги неточны. Android объединит несколько сигналов тревоги, чтобы свести к минимуму пробуждения устройства.

Если по какой-либо причине вы считаете, что для вашего варианта использования требуется точное время, вы можете использовать setExact() для планирования одноразового будильника и продолжать планировать эти сигналы по мере необходимости.

Во-вторых, в Android 6.0 введен режим ожидания, который помогает еще больше минимизировать пробуждения устройства, когда устройство не используется. Идея заключается в том, что если пользователь не активно использует свое устройство, никакие приложения не должны выполнять периодическую работу, такую как удаление свежих новостных статей. Вместо этого, когда пользователь в следующий раз поднимет свое устройство, сработают сигналы тревоги, и ваши данные обновятся.

Если ваше приложение попадает в белый список рекомендаций в документации doze, вы можете попросить своих пользователей внести ваше приложение в белый список из оптимизации батареи.

Комментарии:

1. AlarmManager.setExact(AlarmManager. RTC_WAKEUP, 60000, wakeupIntent); AlarmManager.setRepeating(AlarmManager. RTC_WAKEUP, новая дата ().getTime(), 60000, wakeupIntent);

2. Я также использовал эти два, но все еще есть проблема

3. Кода, который вы только что опубликовали в своем комментарии, нигде нет в вашем исходном сообщении. Если исходное сообщение не соответствует вашему коду, пожалуйста, обновите его. Кроме того, setRepeating() это также неточно (все повторяющиеся сигналы тревоги).

4. смотрите мое редактирование, которое я изменил в своем коде, и все равно оно не работает

5. Если вы работаете на Android 6.0 , добавили ли вы свое приложение в белый список оптимизации заряда батареи в соответствии со второй половиной моего ответа?