Android 网络更改广播接收器无法在One Plus手机中执行
我有一个Android 网络更改广播接收器无法在One Plus手机中执行,android,broadcastreceiver,Android,Broadcastreceiver,我有一个broadcastReceivernamenetworkReceiver.java,在连接或断开Internet时执行。而且它工作得很好 但当应用程序从最近的应用程序中关闭时,NetworkReciver.java不会在One Plus 6手机上运行,而在三星手机上运行正常 我不明白为什么One Plus设备的行为不同 我的代码: 清单 <uses-permission android:name="android.permission.INTERNET" /> <
broadcastReceiver
namenetworkReceiver.java
,在连接或断开Internet时执行。而且它工作得很好
但当应用程序从最近的应用程序中关闭时,NetworkReciver.java
不会在One Plus 6手机上运行,而在三星手机上运行正常
我不明白为什么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>
问题:
<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>
当从One Plus设备中最近的应用关闭应用时,NetworkReceiver不会执行。根本原因: 安卓N OnePlus推出了一项类似于Mi设备的功能,可防止某些应用程序在重新启动后自动启动。我怀疑同样的功能也阻止了你的应用程序接收
BroadcastReceiver
解决方案
在你的应用程序中使用AccessibilityService
服务,并要求用户从设置中为你的应用程序打开AccessibilityService
,在你的应用程序中执行此操作BroadcastReceiver
将按预期工作
由于AccessibilityService
是一项系统级服务,因此通过注册您自己的服务,您就通过了这些制造商应用的特定过滤器,并且只要您的自定义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\u accessibility\u 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
文件中添加您的AccessibilityService
:
<uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE"/>
<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>
注意:我没有尝试过,但它可能会有所帮助。从Android N开始,系统不会向以N+为目标的应用程序的清单接收者发送
连接\u操作
广播
ExplicitbroadcastReceiver
通过上下文注册。registerReceiver()
继续接收这些广播
解决方案:请参阅以Android 7.0+为目标的应用程序,如果它们在其清单中注册接收连接性行动广播,则不会接收连接性行动广播,并且依赖此广播的进程将不会启动 所以,如果你想在互联网连接可用时做一些工作。您可以使用或 例如,下面是作业调度器的示例代码
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中注销广播对您的情况不起作用,因为在应用程序被终止后,您将不会收到广播。Oreo不支持广播接收器作为清单标记,您必须将其注册为具有上下文的服务/活动。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();
}
并从清单
<receiver android:name=".NetworkReciever" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
在安卓牛轧糖中,安卓不会对清单注册广播接收器的网络更改进行广播。 来自&中也提到了 监控连接的变化 针对Android 7.0(API级别24)及更高版本的应用程序不会收到 如果他们声明广播接收器,则广播 在他们的舱单上。应用程序仍将收到 如果他们将其广播接收器注册到 这一背景仍然有效 解决方案 从最近的应用关闭应用时,不会执行NetworkReceiver 我不知道你为什么要在应用程序关闭后更改网络。但是在这种情况下,您必须使用或进行一些定期任务。我建议您使用WorkManager,因为它适用于所有设备。作业调度器是否仅适用于>=21版本的设备。是WorkManager的一个很好的例子(非常简单) 后台解决方案(仅在需要时执行) 并在应用程序启动时安排此工作
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,也可以创建一个
- 在
上注册,在onStart()
onStop()上注销。因为您可能不想在
之后调用UIonStop()
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,因为我之前创建了一个示例
有,的天数,
,[JobService][7]和。在这篇文章中,我开始了一项15分钟的周期性任务。和
调用时将每个日志写入单独的文件中
本试验的结论是:和是
工作效率最高。现在因为EvernoteJobs将使用
下一版本的WorkManager。所以我想到了工作经理
从最近的抽屉中删除应用程序与
networkreceiver
没有关系,当你的应用程序正在运行且internet连接更改其状态时,将调用你的接收器是的,它必须工作。但它在1+6中不起作用。我检查了很多次,然后在这里发布。你的android设备的API版本是什么?1加6 android 8.1 API级别27可能重复这回答了你的问题吗?
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);
}
}
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());
}
}