如何让Android手机的CPU保持清醒状态?

时间:2015-05-19 19:11:31

标签: android android-intent broadcastreceiver alarmmanager intentservice

我被困在它上好几天了。我需要每分钟执行一次功能。此功能正在从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

}

}

1 个答案:

答案 0 :(得分:0)

首先,你的SimpleWakefulService看起来并不是很清醒,它应该是aqurie WakeLock但它没有。例如,这样的服务在这里看:

https://github.com/commonsguy/cwac-wakeful/blob/master/wakeful/src/com/commonsware/cwac/wakeful/WakefulIntentService.java

接下来,是更新功能。它是在获取PARTIAL_WAKE_LOCK的上下文中调用的,但是其中的线程是异步执行的,这也意味着在释放wakelock之后。这就是造成问题的原因。

解决方案是将您的线程代码从更新函数(不需要线程)移动到WakefulIntentService,如上面的链接。