我有一个BroadcastReciever
名称NetworkReciver.java
,该名称在Internet连接或断开连接时执行。而且效果很好。
但是,当应用程序从最近的应用程序中关闭时,NetworkReciver.java
不能在One Plus 6 Phone中执行,而在Samsung Phones中可以正常运行。
我不明白为什么One Plus设备中的行为有所不同
我的代码:
清单
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<receiver android:name=".NetworkReciever" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
NetworkReciever.java:
public class NetworkReciever extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
{
Log.i("TAG", "Network REceiver Executed");
}
}
问题:
从One Plus设备中的最近应用关闭应用后,NetworkReciever不执行。
答案 0 :(得分:4)
从Android N开始,系统不会向目标N +的应用程序的接收方发送CONNECTIVITY_ACTION
广播。
通过BroadcastReceivers
注册的明确Context.registerReceiver()
继续接收这些广播。
答案 1 :(得分:2)
面向Android 7.0+的应用如果注册为在清单中接收它们,则不会接收CONNECTIVITY_ACTION广播,并且依赖于此广播的进程也不会启动。
因此,如果您想在互联网连接可用时做一些工作。您可以使用Job scheduler或work manager。
例如,这是作业调度程序的示例代码。
public static final int MY_BACKGROUND_JOB = 0;
...
public static void scheduleJob(Context context) {
JobScheduler js =
(JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
JobInfo job = new JobInfo.Builder(
MY_BACKGROUND_JOB,
new ComponentName(context, MyJobService.class))
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
.setRequiresCharging(true)
.build();
js.schedule(job);
}
满足您的工作条件时,您的应用程序会收到一个回调,以在指定的JobService.class中运行onStartJob()方法
此外,在活动的onCreate中注册广播并在onDestroy中取消注册对于您的情况将不起作用,因为在应用程序被杀死后您将不会收到广播。
答案 2 :(得分:2)
在Android Nougat中,Android不会广播网络更改以显示已注册的BroadcastReceiver。
从Android Nogout Changes起,在ConnectivityManager中也提到
监控连接的变化
针对Android 7.0(API级别24)及更高版本的应用不会收到 CONNECTIVITY_ACTION广播,如果它们声明广播接收者 在他们的清单上。应用仍将收到CONNECTIVITY_ACTION 如果他们向其注册了BroadcastReceiver广播 Context.registerReceiver(),并且该上下文仍然有效。
从最近使用的应用程序关闭应用程序后,NetworkReciever不执行
我不知道您为什么要在应用关闭后进行网络更改。但是在这种情况下,您必须使用 WorkManager 或 JobScheduler 做一些定期任务。我建议您使用 WorkManager ,因为它适用于所有设备。 JobScheduler 是否仅适用于> = 21版本的设备。 Here是WorkManager的一个很好的例子(非常简单)。
public class MyWorker extends Worker {
@Override
public Worker.Result doWork() {
// get online status
boolean isOnline = isOnline(getApplicationContext());
// Indicate success or failure with your return value:
return Result.SUCCESS;
// (Returning RETRY tells WorkManager to try this task again
// later; FAILURE says not to try again.)
}
public boolean isOnline(Context context) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
//should check null because in airplane mode it will be null
return (netInfo != null && netInfo.isConnected());
}
}
并在应用启动时安排这项工作。
public static void scheduleWork() {
int TIME_INTERVAL_IN_SECONDS = 15;
PeriodicWorkRequest.Builder photoCheckBuilder = new PeriodicWorkRequest.Builder(MyWorker .class, TIME_INTERVAL_IN_SECONDS, TimeUnit.SECONDS);
PeriodicWorkRequest photoCheckWork = photoCheckBuilder.build();
WorkManager instance = WorkManager.getInstance();
if (instance != null) {
instance.enqueueUniquePeriodicWork("TAG", ExistingPeriodicWorkPolicy.KEEP, photoCheckWork);
}
}
或者如果您只是想在应用程序上线时接收网络更改。您可以在下面的解决方案中。
BaseActivity
中。或如果还没有BaseActivity,则创建一个。onStart()
上注册,然后在onStop()
上注销。因为您可能不想在onStop()
之后调用UI。这里是 BaseActivity.java
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
/**
* Created by KHEMRAJ on 9/5/2018.
*/
public class BaseActivity extends AppCompatActivity {
NetworkReceiver receiver;
public boolean isOnline;
@Override
protected void onStart() {
super.onStart();
isOnline = isOnline(this);
// register network change receiver
receiver = new NetworkReceiver();
registerReceiver(receiver, new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE"));
}
@Override
protected void onStop() {
super.onStop();
// unregister network change receiver
unregisterReceiver(receiver);
receiver = null;
}
public class NetworkReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
isOnline = isOnline(context);
Log.i("TAG", "Network REceiver Executed");
}
}
public boolean isOnline(Context context) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
//should check null because in airplane mode it will be null
return (netInfo != null && netInfo.isConnected());
}
}
我只建议您使用WorkManger,因为我之前创建了一个示例 JobScheduler , EvernoteJobs AlarmManager , [JobService] [7] 和 WorkManager 。在其中,我分别开始了15分钟的定期任务。和 调用时将它们的日志记录在单独的文件中。
该测试的结论是。 WorkManager 和 EvernoteJobs 最有效的工作。现在,因为EvernoteJobs将使用 下一版本的WorkManager。所以我想出了WorkManager。
答案 3 :(得分:0)
根本原因:
从Android N开始,OnePlus引入了类似于Mi设备的功能,该功能可防止某些应用在重启后自动启动。我怀疑相同的功能也阻止了您的应用接收BroadcastReceiver
。
解决方案
在您的应用程序中使用AccessibilityService
服务,并要求用户从“设置”中为您的应用程序打开AccessibilityService
,并且在您的应用程序中BroadcastReceiver
都可以正常工作。
由于AccessibilityService
是系统级服务,因此通过注册自己的服务,您将通过这些制造商应用的特定过滤器,并且一旦{{1} },您的应用就会开始接收您已经注册的合格AccessibilityService
。
您可以在这里注册自己的OS
。
创建自定义BroadcastReceiver
AccessibilityService
创建配置文件AccessibilityService
并添加以下代码:
public class MyAccessibilityService extends AccessibilityService {
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {//do nothing }
@Override
public void onInterrupt() { //do nothing}
}
向my_accessibility_service.xml
文件添加权限:
<?xml version="1.0" encoding="utf-8"?>
<accessibility-service
xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityFeedbackType="feedbackSpoken"
android:description="@string/service_desc"
android:notificationTimeout="100"/>
在AndroidManifest.xml
文件中添加<uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE"/>
:
AccessibilityService
您完成了!
以下是检查AndroidManifest.xml
状态的方法:
<service
android:name=".MyAccessibilityService"
android:label="@string/app_name"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService"/>
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="@xml/my_accessibility_service"/>
</service>
注意:我尚未尝试过,但可能会有所帮助。
答案 4 :(得分:0)
Oreo不支持将广播接收器作为清单标签,您必须通过context.registerReceiver()将其注册为服务/活动。或者,您可以使用WorkManager为特定的网络条件安排一些时间。
在OnCreate
NetworkReciever receiver = NetworkReciever ()
IntentFilter filter = new IntentFilter();
filter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
registerReceiver(receiver, filter);
不要忘记在onDestroy
上取消注册
@Override
protected void onDestroy() {
if (receiver != null) {
unregisterReceiver(receiver);
receiver = null;
}
super.onDestroy();
}
并将其从Manifest
<receiver android:name=".NetworkReciever" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>