未检查Android活动结果

时间:2016-06-04 08:51:33

标签: android android-intent android-activity android-bluetooth

我有一个应用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
                }
            }
        }
    };
}

1 个答案:

答案 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(如果需要;))