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):
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?
@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.
Most helpful comment
@Fedelaus the error
Failed resolving method startActivityForResultmight indicate that there are invalid arguments passed tostartActivityForResult.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.
I had to remove the
setDatafor 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.