我有一个应用 LoginActivity
-> MainActivity
。主要 Activity 是这样开始的,因为我不想将 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但它似乎不适用,因为我没有以编程方式设置任何结果。出于某种原因,用户选择“否”/“拒绝”只会在第一次时得到正确检查,而第二次则不会
考虑到当我单击“否/拒绝”时对话框再次显示,我想也许 onResume()
被再次调用从而调用 enableBT()
?我不确定问题是否与此类似,还是我处理 Activity 之间转换的方式
编辑:
我已经缩小了问题范围。每当调用 onActivityResult
时,我添加了一行以注销 resultCode
值。在第一次运行期间,resultCode
得到正确显示,但在重新启动 MainActivity
后的第二次运行中,没有任何代码被记录。通过更多测试,似乎在第二次运行时,每当我点击否/拒绝时,都会调用 enableBT
/onResume
而不是首先检查结果代码以确定它应该做什么做 - 它只是自动重新启动 Activity/fragment 。这是否意味着 onActivityResult
没有被调用或者没有结果代码?
EDIT2:下面添加了完整的代码......
登录 Activity :
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();
}
});
}
}
主要 Activity :
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();
}
}
BT助手:
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
}
}
}
};
}
最佳答案
您的 BTHelper
类是一个 Singleton
,这意味着在应用程序运行期间只有一个实例可用。
所以在您的 getInstance()
方法中,您将 Activity
传递给它。第一次使用 Activity 初始化它。 Activity 结束,登录 "new" MainActivity 后启动。它再次调用 BTHelper.getInstance(this)
。这次它看到 sInstance
不为空(因为 sInstance
是静态的并且之前已设置),所以它返回保存前一个的 sInstance
引用以前的主要 Activity ,现在可能已被销毁。实际上,在 Singleton
类中使用许可的 getInstance
是非常糟糕的做法。您有一个 BTHelper
副本,但您想将它用于主要 Activity 的不同实例。所以每次你想使用 BTHelper
时最好有一个实地 Activity 和设置:
btHelper = BTHelper.getInstance();
btHelper.setCallingActivity(this);
您还应该阅读 Singleton Design Pattern (如果需要的话;))
关于未检查 Android Activity 结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37628308/