pro*_*ook 6 android sleep-mode
我有一个需要同步到互联网的Android应用程序,但是一旦手机进入睡眠状态,我就无法访问互联网.它仅在用户使用"电池模式"时发生,当它在15分钟后关闭数据时.我写了一个测试应用程序,它打开了数据,但它仍然连接到服务器.
我尝试了什么:
在摩托罗拉Atrix Android 2.3.3上测试过.我不能依靠Wifi.在现实生活中,它将每周同步.我们怎样才能成功呢?
AlarmManager:
alarm_manager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmReceiver.class);
PendingIntent pending = PendingIntent.getBroadcast(this, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
alarm_manager.setRepeating(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis(), 15000, pending);
Run Code Online (Sandbox Code Playgroud)
AlarmReceiver:
public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.d("MYTAG", "RECEIVED getMobileDataEnabled: " + getMobileDataEnabled(context));
if (!isOnline(context)) {
Log.d("MYTAG", "NO INET");
if (turnOnInet(context)) {
Log.d("MYTAG", "INET IS ON");
}
}
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://xxx.xxx.xxx.xxx/ping/pong/moto/");
try {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
nameValuePairs.add(new BasicNameValuePair("short_code", "ROFL"));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
httpclient.execute(httppost);
Log.d("MYTAG", "POST FINISHED");
}
catch (Exception e) {
Log.e("MYTAG", "MYTAG", e);
}
}
public boolean isOnline(Context context) {
ConnectivityManager cm = (ConnectivityManager)context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null){
Log.d("MYTAG", "isAvailable: "+netInfo.isAvailable());
}
if (netInfo != null && netInfo.isConnectedOrConnecting()) {
return true;
}
return false;
}
public boolean turnOnInet(Context context) {
ConnectivityManager mgr = (ConnectivityManager)context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
if (mgr == null) {
Log.d("MYTAG", "ConnectivityManager == NULL");
return false;
}
try {
Method setMobileDataEnabledMethod = mgr.getClass().getDeclaredMethod("setMobileDataEnabled", boolean.class);
if (null == setMobileDataEnabledMethod) {
Log.d("MYTAG", "setMobileDataEnabledMethod == null");
return false;
}
setMobileDataEnabledMethod.invoke(mgr, true);
}
catch(Exception e) {
Log.e("MYTAG", "MYTAG", e);
return false;
}
return true;
}
private boolean getMobileDataEnabled(Context context) {
ConnectivityManager mgr = (ConnectivityManager)context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
if (mgr == null) {
Log.d("MYTAG", "getMobileDataEnabled ConnectivityManager == null");
return false;
}
try {
Method method = mgr.getClass().getMethod("getMobileDataEnabled");
return (Boolean) method.invoke(mgr);
} catch (Exception e) {
Log.e("MYTAG", "MYTAG", e);
return false;
}
}
}
Run Code Online (Sandbox Code Playgroud)
AndroidManifest.xml中
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
Run Code Online (Sandbox Code Playgroud)
Com*_*are 15
首先,你需要从中获取HttpPost代码BroadcastReceiver并将其转换为IntentService.永远不要在主应用程序线程上进行网络I/O,并在主应用程序线程onReceive()上调用.例如,如果您花费太长时间,Android将通过您的Internet操作中途终止您的代码.
其次,考虑到IntentService,你需要使用一个WakeLock.这可能会引导你使用我的WakefulIntentService,处理这两个问题.或者,使用WakefulBroadcastReceiver,具有相同的目的.
第三,删除turnOnInet()和getMobileDataEnabled().您不需要它们,它们不可靠,特别turnOnInet()是用户恶意 - 如果用户想要移动数据,他们就会打开它.
现在,考虑到所有这一切,在你onHandleIntent()的你IntentService()(或你的doWakefulWork()你的WakefulIntentService),如果你没有互联网连接的时候了,作为临时解决方法,SystemClock.sleep()一秒钟,再试一次,在一个循环中重复几次.如果您发现稍微上网后可以访问互联网,那么您可以考虑变得更复杂(例如,监听连接更改广播而不是轮询,尽管这会让您远离WakefulIntentService并进入常规Service的自己的后台线程和国家机器WakeLock管理).或者,坚持下去sleep()- 如果你把这个后台线程绑定几秒钟,它就不太可能成为世界末日.但是,如果您在适度的时间之后没有获得连接,请不要无限期地尝试,因为您可能无法获得连接的原因有很多,包括Android 4.0+上的用户驱动带宽管理.
我建议改变一下这个方法,这一点都不错,确保你总是同步,这是唯一的问题,你不会给用户提供决定的机会,因为如果我,作为用户,决定关闭我的数据我只是不希望任何人打开它.可能有几个原因,其中任何一个都应该足够,但是说你离开这个国家并且你没有国际数据计划,并且偶然或默认你已经激活了数据漫游.如果我发现某些应用程序将我的数据打开并花费了大量金钱,我会非常生气,而且我会是个人的.
一个更合适的方法和直接的解决方案是,每当用户打开你的应用程序或根据一些简单的条件(上次同步)访问某些wifi连接(ConnectivityManager是你的朋友)时,可以不时进行硬/完全同步超过一周,过时的保存数据,不一致等)并在其余情况下进行软同步(在后台更新数据).
此外,定期同步意味着在用户不使用应用程序的情况下浪费用户数据.最终,这会使您的应用程序成为每隔一段时间被系统关闭的完美候选者.
希望能帮助到你.随时向我们通报您的进度.
相关阅读:优化下载以实现高效的网络访问
| 归档时间: |
|
| 查看次数: |
7084 次 |
| 最近记录: |