android - 清除最近的任务后收不到广播
问题描述
我想制作一个应用程序,它会在接收到 wifi 状态更改的广播时做一些事情。如何编辑此代码以使服务在清除最近任务后也接收广播? 请帮忙。谢谢
这是下面的代码:
public class IntentService extends Service {
SharedPreferences sharedPreferences;
SimpleDateFormat simpleDateFormat;
BroadcastReceiver broadcastReceiver= new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
int wifiStateExtra=intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 0);
sharedPreferences.edit().putString(simpleDateFormat.format(new Date())," :"+ wifiStateExtra).apply();
Log.d("Wifi State", " :"+wifiStateExtra +" i :" +i);
}
};
private int i;
public IntentService() {
super();
}
@Override
public void onCreate() {
super.onCreate();
sharedPreferences = getSharedPreferences("test", MODE_PRIVATE);
simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
}
@Override
public void onStart(@Nullable Intent intent, int startId) {
super.onStart(intent, startId);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
registerReceiver(broadcastReceiver, intentFilter);
}
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
return START_STICKY;
}
@Override
public void onTaskRemoved(Intent rootIntent) {
Toast.makeText(getApplicationContext(), "onTaskRemoved called", Toast.LENGTH_LONG).show();
startService(rootIntent);
super.onTaskRemoved(rootIntent);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
解决方案
Nougat 及以上:我们必须使用 JobScheduler 和 JobService 进行连接更改。
我可以把这分成三个步骤。
在活动中注册 JobScheduler。此外,启动 JobService(服务来处理来自 JobScheduler 的回调。使用 JobScheduler 调度的请求最终会落在该服务的“onStartJob”方法上。)
public class NetworkConnectionActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_network_connection);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
scheduleJob();
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void scheduleJob() {
JobInfo myJob = new JobInfo.Builder(0, new ComponentName(this, NetworkSchedulerService.class))
.setRequiresCharging(true)
.setMinimumLatency(1000)
.setOverrideDeadline(2000)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
.setPersisted(true)
.build();
JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
jobScheduler.schedule(myJob);
}
@Override
protected void onStop() {
// A service can be "started" and/or "bound". In this case, it's "started" by this Activity
// and "bound" to the JobScheduler (also called "Scheduled" by the JobScheduler). This call
// to stopService() won't prevent scheduled jobs to be processed. However, failing
// to call stopService() would keep it alive indefinitely.
stopService(new Intent(this, NetworkSchedulerService.class));
super.onStop();
}
@Override
protected void onStart() {
super.onStart();
// Start service and provide it a way to communicate with this class.
Intent startServiceIntent = new Intent(this, NetworkSchedulerService.class);
startService(startServiceIntent);
}
}
开始和完成工作的服务。
public class NetworkSchedulerService extends JobService implements
ConnectivityReceiver.ConnectivityReceiverListener {
private static final String TAG = NetworkSchedulerService.class.getSimpleName();
private ConnectivityReceiver mConnectivityReceiver;
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "Service created");
mConnectivityReceiver = new ConnectivityReceiver(this);
}
/**
* When the app's NetworkConnectionActivity is created, it starts this service. This is so that the
* activity and this service can communicate back and forth. See "setUiCallback()"
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "onStartCommand");
return START_NOT_STICKY;
}
@Override
public boolean onStartJob(JobParameters params) {
Log.i(TAG, "onStartJob" + mConnectivityReceiver);
registerReceiver(mConnectivityReceiver, new IntentFilter(Constants.CONNECTIVITY_ACTION));
return true;
}
@Override
public boolean onStopJob(JobParameters params) {
Log.i(TAG, "onStopJob");
unregisterReceiver(mConnectivityReceiver);
return true;
}
@Override
public void onNetworkConnectionChanged(boolean isConnected) {
String message = isConnected ? "Good! Connected to Internet" : "Sorry! Not connected to internet";
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
}
}
最后,检查网络连接的接收器类发生了变化。
public class ConnectivityReceiver extends BroadcastReceiver {
private ConnectivityReceiverListener mConnectivityReceiverListener;
ConnectivityReceiver(ConnectivityReceiverListener listener) {
mConnectivityReceiverListener = listener;
}
@Override
public void onReceive(Context context, Intent intent) {
mConnectivityReceiverListener.onNetworkConnectionChanged(isConnected(context));
}
public static boolean isConnected(Context context) {
ConnectivityManager cm = (ConnectivityManager)
context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
return activeNetwork != null && activeNetwork.isConnectedOrConnecting();
}
public interface ConnectivityReceiverListener {
void onNetworkConnectionChanged(boolean isConnected);
}
}
不要忘记在清单文件中添加权限和服务。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.yourpackagename">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!-- Always required on api < 21, needed to keep a wake lock while your job is running -->
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<!-- Required on api < 21 if you are using setRequiredNetworkType(int) -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!-- Required on all api levels if you are using setPersisted(true) -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<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=".connectivity.NetworkConnectionActivity"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Define your service, make sure to add the permision! -->
<service
android:name=".connectivity.NetworkSchedulerService"
android:exported="true"
android:permission="android.permission.BIND_JOB_SERVICE"/>
</application>
</manifest>
请参阅以下链接以获取更多信息。 https://github.com/jiteshmohite/Android-Network-Connectivity
https://github.com/evant/JobSchedulerCompat
https://github.com/googlesamples/android-JobScheduler https://medium.com/@iiro.krankka/its-time-to-kiss-goodbye-to-your-implicit-broadcastreceivers-eefafd9f4f8a
推荐阅读
- python - 将 einsum 表示法转换为 for 循环
- javascript - 从 JavaScript 的 Django 模板中的 for 循环获取元素
- ipywidgets - 将下拉列表和按钮与 ipywidgets 相结合
- r - ggplot2中的线性回归
- javascript - 如何在另一个对象中检查至少一个对象
- linux - Linux 命令将文件内容每行一个字复制到从同一命令创建的新文件中
- javascript - 子进程 setInterval 偶尔不会触发
- java - 递归期间的奇怪错误
- swift - 如何从 .sks 文件加载精灵以显示在我的 ARSKView 中?
- html - 将 SVG 用于向量及其与浏览器的兼容性