I use InAppUpdater library for Android In App Updates.
For testing I created a simple application with versionCode 3(before this I posted versionCode 2 in the internal test track, but I did not see updates in my application with versionCode 1) and uploaded it in the Google play in a closed track(alpha version). On the Android device I installed versionCode 2.
Code:
public class UpdateActivity extends AppCompatActivity {
private UpdateManager mUpdateManager;
static final int REQUEST_CODE = 781;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_update);
TextView txtCurrentVersion = findViewById(R.id.currentVersion);
TextView txtAvailableVersion = findViewById(R.id.availableVersion);
txtCurrentVersion.setText(String.valueOf(BuildConfig.VERSION_CODE));
// Initialize the Update Manager with the Activity and the Update Mode
mUpdateManager = UpdateManager.Builder(this);
// Callback from Available version code
mUpdateManager.getAvailableVersionCode(code -> txtAvailableVersion.setText(String.valueOf(code)));
}
#Override
protected void onResume() {
super.onResume();
// Continue updates when resumed
mUpdateManager.continueUpdate();
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE) {
if (resultCode == RESULT_OK) {
Log.d("MyTag", "Result ok! Result code: " + resultCode);
}
else if(resultCode == RESULT_CANCELED){
Log.d("MyTag", "Result canceled! Result code: " + resultCode);
}
else if(resultCode == ActivityResult.RESULT_IN_APP_UPDATE_FAILED){
Log.d("MyTag", "In app update failed! Result code: " + resultCode);
}
}
}
public void tryToUpdate(View view){
mUpdateManager.mode(UpdateManagerConstant.FLEXIBLE).start();
}
}
After starting, I see that current version = 2, available version = 3, so the app sees the update. Next I click the tryToUpdate button and see the update dialog, click "update", wait, see "An update has just been downloaded", click "restart", see installation activity, after that my application restarts and I see the old version - current version = 2, and this is the problem. Of course, I tried to manually close and open the app but I still see the old version. But if I delete the old version and manually install the new version from Google Play, then all works fine.
So, how can I solve this?
Related
Google Immediate app update, as far as I understand, shouldn't be cancelable, but the dialog as an X icon that cancels the update process.
Is there a way to remove the cancel option?
I'm using the latest play core version, 1.10.2
Thanks
At the beginning, I had the same understanding, but looking up in documentation, I wasn't able to find this information.
Both InApp update types are cancelable, and the only way to prevent the user to update before uses your app will be finish the app if onActivityResult() returns something diffrent than OK
The difference between Flexible and Immediate update is:
In Flexible update, if the user decide to update, it can uses the app during the download and when the download is finished, you need show some U.I to call the completeUpdate().
In Immediate update, if the user decide to update, it can't use uses the app, because a fullscreen progress dialog will be show. After the download is completed, the Android will install the new version even if your app is in background.
InAppUpdate Doc
You can handle the cancel button and back button click listener.
If the user clicks cancel or back button then
onActivityResult
callback is executed and you can reopen the app update screen if
resultcode == RESULT_CANCELED
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == APP_UPDATE_REQ_CODE) {
if (resultCode == RESULT_CANCELED) {
// App update is canceled by the user so re-open the in-app update screen.
// This block of code is executed if user clicks cancel button from the in-app update screen or press the hardware back button.
checkForAppUpdate();
} else if (resultCode == RESULT_OK) {
// App successfully updated to the latest version.
finish();
} else {
// Update fails then re-open the in-app update screen.
checkForAppUpdate();
}
}
}
private void checkForAppUpdate(){
if (this instanceof SplashActivity){
return;
}
if (appUpdateManager == null){
appUpdateManager = AppUpdateManagerFactory.create(this);
}
Task<AppUpdateInfo> appUpdateInfoTask = appUpdateManager.getAppUpdateInfo();
appUpdateInfoTask.addOnSuccessListener(appUpdateInfo -> {
if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
&& appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE)) {
startUpdateFlow(appUpdateInfo);
}
});
Official android document:
public class MainActivity extends Activity implements PermissionRequest.Response{
public static int CAMERA_PREVIEW_RESULT = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new CameraPreviewIntent(this)
.setExportDir(CameraPreviewIntent.Directory.DCIM, "ImgLyExample")
.setExportPrefix("example_")
.setEditorIntent(
new PhotoEditorIntent(this)
.setExportDir(PhotoEditorIntent.Directory.DCIM, "ImgLyExample")
.setExportPrefix("result_")
.destroySourceAfterSave(true)
)
.startActivityForResult(CAMERA_PREVIEW_RESULT);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, android.content.Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK && requestCode == CAMERA_PREVIEW_RESULT) {
String path = data.getStringExtra(CameraPreviewActivity.RESULT_IMAGE_PATH);
Toast.makeText(this, "Image Save on: " + path, Toast.LENGTH_LONG).show();
}
}
Hello
I want to edit the above code so that in the result the activity displays the result image along with the file path, can someone please help with this as I am very new to android development.
The github link to this sdk is-
https://github.com/imgly/imgly-sdk-android-demo
v1 of the SDK is deprecated, please use v2 instead. Please see the documentation how to integrate the newest version.
https://github.com/imgly/imgly-sdk-android-demo
Else I'am not sure what you actually want.
Can you please explain, how your app need to perform?
Sorry for my poor English and the fact I am a newbie on Android development.
I'm developping an Android app which should send data to the datastore of Dropbox. My problem is, when my code is getting this line:
mAccountManager.startLink(DropboxHelper.this,REQUEST_LINK_TO_DBX);
Then my logcat send me the message below:
10-19 10:40:32.411: W/com.dropbox.client2.android.AuthActivity(28381): There are multiple
apps registered for the AuthActivity URI scheme (db-qeojdcjk0dkkswc). Another app may be
trying to impersonate this app, so authentication will be disabled.
The closer explanation I have found is this one:
Android + DropboxSync startLink
But the comments have not helped me.
Here my code :
public class DropboxHelper extends ActionBarActivity {
// *** Objects and APP_KEY + APP_SECRET are instantiate here ***
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dropbox_activity);
// Set up the account manager
mAccountManager = DbxAccountManager.getInstance(getApplicationContext(), APP_KEY, APP_SECRET);
mUnlinkButton = (Button) findViewById(R.id.unlink_button);
mUnlinkButton.setVisibility(View.GONE);
// Button to link to Dropbox
mLinkButton = (Button) findViewById(R.id.link_button);
mLinkButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if ( mAccountManager.getLinkedAccount() == null )
mAccountManager.startLink(DropboxHelper.this, REQUEST_LINK_TO_DBX);
else
{
Toast.makeText(DropboxHelper.this, "Connection déjà établie, vous pouvez vous déconnecter si vous le souhaitez", Toast.LENGTH_LONG).show();
mUnlinkButton.setVisibility(View.VISIBLE);
}
}
});
mUnlinkButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
mAccountManager.unlink();
Toast.makeText(DropboxHelper.this, "Déconnecté", Toast.LENGTH_LONG).show();
}
});
// Set up the datastore manager
if (mAccountManager.hasLinkedAccount()) {
try {
// Use Dropbox datastores
mDatastoreManager = DbxDatastoreManager.forAccount(mAccountManager.getLinkedAccount());
mLinkButton.setVisibility(View.GONE);
} catch (DbxException.Unauthorized e) {
System.out.println("Account was unlinked remotely");
}
}
if (mDatastoreManager == null) {
// Account isn't linked yet, use local datastores
mDatastoreManager = DbxDatastoreManager.localManager(mAccountManager);
// Show link button
mLinkButton.setVisibility(View.VISIBLE);
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_LINK_TO_DBX) {
if (resultCode == Activity.RESULT_OK) {
account = mAccountManager.getLinkedAccount();
try {
// Migrate any local datastores to the linked account
mDatastoreManager.migrateToAccount(account);
// Now use Dropbox datastores
mDatastoreManager = DbxDatastoreManager.forAccount(account);
// Hide link button
mLinkButton.setVisibility(View.GONE);
} catch (DbxException e) {
e.printStackTrace();
}
} else {
// Link failed or was cancelled by the user
}
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
}
I can't figure out How to solve this issue, I really thank you If you can help me.
Best regards.
This generally means you have more than one app installed using the same app key. Often, this can happen if you have, for example, a sample app from the SDK as well as the app you're developing installed on the same device (or virtual device) using your app key. The solution is just to uninstall one of the apps, or use a different app key in one of them.
I am making a activity whereby i ask the user to load image from various sources and showing the selected image on a imageview in a different activity.
I am able to show the image from the camera and gallery but from dropbox it is showing error.
For Camera and gallery i can even query the uri obtained from
intent.getData()
in the onactivityresult method and obtain the Filepath and accordingly even obtain the bitmap and resize it .
But the same is not working for Dropbox. Kindly update what code to use for Dropbox so that all options start working.
thanks
For Dropbox you will need to use their Android Chooser to choose files from the user's Dropbox account. You will need a Dropbox API key for this. Once you have grabbed the chooser library and your API key it should be fairly easy to implement;
private Button mChooserButton;
private DbxChooser mChooser;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mChooser = new DbxChooser(APP_KEY);
mChooserButton = (Button) findViewById(R.id.chooser_button);
mChooserButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
mChooser.forResultType(DbxChooser.ResultType.PREVIEW_LINK)
.launch(MainActivity.this, DBX_CHOOSER_REQUEST);
}
});
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == DBX_CHOOSER_REQUEST) {
if (resultCode == Activity.RESULT_OK) {
DbxChooser.Result result = new DbxChooser.Result(data);
Log.d("main", "Link to selected file: " + result.getLink());
// Handle the result
} else {
// Failed or was cancelled by the user.
}
} else if (requestCode == GALLERY) {
// If your request was from the user gallery
Log.d("main", "Link to selected file: " + data.getData());
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
First post, so please go easy.
I have an app with a handful of tabs, the first is opened on running the app.
One of the tabs is 'My Account' (a ListActivity) showing account options. I switch to this and if the user is not logged in, it, in turn, runs a UserLogon activity using the following:
Intent logonActivity = new Intent(getBaseContext(), UserLogon.class);
startActivityForResult(logonActivity, 0);
To catch the result, I use the following code:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == 0){
MainBlock ta = (MainBlock) this.getParent();
TabHost th = ta.getMyTabHost();
th.setCurrentTab(0);
finish();
}
if (requestCode == 100)
{
showAccountOptions();
}
}
In the UserLogon class, I have the usual fare; TextView's and Button's. The intention is that if the user cancels the login, it will revert to the initial tab, or if login is successful, it will show the Account Options. And this is indeed what does happen.
All good so far.
The problem I'm having is that if I cancel the login and return to the first tab, when I select the Accounts tab again, I'm not presented with the UserLogon activity. I was under the impression that finish() would close the UserLogon activity, and the Accounts activity but it would appear not.
So, my question is simply, how do I, in effect, restart the Accounts activity so that the user would be presented with the option to login once more.
We're good people and all willing to help ;-) I'll give it a shot. Still, I'm not quite sure I get that all right.
Basically you have an TabActivity which you setup and where you do something like that:
myTabHost.setOnTabChangedListener(new OnTabChangeListener(){
#Override
public void onTabChanged(String tabId) {
if (tabId.equals("account") && !loggedIn) {
Intent logonActivity = new Intent(getBaseContext(), UserLogon.class);
startActivityForResult(logonActivity, 0);
}
}});
You're basically saying that the first Activity start of UserLogon works, but the second one doesn't, right? Did you debugged to that point to check whether you reach the code which starts the activity again?
Update based on comment
Your UserLogon should always provide a result information, here's a blueprint:
public class UserLogon extends Activity {
public void onCreate(Bundle bundle) {
// ... do something ...
// if activity is canceled this will be the "last" result
setResult(RESULT_CANCELED);
}
public void checkLoginOrSomethingLikeThat() {
Intent result = new Intent();
// put your results in this intent
setResult(RESULT_OK, intent);
// close activity since we have the information we need
finish();
}
}
The parent activity which is waiting for the result should do it like that:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// it's good practice to use a constant for 0 like LOGIN_REQUEST
// otherwise you will ask yourself later "What the hell did 0 stand for?"
if(requestCode == 0){
if (resultCode == RESULT_OK) {
// get needed data from data intent and react on that
} else {
// no success, react on that
}
}
// ... I don't know what your resultCode 100 is but handle itwith the same pattern
}