Как сохранить процессор Android телефона всегда бодрствующим?
Я застрял на нем в течение нескольких дней. Мне нужно выполнять функцию каждую минуту. Эта функция выполняет POST-вызов из приложения на сервер и передает местоположение пользователя в минуту. Координаты местоположения передаются в течение нескольких часов, однако через несколько часов передача координат местоположения на Сервер прекращается самостоятельно. Я использую WakefulBroadcastReceiver и IntentService, чтобы убедиться, что процессор не спит. Я также использую Alarm, чтобы убедиться, что функция выполняется каждую минуту.
Вот так выглядит мой WakefulBroadcastReceiver:
public class SimpleWakefulReceiver extends WakefulBroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// This is the Intent to deliver to our service.
Intent service = new Intent(context, SimpleWakefulService.class);
// Start the service, keeping the device awake while it is launching.
Log.i("SimpleWakefulReceiver", "Starting service @ " +
SystemClock.elapsedRealtime());
startWakefulService(context, service);
}
}
Вот как выглядит мой IntentService:
public class SimpleWakefulService extends IntentService {
public MainActivity obj;
public Alarm alarm;
public SimpleWakefulService() {
super("SimpleWakefulService");
}
@Override
protected void onHandleIntent(Intent intent) {
boolean flag = true;
while(flag){
Log.i("SimpleWakefulService", "Running service ");
alarm = new Alarm();
alarm.SetAlarm(SimpleWakefulService.this);
Log.i("Called alarm.SetAlarm","Called alarm.SetAlarm");
}
SimpleWakefulReceiver.completeWakefulIntent(intent);
// wl.release();
}
}
Вот как выглядит мой класс Alarm:
public class Alarm extends BroadcastReceiver
{
public MainActivity obj;
@Override
public void onReceive(Context context, Intent intent)
{
PowerManager pm = (PowerManager)
context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl =
pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "");
wl.acquire();
obj = new MMMainActivity();
obj.UpdateData();
Toast.makeText(context, "Alarm !!!!!!!!!!", Toast.LENGTH_LONG).show();
wl.release();
}
public void SetAlarm(Context context)
{
Log.i("Inside SetAlarm","Inside SetAlarm");
AlarmManager am =( AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, Alarm.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
am.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 60 * 1, pi); // Millisec * Second * Minute
}
public void CancelAlarm(Context context)
{
Intent intent = new Intent(context, Alarm.class);
PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(sender);
}
}
Вот как выглядит функция (названная UpdataData ()), которую нужно выполнять каждую минуту:
public void UpdateData() {
final boolean flag = true;
Log.i("Inside Update Data", "Inside Update Data");
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
for(int i=0; i<1; i++){
try {
// Your code goes here
if (locationclient != null
&& locationclient.isConnected()) {
loc = locationclient.getLastLocation();
lat = loc.getLatitude();
lng = loc.getLongitude();
}
try { // Updating the latest location in the UI, just
// for convinience.
HttpClient httpClient = new DefaultHttpClient();
// Creating HTTP Post
HttpPost httpPost = new HttpPost(
"http://www.mywebsite.com/update");
List<NameValuePair> nameValuePair = new ArrayList<NameValuePair>(
3);
// Building post parameters//
// key and value pair
Log.i("token", "token" + token);
Log.i("Latitude for III POST Call",
"Latitude for III POST Call" + lat);
Log.i("Longitude for III POST Call",
"Longitude for III POST Call" + lng);
nameValuePair.add(new BasicNameValuePair("token",
token));
nameValuePair.add(new BasicNameValuePair("lat",
Double.toString(lat)));
nameValuePair.add(new BasicNameValuePair("lng",
Double.toString(lng)));
Log.i("Made UpdateData Post Call",
"Made UpdateData Post Call");
// Url Encoding the POST parameters
try {
httpPost.setEntity(new UrlEncodedFormEntity(
nameValuePair));
} catch (UnsupportedEncodingException e) {
// writing error to Log
e.printStackTrace();
}
// Making HTTP Request
try {
HttpResponse response = httpClient
.execute(httpPost);
// writing response to log
Log.d("Http Response:", response.toString());
// Your code goes here
} catch (IOException e) {
// writing exception to log
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}// loop closed
}
});
thread.start();
}// UpdateData closed
Почему даже после использования всего этого UpdateData () не может выполняться бесконечно, каждые 60 секунд? Любая помощь в этом отношении будет принята с благодарностью. Также обратите внимание, что UpdateData () выполняется каждые 60 секунд в течение нескольких часов, но через некоторое время его выполнение останавливается само по себе и, следовательно, происходит передача координат местоположения из приложения на сервер.
РЕДАКТИРОВАТЬ: я отредактировал SimpleWakefulService и добавил необходимые изменения в соответствии с одним из ответов. В течение нескольких часов все работало хорошо, однако через несколько часов служба была автоматически убита. Я считаю, что услуги не предназначены для убийства. Может ли кто-нибудь объяснить это? SimpleWakefulService:
public class SimpleWakefulService extends IntentService implements
OnClickListener,ConnectionCallbacks, OnConnectionFailedListener,
LocationListener,GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener {
public static Location loc;
public static LocationClient locationclient;
public static double lat = 10, lng = 10;
public static String token;
public Alarm alarm;
public SimpleWakefulService() {
super("SimpleWakefulService");
}
@Override
protected void onHandleIntent(Intent intent) {
//Getting the value of token from another Class
token = ConfirmToken.uvalue;
Log.i("WakefulServiceutoken", "WakefulServicutoken" + token);
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "");
wl.acquire();
final boolean flag = true;
while (flag) {
try {
// Your code goes here
if (locationclient != null
&& locationclient.isConnected()) {
loc = locationclient.getLastLocation();
lat = loc.getLatitude();
lng = loc.getLongitude();
}
try { // Updating the latest location in the UI, just
// for convinience.
HttpClient httpClient = new DefaultHttpClient();
// Creating HTTP Post
HttpPost httpPost = new HttpPost(
"http://www.mywebsite.com/update");
List<NameValuePair> nameValuePair = new ArrayList<NameValuePair>(
3);
// Building post parameters//
// key and value pair
Log.i("token", "token" + token);
Log.i("Latitude for III POST Call",
"Latitude for III POST Call" + lat);
Log.i("Longitude for III POST Call",
"Longitude for III POST Call" + lng);
nameValuePair.add(new BasicNameValuePair("token",
token));
nameValuePair.add(new BasicNameValuePair("lat",
Double.toString(lat)));
nameValuePair.add(new BasicNameValuePair("lng",
Double.toString(lng)));
// Url Encoding the POST parameters
try {
httpPost.setEntity(new UrlEncodedFormEntity(
nameValuePair));
} catch (UnsupportedEncodingException e) {
// writing error to Log
e.printStackTrace();
}
// Making HTTP Request
try {
HttpResponse response = httpClient
.execute(httpPost);
// writing response to log
Log.d("Http Response:", response.toString());
// Your code goes here
} catch (IOException e) {
// writing exception to log
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
try {
Thread.sleep(10000);
} catch (Exception e) {
}
}// While closed
//SimpleWakefulReceiver.completeWakefulIntent(intent);
//wl.release();
}
@Override
public void onDisconnected() {
// TODO Auto-generated method stub
}
@Override
public void onLocationChanged(Location arg0) {
// TODO Auto-generated method stub
}
@Override
public void onProviderDisabled(String arg0) {
// TODO Auto-generated method stub
}
@Override
public void onProviderEnabled(String arg0) {
// TODO Auto-generated method stub
}
@Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
// TODO Auto-generated method stub
}
@Override
public void onConnectionFailed(ConnectionResult result) {
// TODO Auto-generated method stub
}
@Override
public void onConnected(Bundle arg0) {
// TODO Auto-generated method stub
}
@Override
public void onConnectionSuspended(int arg0) {
// TODO Auto-generated method stub
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
}