Commit f12dda9c by Nguyễn Thị Thúy

update version

parent 0c3d0ca1
...@@ -132,8 +132,8 @@ android { ...@@ -132,8 +132,8 @@ android {
applicationId "com.dcv.invest" applicationId "com.dcv.invest"
minSdkVersion rootProject.ext.minSdkVersion minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 3 versionCode 2
versionName "1.3" versionName "1.2"
vectorDrawables.useSupportLibrary = true vectorDrawables.useSupportLibrary = true
} }
splits { splits {
...@@ -151,6 +151,12 @@ android { ...@@ -151,6 +151,12 @@ android {
keyAlias 'androiddebugkey' keyAlias 'androiddebugkey'
keyPassword 'android' keyPassword 'android'
} }
release {
storeFile file('KeyStore')
storePassword 'dcvinvest'
keyAlias 'dcvinvest'
keyPassword 'dcvinvest'
}
} }
buildTypes { buildTypes {
debug { debug {
...@@ -159,8 +165,9 @@ android { ...@@ -159,8 +165,9 @@ android {
release { release {
// Caution! In production, you need to generate your own keystore file. // Caution! In production, you need to generate your own keystore file.
// see https://facebook.github.io/react-native/docs/signed-apk-android. // see https://facebook.github.io/react-native/docs/signed-apk-android.
signingConfig signingConfigs.debug signingConfig signingConfigs.release
minifyEnabled enableProguardInReleaseBuilds minifyEnabled enableProguardInReleaseBuilds
debuggable true
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
} }
} }
...@@ -222,7 +229,8 @@ implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0-alpha02' ...@@ -222,7 +229,8 @@ implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0-alpha02'
implementation jscFlavor implementation jscFlavor
} }
implementation 'com.google.firebase:firebase-analytics:17.2.2' implementation 'com.google.firebase:firebase-analytics:17.2.2'
implementation 'com.google.android.play:core:1.7.3'
implementation 'com.google.android.material:material:1.0.0'
} }
// Run this once to be able to run the application with BUCK // Run this once to be able to run the application with BUCK
......
package com.dcv.invest;
import android.app.Activity;
import android.content.Intent;
import android.content.IntentSender;
import android.graphics.Color;
import androidx.annotation.NonNull;
import com.facebook.react.bridge.ActivityEventListener;
import com.facebook.react.bridge.BaseActivityEventListener;
import com.facebook.react.bridge.LifecycleEventListener;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.google.android.material.snackbar.Snackbar;
import com.google.android.play.core.appupdate.AppUpdateInfo;
import com.google.android.play.core.appupdate.AppUpdateManager;
import com.google.android.play.core.appupdate.AppUpdateManagerFactory;
import com.google.android.play.core.install.InstallState;
import com.google.android.play.core.install.InstallStateUpdatedListener;
import com.google.android.play.core.install.model.AppUpdateType;
import com.google.android.play.core.install.model.InstallStatus;
import com.google.android.play.core.install.model.UpdateAvailability;
import com.google.android.play.core.tasks.Task;
import java.util.Objects;
import static android.app.Activity.RESULT_OK;
public class InAppUpdateModule extends ReactContextBaseJavaModule implements InstallStateUpdatedListener, LifecycleEventListener {
private AppUpdateManager appUpdateManager;
private static ReactApplicationContext reactContext;
private static final int STALE_DAYS = 5;
private static final int MY_REQUEST_CODE = 0;
private final ActivityEventListener mActivityEventListener = new BaseActivityEventListener() {
@Override
public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent intent) {
if (requestCode == MY_REQUEST_CODE) {
if (resultCode != RESULT_OK) {
System.out.println("Update flow failed! Result code: " + resultCode);
// If the update is cancelled or fails,
// you can request to start the update again.
}
}
}
};
InAppUpdateModule(ReactApplicationContext context) {
super(context);
reactContext = context;
reactContext.addActivityEventListener(mActivityEventListener);
reactContext.addLifecycleEventListener(this);
}
@NonNull
@Override
public String getName() {
return "InAppUpdate";
}
@ReactMethod
public void checkUpdate() throws Exception {
appUpdateManager = AppUpdateManagerFactory.create(reactContext);
appUpdateManager.registerListener(this);
Task<AppUpdateInfo> appUpdateInfoTask = appUpdateManager.getAppUpdateInfo();
if (appUpdateInfoTask.getException() != null) throw appUpdateInfoTask.getException();
appUpdateInfoTask.addOnSuccessListener(appUpdateInfo -> {
if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
&& appUpdateInfo.clientVersionStalenessDays() != null
&& appUpdateInfo.clientVersionStalenessDays() > STALE_DAYS
&& appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE)) {
try {
appUpdateManager.startUpdateFlowForResult(
appUpdateInfo,
AppUpdateType.IMMEDIATE,
reactContext.getCurrentActivity(),
MY_REQUEST_CODE);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
} else {
if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
&& appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE)) {
try {
appUpdateManager.startUpdateFlowForResult(
appUpdateInfo,
AppUpdateType.FLEXIBLE,
reactContext.getCurrentActivity(),
MY_REQUEST_CODE);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
}
}
});
}
@Override
public void onStateUpdate(InstallState state) {
if (state.installStatus() == InstallStatus.DOWNLOADED) {
popupSnackbarForCompleteUpdate();
}
}
private void popupSnackbarForCompleteUpdate() {
Snackbar snackbar =
Snackbar.make(Objects.requireNonNull(reactContext.getCurrentActivity()).findViewById(android.R.id.content).getRootView(),
"An update has just been downloaded.",
Snackbar.LENGTH_INDEFINITE);
snackbar.setAction("RESTART", view -> appUpdateManager.completeUpdate());
snackbar.setActionTextColor(Color.GREEN);
snackbar.show();
}
@Override
public void onHostResume() {
if (appUpdateManager != null) {
appUpdateManager
.getAppUpdateInfo()
.addOnSuccessListener(
appUpdateInfo -> {
if (appUpdateInfo.installStatus() == InstallStatus.DOWNLOADED) {
popupSnackbarForCompleteUpdate();
}
if (appUpdateInfo.updateAvailability()
== UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS) {
try {
appUpdateManager.startUpdateFlowForResult(
appUpdateInfo,
AppUpdateType.IMMEDIATE,
reactContext.getCurrentActivity(),
MY_REQUEST_CODE);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
}
});
}
}
@Override
public void onHostPause() {
}
@Override
public void onHostDestroy() {
if (appUpdateManager != null) {
appUpdateManager.unregisterListener(this);
}
}
}
package com.dcv.invest;
import androidx.annotation.NonNull;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class InAppUpdatePackage implements ReactPackage {
@NonNull
@Override
public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new InAppUpdateModule(reactContext));
return modules;
}
@NonNull
@Override
public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
...@@ -29,6 +29,7 @@ public class MainApplication extends Application implements ReactApplication { ...@@ -29,6 +29,7 @@ public class MainApplication extends Application implements ReactApplication {
// Packages that cannot be autolinked yet can be added manually here, for example: // Packages that cannot be autolinked yet can be added manually here, for example:
// packages.add(new MyReactNativePackage()); // packages.add(new MyReactNativePackage());
// packages.add(new RNBootSplashPackage()); // packages.add(new RNBootSplashPackage());
packages.add(new InAppUpdatePackage());
return packages; return packages;
} }
......
...@@ -15,7 +15,6 @@ enableScreens(); ...@@ -15,7 +15,6 @@ enableScreens();
const RootView = (props) => { const RootView = (props) => {
useEffect(() => { useEffect(() => {
checkVersion();
}, []); }, []);
const checkVersion = (props) => { const checkVersion = (props) => {
......
...@@ -14,6 +14,7 @@ import {getFontXD, getHeight, getWidth, HEIGHTXD, WIDTHXD} from '../../Config/Fu ...@@ -14,6 +14,7 @@ import {getFontXD, getHeight, getWidth, HEIGHTXD, WIDTHXD} from '../../Config/Fu
import I18n from '../../helper/i18/i18n'; import I18n from '../../helper/i18/i18n';
import DeviceInfo from 'react-native-device-info'; import DeviceInfo from 'react-native-device-info';
import {getNewestVersionInfo} from '../../apis/Functions/users'; import {getNewestVersionInfo} from '../../apis/Functions/users';
import InAppUpdate from '../../helper/InAppUpdate';
const VersionChecker = (props) => { const VersionChecker = (props) => {
const [visible, setVisible] = useState(false); const [visible, setVisible] = useState(false);
...@@ -29,11 +30,11 @@ const VersionChecker = (props) => { ...@@ -29,11 +30,11 @@ const VersionChecker = (props) => {
platform: Platform.OS, platform: Platform.OS,
}); });
if ((res.data.code = 200 && res.data.data)) { if ((res.data.code = 200 && res.data.data)) {
console.log(res) console.log(res);
if(res.data.data[0].version_name !== verCurrent || res.data.data[0].build.toString() !== DeviceInfo.getBuildNumber) { if (res.data.data[0].version_name !== verCurrent || res.data.data[0].build.toString() !== DeviceInfo.getBuildNumber) {
setVersion(res.data.data[0].version_name) setVersion(res.data.data[0].version_name);
setVisible(true) setVisible(true);
setIsForceUpdate(res.data.data[0].is_require_update == 0 ? false : true) setIsForceUpdate(res.data.data[0].is_require_update == 0 ? false : true);
} }
} }
}; };
...@@ -54,7 +55,12 @@ const VersionChecker = (props) => { ...@@ -54,7 +55,12 @@ const VersionChecker = (props) => {
if (Platform.OS === 'ios') { if (Platform.OS === 'ios') {
Linking.openURL('itms-apps://itunes.apple.com/us/app/dcv-invest/id1556621903?l=id'); Linking.openURL('itms-apps://itunes.apple.com/us/app/dcv-invest/id1556621903?l=id');
} else { } else {
Linking.openURL('https://play.google.com/store/apps/details?id=com.dcv.invest'); try {
InAppUpdate.checkUpdate()
} catch(e) {
console.log(e)
}
// Linking.openURL('https://play.google.com/store/apps/details?id=com.dcv.invest');
} }
} catch (error) { } catch (error) {
} }
...@@ -97,6 +103,7 @@ const VersionChecker = (props) => { ...@@ -97,6 +103,7 @@ const VersionChecker = (props) => {
<View pointerEvents="box-none" style={styles.containerStyle}> <View pointerEvents="box-none" style={styles.containerStyle}>
<View style={styles.imageUpgradeContainer} zIndex={100}> <View style={styles.imageUpgradeContainer} zIndex={100}>
<Image <Image
source={R.images.iconUpgrade}
style={[styles.imageUpgradeStyle, {tintColor: R.colors.main}]}/> style={[styles.imageUpgradeStyle, {tintColor: R.colors.main}]}/>
</View> </View>
...@@ -112,7 +119,7 @@ const VersionChecker = (props) => { ...@@ -112,7 +119,7 @@ const VersionChecker = (props) => {
{_renderDivider()} {_renderDivider()}
{isForceUpdate ? {isForceUpdate ?
<TouchableOpacity onPress={()=>onUpdatePressed()} style={styles.notNowContainerStyle}> <TouchableOpacity onPress={() => onUpdatePressed()} style={styles.notNowContainerStyle}>
<Text <Text
style={[styles.textNotNowStyle, {color: R.colors.main}]}>{I18n.t('Update')}</Text> style={[styles.textNotNowStyle, {color: R.colors.main}]}>{I18n.t('Update')}</Text>
</TouchableOpacity> </TouchableOpacity>
...@@ -121,13 +128,13 @@ const VersionChecker = (props) => { ...@@ -121,13 +128,13 @@ const VersionChecker = (props) => {
flexDirection: 'row', flexDirection: 'row',
marginHorizontal: WIDTHXD(100), marginHorizontal: WIDTHXD(100),
}]}> }]}>
<TouchableOpacity onPress={()=>cancelUpdate()} <TouchableOpacity onPress={() => cancelUpdate()}
style={[styles.btnButton, {paddingRight: WIDTHXD(90)}]}> style={[styles.btnButton, {paddingRight: WIDTHXD(90)}]}>
<Text <Text
style={[styles.textNotNowStyle, {color: R.colors.color777}]}>{I18n.t('Cancel')}</Text> style={[styles.textNotNowStyle, {color: R.colors.color777}]}>{I18n.t('Cancel')}</Text>
</TouchableOpacity> </TouchableOpacity>
<View style={styles.dividerStyleVertical}></View> <View style={styles.dividerStyleVertical}></View>
<TouchableOpacity onPress={()=>onUpdatePressed()} <TouchableOpacity onPress={() => onUpdatePressed()}
style={[styles.btnButton, {paddingLeft: WIDTHXD(90)}]}> style={[styles.btnButton, {paddingLeft: WIDTHXD(90)}]}>
<Text <Text
style={[styles.textNotNowStyle, {color: R.colors.main}]}>{I18n.t('Update')}</Text> style={[styles.textNotNowStyle, {color: R.colors.main}]}>{I18n.t('Update')}</Text>
......
import {NativeModules} from 'react-native'
module.exports = NativeModules.InAppUpdate
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment