'Flutter In App Purchases not working in module when navigating between native and flutter
I m using in_app_purchase package in Flutter module and then as Flutter Fragment in native android app! It's working fine when we start Flutter screen 1st time and buying but if we came back to native activity and re-opened the flutter screen and try to buy items, the following error is coming!
PlatformException(UNAVAILABLE, BillingClient is unset. Try reconnecting., null, null)
This is my flow inside the app:
- Launched app with native activity
- Launched another activity which extends Fragment Activity
- Inside Fragment Activity I m adding FlutterFragment
- Inside Flutter Screen Initializing in_app_purchase as stated in the readme page.
- Buying consumables and got succeeded.
- Starting initial page of flutter screen (inside flutter module)
- Back to native activity by closing the Fragment Activity which is holding Flutter Fragment.
- Again navigating to Fragment Activity and adding Flutter Fragment then again trying to buy the consumable items.
It shows the above-mentioned error!
Code of Another Activity which extends FragmentActivity
public class FlutterStoreActivity extends FragmentActivity {
MethodChannel channel;
FlutterEngine storeEngine;
FlutterFragment flutterFragment;
DrawerLayout drawerLayout;
RelativeLayout profileRoot, homeRoot;
MainDrawerFragment drawerFragment;
String TAG_FLUTTER_FRAGMENT = "flutterStoreFragmentTag";
TextView titleView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.flutter_store_layout);
homeRoot = findViewById(R.id.flutterStoreHomeButton);
titleView = findViewById(R.id.flutterStoreTitle);
profileRoot = findViewById(R.id.flutterStoreRelative);
homeRoot.setOnClickListener((v)-> channel.invokeMethod("gotoHome", ""));
profileRoot.setOnClickListener((v) -> openDrawer());
drawerLayout = findViewById(R.id.flutterStoreDrawer);
FragmentManager fragmentManager = getSupportFragmentManager();
drawerFragment = new MainDrawerFragment();
fragmentManager.beginTransaction().replace(R.id.flutterStoreNavFragment, drawerFragment, "drawerFragment").commit();
flutterFragment = (FlutterFragment) fragmentManager.findFragmentByTag(TAG_FLUTTER_FRAGMENT);
// if (flutterFragment == null) {
storeEngine = FlutterEngineCache.getInstance().get(MyApplication.FLUTTER_ENGINE_KEY);
flutterFragment = FlutterFragment.withCachedEngine(MyApplication.FLUTTER_ENGINE_KEY)
.renderMode(RenderMode.texture).build();
MyApplication myApplication = MyApplication.getInstance();
channel = new MethodChannel(storeEngine.getDartExecutor().getBinaryMessenger(), "my.flutter.channel");
channel.setMethodCallHandler((call,result)->{
@SuppressWarnings("unchecked") List<Object> params = (List<Object>)call.arguments;
System.out.println("Called Method: "+call.method+" and params are "+params);
switch (call.method){
case "tabChanged": {
titleView.setText(params.get(0).toString());
if(params.size()>1 && (boolean)params.get(1)){
FlutterStoreActivity.this.finish();
}
break;
}
}
});
fragmentManager.beginTransaction().add(R.id.flutterStoreFragment, flutterFragment, TAG_FLUTTER_FRAGMENT).commit();
//}
}
public void openDrawer() {
drawerLayout.openDrawer(GravityCompat.END);
drawerLayout.bringToFront();
}
@Override
public void onPostResume() {
super.onPostResume();
if (flutterFragment != null)
flutterFragment.onPostResume();
}
@Override
protected void onNewIntent(@NonNull Intent intent) {
super.onNewIntent(intent);
if (flutterFragment != null)
flutterFragment.onNewIntent(intent);
}
@Override
public void onBackPressed() {
if (flutterFragment != null)
flutterFragment.onBackPressed();
}
@Override
public void onRequestPermissionsResult(
int requestCode,
@NonNull String[] permissions,
@NonNull int[] grantResults
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (flutterFragment != null)
flutterFragment.onRequestPermissionsResult(
requestCode,
permissions,
grantResults
);
}
@Override
public void onUserLeaveHint() {
if (flutterFragment != null)
flutterFragment.onUserLeaveHint();
}
@Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
if (flutterFragment != null)
flutterFragment.onTrimMemory(level);
}
}
Code of gotHome in Flutter Fragment (module/AAR)
channel.setMethodCallHandler((call) async {
if (call.method == 'gotoHome') {
context.read(internetListener).restartModule();
}
});
The context.read.... is a change notifier and it is in the top declaration of the widget tree. So it won't rebuild by states and its code is
restartModule(){
restart = true;
notifyListeners();
Future.delayed(const Duration(milliseconds: 300),(){
restart = false;
notifyListeners();
SystemChannels.platform.invokeMethod('SystemNavigator.pop');
});
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
