gpt4 book ai didi

android - 蓝牙连接状态更改时防止onDestroy

转载 作者:行者123 更新时间:2023-11-30 00:31:00 27 4
gpt4 key购买 nike

目标


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


问题


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


代码中没有任何内容可以侦听和/或应对蓝牙连接状态的更改做出反应。

该问题通过使用BroadcastReceivers表现出来,而后者又使用意图启动了Activity。由于某种原因,即使蓝牙连接的唯一变化是BluetoothAdapterProperties,Activity仍会在其生命周期中继续运行,并产生新的窗口:CONNECTION_STATE_CHANGE

我仅在配备Android N的Nexus 6P上进行了测试。我还不知道此实现对任何其他设备的影响。但是我至少需要在一台设备上运行它。

更新

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

更新2

我还可以得出结论,使用此方法https://stackoverflow.com/a/6529365/975641禁用静态声明的BroadcastReceiver不会有所改善。一旦Manifest-BroadcastReceiver从Android捕获到ACL_CONNECTED意图,并启动我的自定义活动,则在连接状态更改时(通常在ACL_DISCONNECTED之前),它将无情地调用onDestroy。是否在清单中声明了ACL_DISCONNECTED都没有关系。只要我的接收方正在侦听ACL_CONNECTED意图,并以此为基础启动我的Activity,就可以在连接状态更改时调用onDestroy。真令人沮丧

表现

<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.VIBRATE" />

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".BtActivity"
android:launchMode="singleTop" />
<receiver android:name=".BtConnectionBroadcastReceiver" android:priority="100000">
<intent-filter>
<action android:name="android.bluetooth.device.action.ACL_CONNECTED" />
<action android:name="android.bluetooth.device.action.ACL_DISCONNECTED" />
<action android:name="android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED" />
<action android:name="android.intent.action.MEDIA_BUTTON" />
<action android:name="android.media.VOLUME_CHANGED_ACTION" />
</intent-filter>
</receiver>
</application>


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有理由杀死自己然后再次重新启动。这使我处于“活动”仍在运行的状态,但是不是原来的“活动”已启动。

但是,我确实在logcat中看到了一些与此有关的东西,并且是在这种顺序中。

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 BT:onDestroy

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

06-02 15:45:09.216 3502 3805 D CachedBluetoothDevice:onProfileStateChanged:配置文件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:onResume

最佳答案

在AndroidManifest.xml中为Activity添加以下内容,它对我有用。

android:configChanges="keyboard|keyboardHidden"

关于android - 蓝牙连接状态更改时防止onDestroy,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44367910/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com