真实设备上不调用广播接收器
Broadcast receiver is not called on real devices
我已经将目标版本从 Android 8 更新到 Android 10 之后我遇到了广播接收器没有在设备上被调用的问题(我已经在 Samsung s9(Pie) 上测试过, Mi Note 5(Oreo)) 接受 Google Pixel 2 XL 设备(Android 10) 但它在 Genymotion Samsung s9 模拟器或任何模拟器上运行良好。谁能说出可能的问题是什么?
内部有一个名为 SipService 的服务,它注册了 Intent 过滤器,我们从 activity 之一触发了 Intent 过滤器之一。部分代码如下。
ACtivity
onCreate() 方法内部
registerReceiver(registrationStateReceiver, new IntentFilter(SipManager.ACTION_SIP_REGISTRATION_CHANGED));
bindService(new Intent(mContext, SipService.class), connection, Context.BIND_AUTO_CREATE);
在一些 Webservice 调用和操作之后,我们将如下调用已注册的 Intent Filter 之一。
Intent intent = new Intent(SipManager.ACTION_SIP_REQUEST_RESTART);
sendBroadcast(intent);
SipService 内部 class
private void registerBroadcasts() {
// Register own broadcast receiver
if (deviceStateReceiver == null) {
IntentFilter intentfilter = new IntentFilter();
intentfilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
intentfilter.addAction(SipManager.ACTION_SIP_ACCOUNT_CHANGED);
intentfilter.addAction(SipManager.ACTION_SIP_ACCOUNT_DELETED);
intentfilter.addAction(SipManager.ACTION_SIP_CAN_BE_STOPPED);
intentfilter.addAction(SipManager.ACTION_SIP_REQUEST_RESTART);
intentfilter.addAction(DynamicReceiver4.ACTION_VPN_CONNECTIVITY);
if (Compatibility.isCompatible(5)) {
deviceStateReceiver = new DynamicReceiver5(this);
} else {
deviceStateReceiver = new DynamicReceiver4(this);
}
registerReceiver(deviceStateReceiver, intentfilter);
deviceStateReceiver.startMonitoring();
}
}
接收者Class
public class DynamicReceiver4 extends BroadcastReceiver {
private static final String THIS_FILE = "DynamicReceiver";
// Comes from android.net.vpn.VpnManager.java
// Action for broadcasting a connectivity state.
public static final String ACTION_VPN_CONNECTIVITY = "vpn.connectivity";
/** Key to the connectivity state of a connectivity broadcast event. */
public static final String BROADCAST_CONNECTION_STATE = "connection_state";
private SipService service;
// Store current state
private String mNetworkType;
private boolean mConnected = false;
private String mRoutes = "";
private boolean hasStartedWifi = false;
private Timer pollingTimer;
/**
* Check if the intent received is a sticky broadcast one
* A compat way
* @param it intent received
* @return true if it's an initial sticky broadcast
*/
public boolean compatIsInitialStickyBroadcast(Intent it) {
if(ConnectivityManager.CONNECTIVITY_ACTION.equals(it.getAction())) {
if(!hasStartedWifi) {
hasStartedWifi = true;
return true;
}
}
return false;
}
public DynamicReceiver4(SipService aService) {
service = aService;
}
@Override
public void onReceive(final Context context, final Intent intent) {
// Run the handler in SipServiceExecutor to be protected by wake lock
service.getExecutor().execute(new SipService.SipRunnable() {
public void doRun() throws SipService.SameThreadException {
onReceiveInternal(context, intent, compatIsInitialStickyBroadcast(intent));
}
});
}
/**
* Internal receiver that will run on sip executor thread
* @param context Application context
* @param intent Intent received
* @throws SameThreadException
*/
private void onReceiveInternal(Context context, Intent intent, boolean isSticky) throws SipService.SameThreadException {
String action = intent.getAction();
Log.d(THIS_FILE, "Internal receive " + action);
if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
ConnectivityManager cm =
(ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
onConnectivityChanged(activeNetwork, isSticky);
} else if (action.equals(SipManager.ACTION_SIP_ACCOUNT_CHANGED)) {
final long accountId = intent.getLongExtra(SipProfile.FIELD_ID, SipProfile.INVALID_ID);
// Should that be threaded?
if (accountId != SipProfile.INVALID_ID) {
final SipProfile account = service.getAccount(accountId);
if (account != null) {
Log.d(THIS_FILE, "Enqueue set account registration");
service.setAccountRegistration(account, account.active ? 1 : 0, true);
}
}
} else if (action.equals(SipManager.ACTION_SIP_ACCOUNT_DELETED)){
final long accountId = intent.getLongExtra(SipProfile.FIELD_ID, SipProfile.INVALID_ID);
if(accountId != SipProfile.INVALID_ID) {
final SipProfile fakeProfile = new SipProfile();
fakeProfile.id = accountId;
service.setAccountRegistration(fakeProfile, 0, true);
}
} else if (action.equals(SipManager.ACTION_SIP_CAN_BE_STOPPED)) {
service.cleanStop();
} else if (action.equals(SipManager.ACTION_SIP_REQUEST_RESTART)){
service.restartSipStack();
} else if(action.equals(ACTION_VPN_CONNECTIVITY)) {
onConnectivityChanged(null, isSticky);
}
}
实际上,我的错基本上是 ABI(应用程序二进制接口)问题导致 64 位设备出现问题。
我已经将目标版本从 Android 8 更新到 Android 10 之后我遇到了广播接收器没有在设备上被调用的问题(我已经在 Samsung s9(Pie) 上测试过, Mi Note 5(Oreo)) 接受 Google Pixel 2 XL 设备(Android 10) 但它在 Genymotion Samsung s9 模拟器或任何模拟器上运行良好。谁能说出可能的问题是什么?
内部有一个名为 SipService 的服务,它注册了 Intent 过滤器,我们从 activity 之一触发了 Intent 过滤器之一。部分代码如下。
ACtivity
onCreate() 方法内部
registerReceiver(registrationStateReceiver, new IntentFilter(SipManager.ACTION_SIP_REGISTRATION_CHANGED));
bindService(new Intent(mContext, SipService.class), connection, Context.BIND_AUTO_CREATE);
在一些 Webservice 调用和操作之后,我们将如下调用已注册的 Intent Filter 之一。
Intent intent = new Intent(SipManager.ACTION_SIP_REQUEST_RESTART);
sendBroadcast(intent);
SipService 内部 class
private void registerBroadcasts() {
// Register own broadcast receiver
if (deviceStateReceiver == null) {
IntentFilter intentfilter = new IntentFilter();
intentfilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
intentfilter.addAction(SipManager.ACTION_SIP_ACCOUNT_CHANGED);
intentfilter.addAction(SipManager.ACTION_SIP_ACCOUNT_DELETED);
intentfilter.addAction(SipManager.ACTION_SIP_CAN_BE_STOPPED);
intentfilter.addAction(SipManager.ACTION_SIP_REQUEST_RESTART);
intentfilter.addAction(DynamicReceiver4.ACTION_VPN_CONNECTIVITY);
if (Compatibility.isCompatible(5)) {
deviceStateReceiver = new DynamicReceiver5(this);
} else {
deviceStateReceiver = new DynamicReceiver4(this);
}
registerReceiver(deviceStateReceiver, intentfilter);
deviceStateReceiver.startMonitoring();
}
}
接收者Class
public class DynamicReceiver4 extends BroadcastReceiver {
private static final String THIS_FILE = "DynamicReceiver";
// Comes from android.net.vpn.VpnManager.java
// Action for broadcasting a connectivity state.
public static final String ACTION_VPN_CONNECTIVITY = "vpn.connectivity";
/** Key to the connectivity state of a connectivity broadcast event. */
public static final String BROADCAST_CONNECTION_STATE = "connection_state";
private SipService service;
// Store current state
private String mNetworkType;
private boolean mConnected = false;
private String mRoutes = "";
private boolean hasStartedWifi = false;
private Timer pollingTimer;
/**
* Check if the intent received is a sticky broadcast one
* A compat way
* @param it intent received
* @return true if it's an initial sticky broadcast
*/
public boolean compatIsInitialStickyBroadcast(Intent it) {
if(ConnectivityManager.CONNECTIVITY_ACTION.equals(it.getAction())) {
if(!hasStartedWifi) {
hasStartedWifi = true;
return true;
}
}
return false;
}
public DynamicReceiver4(SipService aService) {
service = aService;
}
@Override
public void onReceive(final Context context, final Intent intent) {
// Run the handler in SipServiceExecutor to be protected by wake lock
service.getExecutor().execute(new SipService.SipRunnable() {
public void doRun() throws SipService.SameThreadException {
onReceiveInternal(context, intent, compatIsInitialStickyBroadcast(intent));
}
});
}
/**
* Internal receiver that will run on sip executor thread
* @param context Application context
* @param intent Intent received
* @throws SameThreadException
*/
private void onReceiveInternal(Context context, Intent intent, boolean isSticky) throws SipService.SameThreadException {
String action = intent.getAction();
Log.d(THIS_FILE, "Internal receive " + action);
if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
ConnectivityManager cm =
(ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
onConnectivityChanged(activeNetwork, isSticky);
} else if (action.equals(SipManager.ACTION_SIP_ACCOUNT_CHANGED)) {
final long accountId = intent.getLongExtra(SipProfile.FIELD_ID, SipProfile.INVALID_ID);
// Should that be threaded?
if (accountId != SipProfile.INVALID_ID) {
final SipProfile account = service.getAccount(accountId);
if (account != null) {
Log.d(THIS_FILE, "Enqueue set account registration");
service.setAccountRegistration(account, account.active ? 1 : 0, true);
}
}
} else if (action.equals(SipManager.ACTION_SIP_ACCOUNT_DELETED)){
final long accountId = intent.getLongExtra(SipProfile.FIELD_ID, SipProfile.INVALID_ID);
if(accountId != SipProfile.INVALID_ID) {
final SipProfile fakeProfile = new SipProfile();
fakeProfile.id = accountId;
service.setAccountRegistration(fakeProfile, 0, true);
}
} else if (action.equals(SipManager.ACTION_SIP_CAN_BE_STOPPED)) {
service.cleanStop();
} else if (action.equals(SipManager.ACTION_SIP_REQUEST_RESTART)){
service.restartSipStack();
} else if(action.equals(ACTION_VPN_CONNECTIVITY)) {
onConnectivityChanged(null, isSticky);
}
}
实际上,我的错基本上是 ABI(应用程序二进制接口)问题导致 64 位设备出现问题。