我有一个应用LoginActivity
- > MainActivity
。主要活动是这样开始的,因为我不想将LoginActivity
添加到堆栈中:
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
启动MainActivity
后,在onResume
中,我会检查蓝牙是否已启用。如果没有,请询问用户是否要启用它(这发生在帮助程序类btHelper
中):
public void enableBT(){
if (!mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
mainActivity.startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
}
所以在这里,我需要检查用户选择的内容。如果他们选择是,那么我将启用BT并注册广播接收器。如果他们选择否,我想完成MainActivity
并返回LoginActivity
:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == btHelper.REQUEST_ENABLE_BT) {
if (resultCode == RESULT_OK) {
//Register broadcast receiver once BT is enabled
btHelper.registerBroadcastReceiver();
} else {
Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finishAffinity();
}
}
}
当我运行应用程序时,如果用户选择“是”,那么一切正常。如果他们选择“否”,那么一切正常,他们就会进入“登录”界面。然而,当他们再次登录时,当然会出现对话框,询问他们是否要启用BT,但是如果他们第二次选择“否”,那么他们就不会被带到登录状态 - 对话框只是重新显示
我已经看到了这个问题here但它似乎不适用,因为我没有以编程方式设置任何结果。出于某种原因,用户选择No / Deny只能在第一次正确检查而不是第二次
鉴于当我单击No / Deny时,对话框再次显示,我想可能再次调用onResume()
,因此调用enableBT()
?我不确定问题是这样的,还是我处理活动之间的转换
编辑:
我把问题缩小了一点。每当调用resultCode
时,我都会添加一行来注销onActivityResult
值。在第一次运行期间,resultCode
正确显示,但在重新启动MainActivity
后第二次运行时,没有记录任何代码。通过一些更多的测试,似乎在第二次运行时,无论何时我点击No / Deny,都会调用enableBT
/ onResume
而不是先检查结果代码以确定它应该做什么 - 它只是自动重启活动/片段。这是否意味着onActivityResult
没有被调用或者没有结果代码?
EDIT2:下面添加完整代码......
LoginActivity:
public class LoginActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Check if this is a fresh app launch, or a launcher click after app minimize
if (!isTaskRoot()
&& getIntent().hasCategory(Intent.CATEGORY_LAUNCHER)
&& getIntent().getAction() != null
&& getIntent().getAction().equals(Intent.ACTION_MAIN)) {
finish();
return;
}
setContentView(R.layout.activity_login);
coordinatorLayoutView = findViewById(R.id.coordinator_layout_login);
//get views for textboxes and buttons
loginButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//perform some password checking, then login
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
}
});
}
}
MainActivity:
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Get fragment manager
fragmentManager = getSupportFragmentManager();
//Start the initial fragment
connectFragment = new ConnectFragment();
addFragment(connectFragment, false);
//Set navigation drawer/menu here
//Create bluetooth helper
btHelper = BTHelper.getInstance(this);
}
@Override
protected void onResume(){
super.onResume();
//Check and enable bluetooth
if (btHelper.getBTAdapter() == null) {
//Show alert here saying bluetooth is required, when OK is pressed, invoke `quitToLogin()`
} else {
//If bluetooth is not enabled, ask to enable it
btHelper.enableBT();
}
}
@Override
protected void onDestroy() {
Log.d(TAG, "onDestroy called");
super.onDestroy();
btHelper.unregisterBroadcastReceiver();
}
public void addFragment(Fragment fragment, Boolean addToBackStack) {
if (fragment != null) {
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
//Check getFragments() == null to prevent the initial blank
//fragment (before 'Connect' fragment is displayed) from being added to the backstack
if (fragmentManager.getFragments() == null || !addToBackStack) {
fragmentTransaction.replace(R.id.fragment_container, fragment, fragment.getClass().getSimpleName())
.commit();
} else {
fragmentTransaction.replace(R.id.fragment_container, fragment, fragment.getClass().getSimpleName())
.addToBackStack(null)
.commit();
}
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d(TAG, "Result code: " + Integer.toString(resultCode));
if (requestCode == btHelper.REQUEST_ENABLE_BT) {
if (resultCode == RESULT_OK) {
//Register broadcast receiver once BT is enabled
btHelper.registerBroadcastReceiver();
} else {
quitToLogin();
}
} else if (requestCode == btHelper.REQUEST_ENABLE_DISCOVERABLE) {
if (resultCode == 60) { //result code is discoverable time set in helper
//Start discovery
btHelper.startDiscovery();
} else {
//do other things
}
}
}
public void quitToLogin(){
Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finishAffinity();
}
}
BTHelper:
public class BTHelper {
public static final String TAG = "BTHelper";
private static BTHelper sInstance;
Activity mainActivity;
private BluetoothAdapter mBluetoothAdapter;
final int REQUEST_ENABLE_BT = 0;
final int REQUEST_ENABLE_DISCOVERABLE = 1;
//Flags
Boolean discoveryStarted;
Boolean broadcastReceiverEnabled;
public static synchronized BTHelper getInstance(Activity activity) {
if (sInstance == null) {
sInstance = new BTHelper(activity);
Log.d(TAG, "New BTHelper created");
}
return sInstance;
}
private BTHelper(Activity activity) {
this.mainActivity = activity;
this.mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
this.discoveryStarted = false;
this.broadcastReceiverEnabled = false;
}
public BluetoothAdapter getBTAdapter(){
return this.mBluetoothAdapter;
}
public void enableBT(){
if (!mBluetoothAdapter.isEnabled()) {
Log.d(TAG, "enableBT is called");
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
mainActivity.startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
}
public void registerBroadcastReceiver(){
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
mainActivity.registerReceiver(mReceiver, filter);
this.broadcastReceiverEnabled = true;
}
public void unregisterBroadcastReceiver(){
if(this.broadcastReceiverEnabled){
mainActivity.unregisterReceiver(mReceiver);
}
this.broadcastReceiverEnabled = false;
}
public boolean checkBondedDevices(){
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
// Loop through paired devices to check for match
for (BluetoothDevice device : pairedDevices) {
//conditions here to find a specific device and connect to it
return true;
}
}
}
return false;
}
public void enableDiscoverable(){
//Enable discoverability
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 60);
mainActivity.startActivityForResult(discoverableIntent, REQUEST_ENABLE_DISCOVERABLE);
}
public void startDiscovery(){
//Start discovering devices
Log.d(TAG, "Starting discovery...");
this.discoveryStarted = true;
mBluetoothAdapter.startDiscovery();
}
// Create a BroadcastReceiver for bluetooth ACTION_FOUND
public final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
//Check for matching device
if(check device name/MAC address of specific device){
//Stop discovery
discoveryStarted = false;
mBluetoothAdapter.cancelDiscovery();
//Connect to device here
}
}
}
};
}
答案 0 :(得分:2)
您的BTHelper
类是Singleton
,这意味着在应用程序运行时只有一个实例可用。
因此,在getInstance()
方法中,您将Activity
传递给它。第一次使用活动初始化它。活动结束,登录“新”后,MainActivity将启动。它再次调用BTHelper.getInstance(this)
。这次它看到sInstance
不为空(因为sInstance
是静态的并且先前已设置过),所以它返回sInstance
,它保留了之前对前一个主要活动的引用很可能被毁实际上,在getInstance
课程中有一个经过许可的Singleton
是非常糟糕的做法。您有BTHelper
的一个副本,但是您希望将其与主要活动的不同实例一起使用。因此,每次要使用BTHelper
时,最好有一个字段活动并设置:
btHelper = BTHelper.getInstance();
btHelper.setCallingActivity(this);
您还应该阅读Singleton Design Pattern(如果需要;))