I'm developing a Flutter Plugin for Android using Java. When i call the MethodChannel, I need to call another Android Intent. If I was using an native activity, it would be simple since I can call startActivityForResult
and implement the method onActivityResult
on the same class.
But, when I develop a Flutter Plugin, I can implement FlutterPlugin
, MethodCallHandler
and ActivityAware
interfaces but how can I start a new activity and listen for async result?
Java code:
public class GetnetPlugin implements FlutterPlugin, MethodCallHandler, ActivityAware {
private MethodChannel channel;
private Context context;
private Activity activity;
@Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
context = flutterPluginBinding.getApplicationContext();
channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "com.example/method");
channel.setMethodCallHandler(this);
}
@Override
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
channel.setMethodCallHandler(null);
}
@Override
public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
switch (call.method){
case "makePayment":
makePayment();
result.success(true);
return;
default:
result.notImplemented();
return;
}
}
@Override
public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) {
this.activity = binding.getActivity();
}
@Override
public void onDetachedFromActivityForConfigChanges() {
this.activity = null;
}
@Override
public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) {
this.activity = binding.getActivity();
}
@Override
public void onDetachedFromActivity() {
this.activity = null;
}
//This is the method that is called with main action. It starts a new activity by a new intent, then it should listen for a async result
public void makePayment(){
Bundle bundle = new Bundle();
DecimalFormat df = new DecimalFormat("000000000000");
bundle.putString("amount", df.format(10));
bundle.putString("paymentType", "credit");
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("getnet://pagamento/v3/payment"));
intent.putExtras(bundle);
if(intent != null) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activity.startActivityForResult(intent, REQUEST_CODE);
}
}
//This is the method that I need to be called after new activity returns a result
public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
channel.invokeMethod("success", data);
}
});
}
}
Flutter side:
class Getnet {
final MethodChannel _channel =
const MethodChannel('com.example/method');
final StreamController _streamController = StreamController.broadcast();
Getnet() {
_channel.setMethodCallHandler((call) async {
final method = call.method;
switch (method) {
case 'success':
_streamController.sink.add({
"status": 1,
"msg": call.arguments,
});
break;
case 'error':
_streamController.sink.add({
'status': 0,
'msg': call.arguments['errorMessage'],
});
break;
}
});
}
void dispose() {
_streamController.close();
}
Stream get stream => _streamController.stream;
Future makePayment() async {
await _channel.invokeMethod('makePayment');
}
}