android蓝牙连接状态变化,当蓝牙连接状态发生变化时,防止onDestroy(示例代码)

目标

如果已连接的蓝牙设备断开连接,并且活动已在运行,请关闭活动

问题

当蓝牙设备连接状态通过BluetoothAdapterProperties:CONNECTION_STATE_CHANGE更改时,似乎创建了一个新的活动或当前的活动重新启动。

代码中没有任何内容可以监听和/或应该对蓝牙连接状态的变化作出反应。

问题表现在BroadcastReceivers的使用上,而BroadcastReceivers又使用意图启动Activity。出于某种原因,即使蓝牙连接的唯一变化是BluetoothAdapterProperties,活动也会在其生命周期中运行,产生新的窗口:CONNECTION_STATE_CHANGE

我已经在Android N的Nexus 6P上进行了测试。我还不知道这个实现对于任何其他设备意味着什么样的影响。但我至少需要在一台设备上使用它。

UPDATE

我做了一些实验,发现如果我没有在AndroidManifest中注册BroadcastReceiver,那么调用onDestroy的问题就会消失。但是,我希望能够对蓝牙连接设备作出反应,以便我可以启动我的活动,然后处理输入。如果每次新设备连接/断开连接时活动都被销毁,这根本不起作用。如果BroadcastReceiver已经在运行并且可以控制该行为,那么让它成为活动的原因是什么?

更新2

我还可以得出结论,使用这种方法https://stackoverflow.com/a/6529365/975641禁用静态声明的BroadcastReceiver并不会改进。一旦Manifest-BroadcastReceiver从Android捕获ACL_CONNECTED意图并启动我的自定义活动,当连接状态发生变化时(通常在ACL_DISCONNECTED之前),它将无情地在其上调用onDestroy。如果我在Manifest中声明了ACL_DISCONNECTED,则无关紧要。只要我的接收器侦听ACL_CONNECTED意图并基于此启动我的Activity,就会在连接状态发生变化时调用onDestroy。太令人沮丧了。

表现

android:allowBackup="true"

android:icon="@mipmap/ic_launcher"

android:label="@string/app_name"

android:supportsRtl="true"

android:theme="@style/AppTheme">

android:name=".BtActivity"

android:launchMode="singleTop" />

BtConnectionBroadcastReceiver

public class BtConnectionBroadcastReceiver extends BroadcastReceiver {

private static final String TAG = "BT";

public static final String BROADCAST_ACTION_CONNECTED = "CONNECTED";

public static final String BROADCAST_ACTION_DISCONNECTED = "DISCONNECTED";

SharedPreferences mSharedPreferences;

@Override

public void onReceive(Context context, Intent intent) {

String action = intent.getAction();

// When discovery finds a device

if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {

// Get the BluetoothDevice object from the Intent

Log.d(TAG, "DEVICE CONNECTED");

BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

Log.d("DEVICE NAME", device.getName());

Log.d("DEVICE ADDRESS", device.getAddress());

Intent i = new Intent(context, BtActivity.class);

i.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

context.startActivity(i);

} else if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {

Log.d(TAG, "DEVICE DISCONNECTED");

intent = new Intent();

intent.setAction(BtConnectionBroadcastReceiver.BROADCAST_ACTION_DISCONNECTED);

context.sendBroadcast(intent);

}

}

BtActivity

public class BtActivity extends AppCompatActivity {

private static final String TAG = "BT";

Window mWindow;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_bt);

Log.d(TAG, "onCreate");

IntentFilter filter = new IntentFilter(BtConnectionBroadcastReceiver.INTENT_FILTER);

filter.addAction(BtConnectionBroadcastReceiver.BROADCAST_ACTION_CONNECTED);

filter.addAction(BtConnectionBroadcastReceiver.BROADCAST_ACTION_DISCONNECTED);

//registerReceiver(mReceiver, filter);

mWindow = getWindow();

WindowManager.LayoutParams params = new WindowManager.LayoutParams();

//params.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_OFF;

params.screenBrightness = 0.2f;

mWindow.setAttributes(params);

mWindow.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);

mWindow.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);

mWindow.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);

mWindow.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

mWindow.addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);

mWindow.getDecorView().setSystemUiVisibility(

View.SYSTEM_UI_FLAG_LAYOUT_STABLE |

View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |

View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |

View.SYSTEM_UI_FLAG_FULLSCREEN |

View.SYSTEM_UI_FLAG_IMMERSIVE);

}

@Override

protected void onResume() {

super.onResume();

Log.d(TAG, "onResume");

}

@Override

protected void onDestroy() {

super.onDestroy();

Log.d(TAG, "onDestroy");

}

BroadcastReceiver mReceiver = new BroadcastReceiver() {

@Override

public void onReceive(Context context, Intent intent) {

Log.d(TAG, "BROADCAST RECEIVED IN ACTIVITY");

String mac;

if(intent.getAction().equals(BtConnectionBroadcastReceiver.BROADCAST_DEVICE_CONNECTED)) {

Log.d(TAG, "CONNECT BROADCAST RECEIVED");

mac = intent.getStringExtra("mac");

checkConnectedDevice(mac, true); // This adds a device to an internal list

Log.d(TAG, "Activity nr of devices:" +mNrOfDevices);

}

if(intent.getAction().equals(BtConnectionBroadcastReceiver.BROADCAST_DEVICE_DISCONNECTED)) {

Log.d(TAG, "DISCONNECT BROADCAST RECEIVED");

mac = intent.getStringExtra("mac");

checkConnectedDevice(mac, false); // This removes a device from an internal list

Log.d(TAG, "Activity nr of devices:" +mNrOfDevices);

if(mNrOfDevices < 1) {

Log.d(TAG, "No more connected devices");

finish();

}

}

abortBroadcast();

}

};

}

当我运行此代码时,我得到以下链:

启动MainActivity(不包括在内,它只包含一个具有默认主布局的活动,以便注册应用程序接收器)

打开蓝牙设备(这已经配对了,所以android知道它)

等到它连接并得到这个:

设备已连接

的onCreate

的onResume

关闭蓝牙设备然后我得到这个:

设备已断开连接

的onDestroy

的onCreate

的onResume

我无法理解为什么活动在此时重新开始被破坏。活动已在运行,BroadcastReceiver仅向已经运行的活动发送广播。我无法弄清楚为什么Activity会自行杀死然后重新启动。这使我处于Activity仍在运行的状态,但它不是启动的原始Activity。

然而,我确实在logcats中看到了一些似乎与此有关的东西,而且正是在这个排序中;

06-02 15:45:09.156 26431 26431 D BT:设备已断开连接

06-02 15:45:09.213 19547 19547 D BluetoothAdapterService:handleMessage() - MESSAGE_PROFILE_CONNECTION_STATE_CHANGED

06-02 15:45:09.213 26431 26431 D BTI:onDestroy

06-02 15:45:09.214 19547 19547 D BluetoothAdapterProperties:CONNECTION_STATE_CHANGE:FF:FF:20:00:C1:47:2 - > 0

06-02 15:45:09.216 3502 3805 D CachedBluetoothDevice:onProfileStateChanged:profile HID newProfileState 0

06-02 15:45:09.237 414 414 W SurfaceFlinger:无法登录到二进制事件日志:溢出。

06-02 15:45:09.239 26431 26431 D BT:onCreate

06-02 15:45:09.243 26431 26431 D BT:对不起

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值