【发布时间】:2020-09-15 09:26:21
【问题描述】:
目前我正在从 android 实现应用内更新功能。我正在使用立即更新方法,我面临的问题是当 UI 提示用户更新显示并且用户没有单击更新按钮而是单击十字按钮时。应用更新的 UI 刚刚关闭,用户可以继续使用该应用。
我想要的是,当用户单击十字按钮时,应用程序会立即关闭,直到用户更新应用程序,然后他们才能像往常一样使用该应用程序。我也使用java代码进行android开发。
public class LoginActivity extends AppCompatActivity {
private LoginViewModel loginViewModel;
public static final String MyPREFERENCES = "LoginPrefs" ;
public static final String Name = "nameKey";
public static final String User = "userKey";
public static final String con = "closed";
public static String error = "";
public static int userFlag = 0;
SharedPreferences sharedpreferences;
SharedPreferences.Editor editor;
public TextInputEditText usernameEditText;
public TextInputEditText passwordEditText;
private AppUpdateManager mAppUpdateManager;
private int RC_APP_UPDATE = 999;
private int inAppUpdateType;
private com.google.android.play.core.tasks.Task<AppUpdateInfo> appUpdateInfoTask;
private InstallStateUpdatedListener installStateUpdatedListener;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
loginViewModel = ViewModelProviders.of(this, new LoginViewModelFactory())
.get(LoginViewModel.class);
usernameEditText = findViewById(R.id.user);
passwordEditText = findViewById(R.id.pass);
final Button loginButton = findViewById(R.id.submitBTN);
final TextInputLayout userL = findViewById(R.id.userL);
final TextInputLayout passL = findViewById(R.id.passL);
final JellyToggleButton jtb = findViewById(R.id.jtb);
// Creates instance of the manager.
mAppUpdateManager = AppUpdateManagerFactory.create(this);
// Returns an intent object that you use to check for an update.
appUpdateInfoTask = mAppUpdateManager.getAppUpdateInfo();
//lambda operation used for below listener
//For flexible update
installStateUpdatedListener = installState -> {
if (installState.installStatus() == InstallStatus.DOWNLOADED) {
popupSnackbarForCompleteUpdate();
}
};
mAppUpdateManager.registerListener(installStateUpdatedListener);
inAppUpdateType = AppUpdateType.IMMEDIATE; //1
inAppUpdate();
if(userFlag==1){
jtb.setChecked(true);
}
userL.setHint("Enter username");
sharedpreferences = getSharedPreferences(MyPREFERENCES, MODE_PRIVATE);
loginViewModel.getLoginFormState().observe(this, new Observer<LoginFormState>() {
@Override
public void onChanged(@Nullable LoginFormState loginFormState) {
if (loginFormState == null) {
return;
}
loginButton.setEnabled(loginFormState.isDataValid());
if (loginFormState.getUsernameError() != null) {
usernameEditText.setError(getString(loginFormState.getUsernameError()));
loginButton.startAnimation(AnimationUtils.loadAnimation(LoginActivity.this,R.anim.shake));
}
if (loginFormState.getPasswordError() != null) {
passwordEditText.setError(getString(loginFormState.getPasswordError()));
loginButton.startAnimation(AnimationUtils.loadAnimation(LoginActivity.this,R.anim.shake));
}
}
});
loginViewModel.getLoginResult().observe(this, new Observer<LoginResult>() {
@Override
public void onChanged(@Nullable LoginResult loginResult) {
if (loginResult == null) {
return;
}
if (loginResult.getError() != null) {
showLoginFailed(loginResult.getError());
}
if (loginResult.getSuccess() != null) {
updateUiWithUser(loginResult.getSuccess());
Intent i = new Intent(LoginActivity.this, user_dashboard.class);
startActivity(i);
}
setResult(Activity.RESULT_OK);
//Complete and destroy login activity once successful
}
});
TextWatcher afterTextChangedListener = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// ignore
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// ignore
}
@Override
public void afterTextChanged(Editable s) {
loginViewModel.loginDataChanged(usernameEditText.getText().toString(),
passwordEditText.getText().toString());
}
};
usernameEditText.addTextChangedListener(afterTextChangedListener);
passwordEditText.addTextChangedListener(afterTextChangedListener);
passwordEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
loginViewModel.login(usernameEditText.getText().toString(),
passwordEditText.getText().toString());
}
return false;
}
});
loginButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(userFlag==0) {
loginViewModel.login(usernameEditText.getText().toString(),
passwordEditText.getText().toString());
getStaffData();
}
else if(userFlag==1){
loginWorker();
}
}
});
jtb.setOnStateChangeListener(new JellyToggleButton.OnStateChangeListener() {
@Override
public void onStateChange(float process, State state, JellyToggleButton jtb) {
if (state.equals(State.LEFT)) {
userL.setHint("Enter username");
error = "Username cannot be empty";
userFlag = 0;
}
if (state.equals(State.RIGHT)) {
userL.setHint("Enter badge ID");
error = "Badge ID cannot be empty";
userFlag = 1;
}
}
});
}
@Override
protected void onDestroy() {
mAppUpdateManager.unregisterListener(installStateUpdatedListener);
finishAndRemoveTask();
super.onDestroy();
}
@Override
protected void onResume() {
try {
mAppUpdateManager.getAppUpdateInfo().addOnSuccessListener(appUpdateInfo -> {
if (appUpdateInfo.updateAvailability() ==
UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS) {
// If an in-app update is already running, resume the update.
try {
mAppUpdateManager.startUpdateFlowForResult(
appUpdateInfo,
inAppUpdateType,
this,
RC_APP_UPDATE);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
}
});
mAppUpdateManager.getAppUpdateInfo().addOnSuccessListener(appUpdateInfo -> {
//For flexible update
if (appUpdateInfo.installStatus() == InstallStatus.DOWNLOADED) {
popupSnackbarForCompleteUpdate();
}
});
} catch (Exception e) {
e.printStackTrace();
}
super.onResume();
}
@Override //For flexible update
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_APP_UPDATE) {
//when user clicks update button
if (resultCode == RESULT_OK) {
Toast.makeText(LoginActivity.this, "App download starts...", Toast.LENGTH_LONG).show();
} else if (resultCode == RESULT_CANCELED) {
//if you want to request the update again just call checkUpdate()
Toast.makeText(LoginActivity.this, "App download canceled.", Toast.LENGTH_LONG).show();
} else if (resultCode == RESULT_IN_APP_UPDATE_FAILED) {
Toast.makeText(LoginActivity.this, "App download failed.", Toast.LENGTH_LONG).show();
}
}
}
private void updateUiWithUser(LoggedInUserView model) {
String welcome = getString(R.string.welcome);
// TODO : initiate successful logged in experience
Toast.makeText(getApplicationContext(), welcome, Toast.LENGTH_LONG).show();
}
private void showLoginFailed(@StringRes Integer errorString) {
Toast.makeText(getApplicationContext(), errorString, Toast.LENGTH_SHORT).show();
}
private void getStaffData() {
String username = usernameEditText.getText().toString();
APIInterface apiInterface3 = APIClient.getClient().create(APIInterface.class);
Call<loginList> call3 = apiInterface3.staffData(username);
call3.enqueue(new Callback<loginList>() {
@Override
public void onResponse(Call<loginList> call, Response<loginList> response) {
loginList list = response.body();
if (list!=null && list.getStatusCode()==1) { //response received.
if(list.getStaffList().size()>0){
Log.d("check-in", list.getStatusCode() + " " + list.getStaffList().get(0).getName());
Toast.makeText(LoginActivity.this,"Logged in",Toast.LENGTH_SHORT).show();
final String name = list.getStaffList().get(0).getName();
final String badge = list.getStaffList().get(0).getBadge();
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putString(Name,name);
editor.putString(User,badge);
editor.putInt(con,1);
editor.apply();
}
else if(list.getStaffList().size()==0){
}
}
}
@Override
public void onFailure(Call<loginList> call, Throwable t) {
Log.d("fail",t.toString());
}
});
}
private void loginWorker(){
String username = usernameEditText.getText().toString();
String password = passwordEditText.getText().toString();
APIInterface apiInterface3 = APIClient.getClient().create(APIInterface.class);
Call<loginList> call3 = apiInterface3.loginWorker(username,password);
call3.enqueue(new Callback<loginList>() {
@Override
public void onResponse(Call<loginList> call, Response<loginList> response) {
loginList list = response.body();
Log.d("response", response.body().toString());
if (list!=null && list.getStatusCode()==1) { //response received.
if(list.getLoginList().size()>0){
Log.d("check-in", list.getStatusCode() + " " + list.getLoginList().get(0).getName());
Toast.makeText(LoginActivity.this,"Logged in",Toast.LENGTH_SHORT).show();
List<login> item = response.body().getLoginList();
final String name = list.getLoginList().get(0).getName();
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putString(Name,name);
editor.putInt(con,1);
editor.apply();
}
String welcome = getString(R.string.welcome);
Toast.makeText(getApplicationContext(), welcome, Toast.LENGTH_SHORT).show();
Intent i = new Intent(LoginActivity.this, user_dashboard.class);
startActivity(i);
}
else
Toast.makeText(LoginActivity.this, "wrong ID or password",Toast.LENGTH_SHORT).show();
}
@Override
public void onFailure(Call<loginList> call, Throwable t) {
Log.d("fail",t.toString());
}
});
editor = sharedpreferences.edit();
editor.putString(User, username);
editor.commit();
}
@Override
public void onBackPressed() {
new MaterialAlertDialogBuilder(LoginActivity.this,R.style.MyDialogTheme)
.setTitle("Exit")
.setMessage("Confirm to exit?")
.setBackground(getDrawable(R.drawable.alert_dialog))
// Specifying a listener allows you to take an action before dismissing the dialog.
// The dialog is automatically dismissed when a dialog button is clicked.
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// Continue with delete
finishAffinity();
}
})
.setNegativeButton(android.R.string.no, null)
.show();
}
private void inAppUpdate() {
try {
// Checks that the platform will allow the specified type of update.
appUpdateInfoTask.addOnSuccessListener(new OnSuccessListener<AppUpdateInfo>() {
@Override
public void onSuccess(AppUpdateInfo appUpdateInfo) {
if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
// For a flexible update, use AppUpdateType.FLEXIBLE
&& appUpdateInfo.isUpdateTypeAllowed(inAppUpdateType)) {
// Request the update.
try {
mAppUpdateManager.startUpdateFlowForResult(
// Pass the intent that is returned by 'getAppUpdateInfo()'.
appUpdateInfo,
// Or 'AppUpdateType.FLEXIBLE' for flexible updates.
inAppUpdateType,
// The current activity making the update request.
LoginActivity.this,
// Include a request code to later monitor this update request.
RC_APP_UPDATE);
} catch (IntentSender.SendIntentException ignored) {
}
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
private void popupSnackbarForCompleteUpdate() {
try {
Snackbar snackbar =
Snackbar.make(
findViewById(R.id.coordinatorL),
"An update has just been downloaded.\nRestart to update",
Snackbar.LENGTH_INDEFINITE);
snackbar.setAction("INSTALL", view -> {
if (mAppUpdateManager != null){
mAppUpdateManager.completeUpdate();
}
});
snackbar.setActionTextColor(getResources().getColor(R.color.orange));
snackbar.show();
} catch (Resources.NotFoundException e) {
e.printStackTrace();
}
}
}
我从谷歌借来的图片,在左边的图片中可以看到右上角有一个十字按钮,用户可以点击关闭更新过程
【问题讨论】: