#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 , добавили ли вы свое приложение в белый список оптимизации заряда батареи в соответствии со второй половиной моего ответа?