简体   繁体   English

如何等待onActivityResult完成?

[英]How to wait until onActivityResult finishes?

I have a fragment that shouldn't be opened if a user does NOT approve activation of Bluetooth, which is requested via this piece of code 我有一个片段,如果用户不同意通过这段代码请求激活蓝牙,则不应打开该片段

    Intent mIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
        mIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 240);
            startActivityForResult(mIntent, 1);
    //Here I want to exit the method in case result is denied
getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.content,new ServerFragment()).addToBackStack(null).commit();

I've been looking in quite a few places and the only thing I've found is to use the setResult from a new activity (in my case, the onActivityResult is overridden in the calling activity since this code is within a fragment) 我一直在寻找很多地方,我发现的唯一发现是使用新活动中的setResult(在我的情况下,onActivityResult在调用活动中被覆盖,因为此代码在一个片段中)

Any ideas? 有任何想法吗?

Thanks! 谢谢!

EDIT: Here's a stack trace 编辑:这是堆栈跟踪

java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=131073, result=240, data=null} to activity {bt.bt/bt.bt.MainActivity}: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
                                                                               at android.app.ActivityThread.deliverResults(ActivityThread.java:3659)
                                                                               at android.app.ActivityThread.handleSendResult(ActivityThread.java:3702)
                                                                               at android.app.ActivityThread.access$1300(ActivityThread.java:155)
                                                                               at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1366)
                                                                               at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                               at android.os.Looper.loop(Looper.java:135)
                                                                               at android.app.ActivityThread.main(ActivityThread.java:5343)
                                                                               at java.lang.reflect.Method.invoke(Native Method)
                                                                               at java.lang.reflect.Method.invoke(Method.java:372)
                                                                               at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
                                                                               at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700)
                                                                            Caused by: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState

You should just return in your function after launching the intent. 启动意图后,您应该只返回函数。 You then wait for the callback in onActivityResult. 然后,您等待onActivityResult中的回调。 In this method, if the result is RESULT_OK, then you would start your fragment. 在此方法中,如果结果为RESULT_OK,则将开始片段。

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == your_request_code_here) {
        if (resultCode != Activity.RESULT_CANCELED) {
            // start fragment
        }
    }
}

Full activity: 完整活动:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent mIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
                mIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 240);
                startActivityForResult(mIntent, 1);
            }
        });
    }

    @Override
    public void onPause() {
        super.onPause();
    }

    @Override
    public void onResume() {
        super.onResume();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == 1) {
            if (resultCode != Activity.RESULT_CANCELED) {

            }
        }
    }
}

As in the code pasted by you, you are instantiating the fragment as soon as you called startActivityForResult() , you don't need to do it - that is causing the issue. 就像在您粘贴的代码中一样,您只要调用startActivityForResult()就实例化该片段,就不需要这样做-这会引起问题。 You just have to startActivityForResult() and then in your onActivityResult() method in your activity you can instantiate your fragment if the resultCode is RESULT_OK 您只需启动startActivityForResult() ,然后在活动的onActivityResult()方法中,如果resultCode为RESULT_OK则可以实例化片段

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == your_request_code_here) {
        if (resultCode == Activity.RESULT_OK) {

getSupportFragmentManager().beginTransaction().replace(R.id.content,new ServerFragment()).addToBackStack(null).commit();
        }
    }
}

I think you should use BroadcastReceiver to register an event Bluetooth. 我认为您应该使用BroadcastReceiver来注册事件蓝牙。 In your Manifest.xml, you need to add two statement: 在您的Manifest.xml中,您需要添加两个语句:

<uses-permission android:name="android.permission.BLUETOOTH" />
<receiver android:name=".BluetoothBroadcastReceiver"
              android:label="@string/app_name">
        <intent-filter>
            <action android:name="android.bluetooth.adapter.action.STATE_CHANGED" />
 </intent-filter>
    </receiver>

Then you need to implement onReceive() method : 然后,您需要实现onReceive()方法:

public void onReceive(Context context, Intent intent) {

    String action = intent.getAction();
    Log.d("BroadcastActions", "Action "+action+"received");
    int state;
    BluetoothDevice bluetoothDevice;

    switch(action)
    {
        case BluetoothAdapter.ACTION_STATE_CHANGED:
            state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
            if (state == BluetoothAdapter.STATE_OFF)
            {
                Toast.makeText(context, "Bluetooth is off", Toast.LENGTH_SHORT).show();
                Log.d("BroadcastActions", "Bluetooth is off");
            }
            else if (state == BluetoothAdapter.STATE_TURNING_OFF)
            {
                Toast.makeText(context, "Bluetooth is turning off", Toast.LENGTH_SHORT).show();
                Log.d("BroadcastActions", "Bluetooth is turning off");
            }
            else if(state == BluetoothAdapter.STATE_ON)
            {
getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.content,new ServerFragment()).addToBackStack(null).commit();
                Log.d("BroadcastActions", "Bluetooth is on");
            }
            break;

....
}

You can see more in this link: Android Broadcast Receiver bluetooth events catching 您可以在此链接中看到更多信息: Android Broadcast Receiver蓝牙事件正在捕获

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM