flutter_in_app_update
flutter_in_app_update copied to clipboard
How to force update and not to let user to use app?
Hi,
I need to force user to update app always. If they not going to update I should block user not to use app. Also I created a example app and try to use your example, but it didn't work and I guess there was no app that I am running in Google Play.
Later I update my app package name which is already in app store and I keep getting error as shown below.
I/flutter ( 7751): PlatformException(Failed to bind to the service., null, null)
Last, your example uses a button to check for update how to use this without button but in initState? Thanks
Note: I all need is to check for Update initial app initialization than force to make performImmediateUpdate().
My original app:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await SystemChrome.setEnabledSystemUIOverlays([]);
await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
SystemChrome.setEnabledSystemUIOverlays([]);
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
return new MaterialApp(
// TODO: SUPPORTED LOCALE
localizationsDelegates: [
const LangDelegate(),
GlobalMaterialLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
const FallbackCupertinoLocalisationsDelegate(),
],
supportedLocales: [
const Locale('tr', 'TR'),
const Locale('en', 'US'),
const Locale('ru', 'RU'),
],
debugShowCheckedModeBanner: false,
title: 'My Cep',
theme: new ThemeData(
primaryColor: capitalDarkGreen,
fontFamily: "Roboto",
),
home: new MyMainHomePage(),
);
}
}
And in MyMainHomePage I have PackageInfo and Connectivity in initState. So where I code the android app update?
Here is the full code (I am not sure where I am making mistake):
import 'package:flutter/material.dart';
import 'package:upgrader/upgrader.dart';
import 'dart:io' show Platform;
import 'dart:async';
import 'package:in_app_update/in_app_update.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
AppUpdateInfo _updateInfo;
GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey();
bool _flexibleUpdateAvailable = false;
@override
void initState() {
// TODO: implement initState
super.initState();
checkForUpdate();
//InAppUpdate.performImmediateUpdate().catchError((e) => _showError(e));
}
// Platform messages are asynchronous, so we initialize in an async method.
Future<void> checkForUpdate() async {
InAppUpdate.checkForUpdate().then((info) {
setState(() {
_updateInfo = info;
});
}).catchError((e) => _showError(e));
}
void _showError(dynamic exception) {
_scaffoldKey.currentState.showSnackBar(SnackBar(content: Text(exception.toString())));
print(exception.toString());
}
@override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
title: const Text('In App Update Example App'),
),
body: _updateInfo?.updateAvailable == false
? new CircularProgressIndicator()
: Platform.isAndroid == true
? Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: <Widget>[
Center(
child: Text('Update info: $_updateInfo'),
),
RaisedButton(
child: Text('Check for Update'),
onPressed: () => checkForUpdate(),
),
RaisedButton(
child: Text('Perform immediate update'),
onPressed: _updateInfo?.updateAvailable == true
? () {
InAppUpdate.performImmediateUpdate().catchError((e) => _showError(e));
}
: null,
),
RaisedButton(
child: Text('Start flexible update'),
onPressed: _updateInfo?.updateAvailable == true
? () {
InAppUpdate.startFlexibleUpdate().then((_) {
setState(() {
_flexibleUpdateAvailable = true;
});
}).catchError((e) => _showError(e));
}
: null,
),
RaisedButton(
child: Text('Complete flexible update'),
onPressed: !_flexibleUpdateAvailable
? null
: () {
InAppUpdate.completeFlexibleUpdate().then((_) {
_scaffoldKey.currentState.showSnackBar(SnackBar(content: Text('Success!')));
}).catchError((e) => _showError(e));
},
)
],
),
)
: UpgradeAlert(
child: Center(child: Text('Checking...')),
));
}
}
After few days of searching it doesn't work on emulator. I install on my android phone and it worked. But I can see only availableVersionCode as 30. But my actual version is version: 2.3.4+34 on Google Play store. I try to make Perform immediate update and I can see the update page which has x on right hand corner which is close button. I press there to close it before update. And second time I try to run it I am keep getting MissingPluginExeption.
My question is how to force user to update and not to cancel it? Thanks
In Google Play Store my App Release: 2.3.4 and version code: 34
I open my project and change the version to: 2.3.3+33
When I run the app I got error that shown below. Any idea why I am getting this error
error info: InAppUpdateState{updateAvailable: false, immediateUpdateAllowed: false, flexibleUpdateAllowed: false, availableVersionCode: null}
Please read https://developer.android.com/guide/playcore/in-app-updates#troubleshoot carefully. I'm pretty sure it won't work with your debug certificates in debug mode.
What do you mean in debug mode? I install app from Android Studio to my phone.
ok, it means:
Make sure that the app that you are testing in-app updates with has the same application ID and is signed with the same signing key as the one available from Google Play.
So I need to update my app with this plugin. Than later (1 day later in example) I have to update my again with new version code on Google play than I can test. ???
Problem is that If I use version as 1.2.0+5 it goes and finds the new update. but if I change version code lower than but closer to currently that available in App Store it doesn't update.
I reduce my app versions to version: 1.2.4+10 and Now I got this:
info: InAppUpdateState{updateAvailable: true, immediateUpdateAllowed: false, flexibleUpdateAllowed: false, availableVersionCode: 30}
also it shows updateAvailable: true but both immediateUpdateAllowed and flexibleUpdateAllowed shows as a false what do you mean availableVersionCode: 30? My app version code: 34 in Google Play. Next update should I have to incease the version code to 30 to 40 and than 50, 60 so on?
I reduce my app versions to version: 1.2.4+10 and Now I got this:
info: InAppUpdateState{updateAvailable: true, immediateUpdateAllowed: false, flexibleUpdateAllowed: false, availableVersionCode: 30}
also it shows updateAvailable: true but both immediateUpdateAllowed and flexibleUpdateAllowed shows as a false what do you mean availableVersionCode: 30? My app version code: 34 in Google Play. Next update should I have to incease the version code to 30 to 40 and than 50, 60 so on?
Same issue with me..... It's issue on google side not this plugin. If you clear play store cache and open play store and go to my apps and then open app it will show update.
I reduce my app versions to version: 1.2.4+10 and Now I got this:
info: InAppUpdateState{updateAvailable: true, immediateUpdateAllowed: false, flexibleUpdateAllowed: false, availableVersionCode: 30}
also it shows updateAvailable: true but both immediateUpdateAllowed and flexibleUpdateAllowed shows as a false what do you mean availableVersionCode: 30? My app version code: 34 in Google Play. Next update should I have to incease the version code to 30 to 40 and than 50, 60 so on?
I am also seeing this. Though this happens only when I open app after clearing cache on play store. When I close the app and open again, it shows true for both update type.
To add to @mdazharuddin1011999, forcing an update check in the play store worked for me, even if I was just on internal testing. For that I followed the steps listed in the explanation of how to do alpha track in-app updates (even though I was on internal): https://stackoverflow.com/questions/56087064/how-can-i-test-in-app-updates-in-android
Yeah it works. If you are seeing "update available" for your app in My apps and games section of Play store, this package works like charm, doesn't matter if you are in internal or beta or production!
And that is exactly my problem. I have to go to PlayStore, I have to find "My apps and games" and I have to check upgrades BEFORE this plugin will find the upgraded version, which is actually already exists on the PlayStore. Need that feature, which make this concept meaningless and check for upgrade directly in the Play Store and not in the device's PlayStore app's chache/memory/stored-datas, ...
@fehernyul Nonsense. The play store update list is cached and auto updates itself - something that nobody has control of. So you'll just have to wait until the update information arrives to this plugin as well.
Did you find a solution to force the app update? I mean users could not use the app unless they update to the latest version.
@zjamshidi I store a "latest version" online somewhere (actually I use Firebase Remote Config but you could store it on your own server). On startup it fetches the version and if it's breaking with respect to the app's current version (Semver semantics), then the app routes to a captive screen.
If you're worried about your app not being able to start up without a connection because it would hang on fetching the version, just fetch the version when you do have a connection during the lifetime of the app.
I do the the same for the "Latest Version". I was wondering if the library provides any solution for forcing users. I ended up calling "performUpdate" method in a loop :/
Aren't "immediate" updates forced anyway? For flexible ones you'd have to loop though yeah if the user does say no, but that probably defeats the point. https://developer.android.com/guide/playcore/in-app-updates