SetResult не возвращается к вызову onActivityResult после первого раза

#java #android #android-activity #realm

#java #Android #android-активность #область

Вопрос:

У меня возникли некоторые проблемы с onActivityResult. У меня есть 2 действия: LoginActivity и MainActivity. MainActivity — это действие запуска. При создании он проверяет, есть ли зарегистрированный пользователь, если нет, он запускает LoginActivity с помощью startActivityForResult() . Когда пользователь успешно входит в систему, метод SetResult(), а затем finish() вызывается при LoginActivity . Это запускает onActivityResult для MainActivity. Все работает нормально.

Тем не менее, у меня есть кнопка выхода из системы в MainActivity. При нажатии он удаляет сеанс текущего пользователя и снова вызывает startActivityForResult и запускает LoginActivity. Тот же поток, только после вызова SetResult() и finish() при LoginActivity на этот раз MainActivity не отображается (приложение переходит в фоновый режим), а onActivityResult() не вызывается. onActivityResult() вызывается только тогда, когда я вручную выводю приложение на передний план. Что дает?

Почему onActivityResult вызывается при первом входе в систему, но не при втором?

Фрагмент манифеста:

         <activity
            android:name=".activities.MainActivity"
            android:label="@string/title_activity_main">
            <intent-filter android:label="@string/app_name">
                <category android:name="android.intent.category.LAUNCHER" />
                <action android:name="android.intent.action.MAIN" />
            </intent-filter>
        </activity>
 

Фрагмент LoginActivity:

 /**
     * Saves the logged in session in the db and creates a UserModel if it's a new user logging in
     * @param intent
     */
    private void saveSession(Intent intent) {

        Session session = intent.getParcelableExtra(Session.SESSION);
        User user = session.getUser();

        realm.beginTransaction();

        //Check if user exists in db
        UserModel userModel = realm.where(UserModel.class).equalTo(PATIENT_ID, session.getUser().getPatientId()).findFirst();

        if(userModel == null) {
            userModel = new UserModel();
            userModel.setLanguage(user.getLanguage());
            userModel.setLastLogin(user.getLastLogin());
            userModel.setPatientId(user.getPatientId());
            userModel.setPermissions(new RealmList<RealmString>());
            for(int i = 0;user.getPermissions().size()>i;i  ) {
                RealmString realmString = new RealmString();
                realmString.setValue(user.getPermissions().get(i));
                userModel.getPermissions().add(realmString);
            }
            userModel.setRegistered(user.getRegistered());
            userModel.setRole(user.getRole());
            userModel.setUserName(user.getUserName());
        }
        UserSessionModel userSession = new UserSessionModel();
        userSession.setUser(userModel);
        userSession.setCookie(session.getCookie());
        userSession.setJwt(session.getJwt());
        realm.copyToRealmOrUpdate(userSession);

        realm.commitTransaction();


        mJwt = session.getJwt();


        finish();
    }

    @Override
    public void finish() {
        Intent result = new Intent();
        result.putExtra(LoginActivity.JWT, mJwt);
        setResult(Activity.RESULT_OK, result);
        super.finish();
    }
 

MainActivity:

 /**
     * Show all the accounts registered on the device.
     * If there are no accounts, start LoginActivity to create one.
     */
    private void getAccount() {

        //Get all accounts
        final RealmResults<UserModel> availableAccounts = realm.where(UserModel.class).findAll();
        if(availableAccounts.size() == 0) {
            //Open login activity if there are no accounts
            Intent intent = new Intent(this, LoginActivity.class);
            this.startActivityForResult(intent, AUTHENTICATE);
        } else if (availableAccounts.size() > 0) {
            availableAccounts.sort("lastLogin", Sort.DESCENDING);
            UserModel account = availableAccounts.get(0);
            getSession(account);
        }
    }

/**
     * Get an authentication token
     */
    private void getSession(UserModel account) {
        UserSessionModel result = realm.where(UserSessionModel.class)
                .equalTo("user.patientId", account.getPatientId())
                .findFirst();

        if(result != null) {
            init(result);
        } else {
            //Authenticate existing account
            Intent intent = new Intent(this, LoginActivity.class);
            intent.putExtra(LoginActivity.PATIENT_ID, account.getPatientId());
            this.startActivityForResult(intent, AUTHENTICATE);
        }
    }
 

Logout in MainActivity

 /**
     * Logout and return to login view
     */
    private void logout() {
        showProgress(true);
        mLogoutTask = new UserLogoutTask(mSession.getCookie());
        if(mSession !=null) {
            realm.beginTransaction();
            mSession.deleteFromRealm();
            realm.commitTransaction();
        }
        mLogoutTask.execute();
        mSession = null;
        getAccount();
    }
 

onActivityResult в MainActivity

 @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        switch (requestCode) {
            case AUTHENTICATE:
                if(resultCode == RESULT_OK){
                    Bundle bundle = data.getExtras();
                    String jwt = bundle.getString(LoginActivity.JWT);
                    UserSessionModel session = realm.where(UserSessionModel.class).equalTo("jwt", jwt).findFirst();
                    init(session);
                }
                break;
        }
    }
 

Метод инициализации

 private void init(final UserSessionModel session) {

        mSession = session;

        View headerView = navigationView.getHeaderView(0);
        lblUsername = ButterKnife.findById(headerView, R.id.header_username);
        // Set username in menu header
        lblUsername.setText(getString(R.string.welcome, mSession.getUser().getUserName()));

        Crashlytics.setUserIdentifier(mSession.getUser().getPatientId());

        //Need to do this for the following code because Realm only allows access to object in the same threads
        final String patientId = mSession.getUser().getPatientId();

        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MRESIST_LOCATION_PERMISSION_CHANGED);
        } else {
            startGPSService();
        }

        //Start sensor service
        Thread t = new Thread(){
            public void run(){
                sensorServiceIntent = new Intent(getApplicationContext(), SensorService.class);
                sensorServiceIntent.putExtra("patientId", patientId);
                getApplicationContext().startService(sensorServiceIntent);
            }
        };
        t.start();
    }
 

Комментарии:

1. вы также должны добавить фрагмент для onActivityResult() метода в свой MainActivity

2. Спасибо, добавлен фрагмент onActivityResult!

3. ну, здесь ничего подозрительного. Мне любопытно, что делает ваш init метод.

4. Добавлено и это 😉

5. Нет, но это могло быть причиной вашей проблемы при использовании launchMode, такого как singleInstance. Используете ли вы этот метод moveTaskToBack() в своем MainActivity ? У меня заканчиваются идеи.