我被困在它上好几天了。我需要每分钟执行一次功能。此功能正在从App到服务器进行POST调用,并且每分钟传输用户的位置。位置坐标传输几个小时,但几个小时后,位置坐标转移到服务器自行停止。我正在使用WakefulBroadcastReceiver和IntentService来确保CPU保持清醒状态。我也在使用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秒执行几个小时,但是,经过一段时间后,它的执行会自行停止,从而将位置坐标从App传输到服务器。
编辑:我编辑了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
}
}
答案 0 :(得分:0)
首先,你的SimpleWakefulService看起来并不是很清醒,它应该是aqurie WakeLock但它没有。例如,这样的服务在这里看:
接下来,是更新功能。它是在获取PARTIAL_WAKE_LOCK的上下文中调用的,但是其中的线程是异步执行的,这也意味着在释放wakelock之后。这就是造成问题的原因。
解决方案是将您的线程代码从更新函数(不需要线程)移动到WakefulIntentService,如上面的链接。