我有一个应用程序,可以检测互联网是否可用。我已经改变了后退按钮的行为,以避免在按下时关闭应用程序。我面临的问题是,当我运行4G或WIFI并且运行应用程序时,它会检测到互联网可用,但是,当我按下后退按钮时,应用程序被放在后台并且不再检测到互联网通过它。
我注意到如果我删除清单文件中的权限,应用程序工作正常,它会在运行时和放在后台时检测到互联网,但我需要这些权限以便稍后发出http发送请求。
对此有何帮助?
谢谢。
main activity.Java
public class MainActivity extends AppCompatActivity {
Timer timer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
init();
}
@Override
public void onBackPressed() {
this.moveTaskToBack(true);
}
private void init() {
timer = new Timer();
Tasker task = new Tasker(MainActivity.this, timer);
task.execute();
}
}
包.java
public class Tasker extends AsyncTask<Void,Void,String> {
final Handler handler = new Handler();
static Timer timer;
Context context;
Toast toast;
private TimerTask doAsynchronousTask;
public Tasker(MainActivity context, Timer timer) {
this.timer = timer;
this.context = context;
}
@Override
protected void onPreExecute() {
}
@Override
protected String doInBackground(Void... voids) {
doTimerTask();
return null;
}
@Override
protected void onPostExecute(String response) {
}
private void showToast(String message){
toast = Toast.makeText(context, message, Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER, 0, 0);
if(!((Activity) context).isFinishing()){
toast.show();
}
}
private void doTimerTask() {
doAsynchronousTask = new TimerTask() {
@Override
public void run() {
handler.post(new Runnable() {
@SuppressWarnings("unchecked")
public void run() {
if(haveNetworkConnection()){
showToast("Online");
}else{
showToast("Offline");
}
}
});
}
};
timer.schedule(doAsynchronousTask, 0, 10000);
}
private boolean haveNetworkConnection() {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
boolean isConnected = activeNetwork != null && activeNetwork.isConnectedOrConnecting();
return isConnected;
}
}
AndroidManifest.xml中
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.e.myapplication">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest>
实际上,它可能不是你理想的答案,但我认为有一种更简单的方法可以使用广播接收器做你真正想做的事情。您不需要使用计时器检查网络状态。这是link
我建议你使用WorkManager
或AlarmManager
,甚至Services
用于背景相关的周期性任务。
使用Timer
-AsyncTask
组合不是一种可行的方法,它可能会导致许多问题,其中一个问题是,一旦它处于后台,它就很容易被Android终止。
我的首选是WorkManager
,因为它可以很好地处理你的任务条件,例如,如果你只想启动你的任务,如果有互联网连接,那么你只需添加一个Work Constraint
到你的工作请求,就像这样
Constraint networkConstraint = new Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build();
workRequest.setConstraints(constraints)
并且只有在连接网络时才会执行您的任务。顺便说一句,他们不需要像AlarmManagers
那样在重新启动后手动重新设置。
但是,它有一些缺点,其中一个是perodic请求只能每15分钟发生一次,你可以通过在每个perodic请求中设置更多的one time work requests以及更短的延迟开始时间间隔来规避(尽管不推荐)。
无论如何,停止使用你现在正在使用的AsyncTask
方法,并使用Android批准的一种“合法”方法来执行后台任务,我推荐WorkManager
,但根据你的情况,你可以选择你喜欢的任何方法,只要它的意思在后台工作。