Nativescript: startActivityForResult not defined on android.support.v4.app.FragmentActivity

Created on 2 Jul 2019  路  3Comments  路  Source: NativeScript/NativeScript

Environment
Provide version numbers for the following components (information can be retrieved by running tns info in your project folder or by inspecting the package.json of the project):

  • CLI: 5.4.2
  • Cross-platform modules: 5.4.3
  • Android Runtime: 5.4.0
  • iOS Runtime: 5.4.0
  • Plugin(s): N/A

Describe the bug
Previously, before 5.0.0 and the API 28 stuff, I was using startActivityForResult within a android.app.Activity. Since the change, this is now a android.support.v7.app.AppCompatActivity.

When attempting to call startActivityForResult within this class causes the following error:

Error: java.lang.Exception: Failed resolving method startActivityForResult on class android.support.v4.app.FragmentActivity

which should definitely exist on FragmentActivity from the docs.

To Reproduce

I have found someone whom has described the steps and provided an example, whom is having the same issue:

https://stackoverflow.com/questions/53314046/how-to-use-startactivityforresult-in-nativescript

None of the answers seem to make sense with the issue. Have I missed a step in my update?

needs more info android question

Most helpful comment

@Fedelaus the error Failed resolving method startActivityForResult might indicate that there are invalid arguments passed to startActivityForResult.

I am not aware of your implementation, but if we re-write the example code from SO as shown below, it will work as expected.

let intent = new android.content.Intent(android.provider.Settings.ACTION_HOME_SETTINGS);
let activity = app.android.foregroundActivity || app.android.startActivity;
activity.startActivityForResult(intent, 100);

I had to remove the setData for the intent and also to pass the directly the integer value for the second argument (instead of the marshaled JS this.MY_PERMISSION_REQUEST ). With both changes, the method is working as expected with no crash. Note that the method is used widely in multiple plugins (e.g. nativescript-camera) which again makes me believe that it is related to a wrong argument being passed (e.g., a marshaled number) or improper usage.

All 3 comments

@Fedelaus the error Failed resolving method startActivityForResult might indicate that there are invalid arguments passed to startActivityForResult.

I am not aware of your implementation, but if we re-write the example code from SO as shown below, it will work as expected.

let intent = new android.content.Intent(android.provider.Settings.ACTION_HOME_SETTINGS);
let activity = app.android.foregroundActivity || app.android.startActivity;
activity.startActivityForResult(intent, 100);

I had to remove the setData for the intent and also to pass the directly the integer value for the second argument (instead of the marshaled JS this.MY_PERMISSION_REQUEST ). With both changes, the method is working as expected with no crash. Note that the method is used widely in multiple plugins (e.g. nativescript-camera) which again makes me believe that it is related to a wrong argument being passed (e.g., a marshaled number) or improper usage.

@NickIliev

Thanks for the heads up. Moving from using this.REQUEST_CODE_SET_DEFAULT_DIALER to just 123 was fine.

This is a stripped back version of what I had:

@JavaProxy('com.company.MainActivity')
class Activity extends android.support.v7.app.AppCompatActivity {
    private REQUEST_CODE_SET_DEFAULT_DIALER: number = 123;

    public onCreate(savedInstanceState: android.os.Bundle): void {
            if (!this._callbacks) {
            setActivityCallbacks(this);
        }

        const intent = new android.content.Intent(android.telecom.TelecomManager.ACTION_CHANGE_DEFAULT_DIALER)
            .putExtra(android.telecom.TelecomManager.EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME, this.getPackageName());

        this.startActivityForResult(intent, this.REQUEST_CODE_SET_DEFAULT_DIALER);
    }
...
}

I found this was not working, but moving closer to your example, I changed

this.startActivityForResult(intent, this.REQUEST_CODE_SET_DEFAULT_DIALER);
this.startActivityForResult(intent, 123);

But previously the implementation using this was working and this is code we've not touched in a while.

How come using class scope variables no longer work in 5? I assume it's something to do with the Javascript/Java compilation.

@Fedelaus, can you checkout the following comment in the documentation:

public onCreate(savedInstanceState: android.os.Bundle): void {
    // Set the isNativeScriptActivity in onCreate (as done in the original NativeScript activity code)
    // The JS constructor might not be called because the activity is created from Android.
    this.isNativeScriptActivity = true;
    ...
}

When your typescript is transpiled to javascript you will get something along the lines of:

var Activity = /** @class */ (function (_super) {
    __extends(Activity, _super);
    function Activity() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.REQUEST_CODE_SET_DEFAULT_DIALER = 123;
        return _this;
    }
    Activity.prototype.onCreate = function (savedInstanceState) {
        this.startActivityForResult(null, this.REQUEST_CODE_SET_DEFAULT_DIALER);
    };
    Activity = __decorate([
        JavaProxy('com.company.MainActivity')
    ], Activity);
    return Activity;
}(android.support.v7.app.AppCompatActivity));

Notice how the REQUEST_CODE_SET_DEFAULT_DIALER field is set inside the activity javascript constructor. But if this constructor is never invoked, the field won't be set.

I am not quite sure how this has been working before NativeScript 5.0 but you may try setting your private field inside the onCreate method of the activity.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

NordlingDev picture NordlingDev  路  3Comments

guillaume-roy picture guillaume-roy  路  3Comments

valentinstoychev picture valentinstoychev  路  3Comments

dhanalakshmitawwa picture dhanalakshmitawwa  路  3Comments

fmmsilva picture fmmsilva  路  3Comments