Skip to content
This repository was archived by the owner on Sep 17, 2025. It is now read-only.

Commit a77e66c

Browse files
committed
Customizable update dialog
1 parent e79003a commit a77e66c

7 files changed

Lines changed: 407 additions & 61 deletions

File tree

.idea/misc.xml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/build.gradle

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,23 @@ android {
3030
}
3131
}
3232

33+
ext {
34+
ankoVersion = "0.9"
35+
}
36+
3337
dependencies {
3438
compile fileTree(dir: 'libs', include: ['*.jar'])
3539
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
3640
exclude group: 'com.android.support', module: 'support-annotations'
3741
})
3842
compile 'com.android.support:appcompat-v7:25.1.0'
3943
testCompile 'junit:junit:4.12'
44+
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
45+
// Anko
46+
compile "org.jetbrains.anko:anko-sdk15:$ankoVersion" // So here it's 15 too
47+
48+
// Anko libs matching support libs
49+
compile "org.jetbrains.anko:anko-appcompat-v7:${ankoVersion}"
50+
51+
compile project(":library")
4052
}

app/src/main/AndroidManifest.xml

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
1-
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
2-
package="com.ackee.versionupdatehandler">
1+
<manifest package="com.ackee.versionupdatehandler"
2+
xmlns:android="http://schemas.android.com/apk/res/android">
33

44
<application
5-
android:allowBackup="true"
5+
android:allowBackup="false"
66
android:icon="@mipmap/ic_launcher"
77
android:label="@string/app_name"
88
android:supportsRtl="true"
99
android:theme="@style/AppTheme">
10-
10+
<activity android:name=".setup.MainActivity">
11+
<intent-filter>
12+
<action android:name="android.intent.action.MAIN"/>
13+
<category android:name="android.intent.category.LAUNCHER"/>
14+
</intent-filter>
15+
</activity>
1116
</application>
1217

1318
</manifest>
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package com.ackee.versionupdatehandler.setup
2+
3+
import android.app.Activity
4+
import android.os.Bundle
5+
import android.support.v7.app.AppCompatActivity
6+
import com.ackee.versioupdatehandler.VersionStatusResolver
7+
import com.ackee.versioupdatehandler.model.BasicVersionsConfiguration
8+
import org.jetbrains.anko.*
9+
import rx.Single
10+
11+
/**
12+
* Activity with samples
13+
14+
* @author David Bilik [[email protected]]
15+
* @since 07/02/2017
16+
**/
17+
class MainActivity : AppCompatActivity() {
18+
companion object {
19+
val TAG: String = MainActivity::class.java.name
20+
}
21+
22+
23+
override fun onCreate(savedInstanceState: Bundle?) {
24+
super.onCreate(savedInstanceState)
25+
scrollView {
26+
verticalLayout {
27+
button {
28+
text = "Not mandatory update"
29+
onClick {
30+
checkWithVersion(13)
31+
}
32+
}.lparams(width = matchParent) {
33+
bottomMargin = dip(16)
34+
}
35+
36+
button {
37+
text = "Mandatory update"
38+
onClick {
39+
checkWithVersion(8)
40+
}
41+
}.lparams(width = matchParent) {
42+
bottomMargin = dip(16)
43+
}
44+
45+
button {
46+
text = "Customized dialog"
47+
}.lparams(width = matchParent) {
48+
bottomMargin = dip(16)
49+
}
50+
51+
button {
52+
text = "Custom UI"
53+
}.lparams(width = matchParent) {
54+
bottomMargin = dip(16)
55+
}
56+
}
57+
}
58+
}
59+
60+
private fun checkWithVersion(version: Int) {
61+
VersionStatusResolver({
62+
Single.just(BasicVersionsConfiguration(10, 15))
63+
}).checkVersionStatusAndOpenDefault(version, supportFragmentManager)
64+
}
65+
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
package com.ackee.versioupdatehandler;
2+
3+
import android.app.Dialog;
4+
import android.content.DialogInterface;
5+
import android.content.Intent;
6+
import android.net.Uri;
7+
import android.os.Bundle;
8+
import android.support.annotation.NonNull;
9+
import android.support.v4.app.DialogFragment;
10+
import android.support.v7.app.AlertDialog;
11+
12+
import com.ackee.versioupdatehandler.model.DialogSettings;
13+
14+
/**
15+
* Dialog indicating that user should update application.
16+
* <p>
17+
* Texts and package name are customizable via {@link DialogSettings} class
18+
*
19+
* @author David Bilik [[email protected]]
20+
* @since 07/02/2017
21+
**/
22+
public class UpdateDialog extends DialogFragment {
23+
24+
private static final String FORCE_UPDATE_KEY = "force_update";
25+
private static final String DIALOG_SETTINGS_KEY = "dialog_settings";
26+
27+
public static UpdateDialog newInstance(boolean forceUpdate, DialogSettings dialogSettings) {
28+
Bundle args = new Bundle();
29+
args.putBoolean(FORCE_UPDATE_KEY, forceUpdate);
30+
args.putParcelable(DIALOG_SETTINGS_KEY, dialogSettings);
31+
UpdateDialog updateDialog = new UpdateDialog();
32+
updateDialog.setArguments(args);
33+
return updateDialog;
34+
}
35+
36+
@NonNull
37+
@Override
38+
public Dialog onCreateDialog(Bundle savedInstanceState) {
39+
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
40+
final DialogSettings settings = getArguments().getParcelable(DIALOG_SETTINGS_KEY);
41+
if (settings == null) {
42+
throw new IllegalArgumentException("Dialog settings cannot be null");
43+
}
44+
String title = "Update app";
45+
if (settings.getTitle() != null) {
46+
title = settings.getTitle();
47+
}
48+
if (settings.getTitleRes() > 0) {
49+
title = getString(settings.getTitleRes());
50+
}
51+
builder.setTitle(title);
52+
String message = "Your application is outdated. Please update to the newest version";
53+
if (settings.getMessage() != null) {
54+
message = settings.getMessage();
55+
}
56+
if (settings.getMessageRes() > 0) {
57+
message = getString(settings.getMessageRes());
58+
}
59+
builder.setMessage(message);
60+
final boolean isForceUpdate = getArguments().getBoolean(FORCE_UPDATE_KEY, false);
61+
62+
String posButton = "Update";
63+
if (settings.getPositiveButton() != null) {
64+
posButton = settings.getPositiveButton();
65+
}
66+
if (settings.getPositiveButtonRes() > 0) {
67+
posButton = getString(settings.getPositiveButtonRes());
68+
}
69+
70+
builder.setPositiveButton(posButton, new DialogInterface.OnClickListener() {
71+
@Override
72+
public void onClick(DialogInterface dialog, int which) {
73+
if (isForceUpdate) {
74+
getActivity().finish();
75+
}
76+
final String appPackageName = settings.getPackageName() == null ? getActivity().getPackageName() : settings.getPackageName(); // getPackageName() from Context or Activity object
77+
openPlayStore(appPackageName);
78+
}
79+
});
80+
String negButton = "Cancel";
81+
if (settings.getNegativeButton() != null) {
82+
negButton = settings.getNegativeButton();
83+
}
84+
if (settings.getNegativeButtonRes() > 0) {
85+
negButton = getString(settings.getNegativeButtonRes());
86+
}
87+
builder.setNegativeButton(negButton, new DialogInterface.OnClickListener() {
88+
@Override
89+
public void onClick(DialogInterface dialog, int which) {
90+
if (isForceUpdate) {
91+
getActivity().moveTaskToBack(true);
92+
}
93+
}
94+
});
95+
return builder.create();
96+
}
97+
98+
/**
99+
* Open Play Store on application detail
100+
*
101+
* @param appPackageName package name of application
102+
*/
103+
private void openPlayStore(String appPackageName) {
104+
try {
105+
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + appPackageName)));
106+
} catch (android.content.ActivityNotFoundException anfe) {
107+
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + appPackageName)));
108+
}
109+
}
110+
}

library/src/main/java/com/ackee/versioupdatehandler/VersionStatusResolver.java

Lines changed: 20 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,9 @@
11
package com.ackee.versioupdatehandler;
22

3-
import android.app.Dialog;
4-
import android.content.DialogInterface;
5-
import android.content.Intent;
6-
import android.net.Uri;
7-
import android.os.Bundle;
8-
import android.support.annotation.NonNull;
9-
import android.support.v4.app.DialogFragment;
103
import android.support.v4.app.FragmentManager;
11-
import android.support.v7.app.AlertDialog;
124
import android.util.Log;
135

6+
import com.ackee.versioupdatehandler.model.DialogSettings;
147
import com.ackee.versioupdatehandler.model.VersionStatus;
158
import com.ackee.versioupdatehandler.model.VersionsConfiguration;
169

@@ -59,15 +52,31 @@ private VersionStatus resolveStatus(int version, VersionsConfiguration configura
5952
return status;
6053
}
6154

55+
/**
56+
* Check for version and show dialog with default settings
57+
*
58+
* @param version current version
59+
* @param fragmentManager fragment manager used for showing dialog fragment
60+
*/
6261
public void checkVersionStatusAndOpenDefault(final int version, final FragmentManager fragmentManager) {
62+
checkVersionStatusAndOpenDefault(version, fragmentManager, new DialogSettings.Builder().build());
63+
}
64+
65+
/**
66+
* Check for version and show dialog with customized visual settings via {@link DialogSettings}
67+
*
68+
* @param version current version
69+
* @param fragmentManager fragment manager used for showing dialog fragment
70+
*/
71+
public void checkVersionStatusAndOpenDefault(final int version, final FragmentManager fragmentManager, final DialogSettings settings) {
6372
checkVersionStatus(version)
6473
.subscribeOn(Schedulers.newThread())
6574
.observeOn(AndroidSchedulers.mainThread())
6675
.subscribe(new Action1<VersionStatus>() {
6776
@Override
6877
public void call(VersionStatus versionStatus) {
6978
if (versionStatus != VersionStatus.UP_TO_DATE) {
70-
showDialog(versionStatus == VersionStatus.UPDATE_REQUIRED, fragmentManager);
79+
showDialog(versionStatus == VersionStatus.UPDATE_REQUIRED, fragmentManager, settings);
7180
}
7281
}
7382
}, new Action1<Throwable>() {
@@ -83,53 +92,8 @@ public void call(Throwable throwable) {
8392
*
8493
* @param forceUpdate indicator if update is mandatory
8594
*/
86-
private void showDialog(boolean forceUpdate, FragmentManager fragmentManager) {
87-
UpdateDialog.newInstance(forceUpdate).show(fragmentManager, UpdateDialog.class.getName());
88-
}
89-
90-
public static class UpdateDialog extends DialogFragment {
91-
92-
private static final String FORCE_UPDATE_KEY = "force_update";
93-
94-
public static UpdateDialog newInstance(boolean forceUpdate) {
95-
Bundle args = new Bundle();
96-
args.putBoolean(FORCE_UPDATE_KEY, forceUpdate);
97-
UpdateDialog updateDialog = new UpdateDialog();
98-
updateDialog.setArguments(args);
99-
return updateDialog;
100-
}
101-
102-
@NonNull
103-
@Override
104-
public Dialog onCreateDialog(Bundle savedInstanceState) {
105-
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
106-
builder.setTitle("Update app");
107-
builder.setMessage("Your application is outdated. Please update to the newest version");
108-
final boolean isForceUpdate = getArguments().getBoolean(FORCE_UPDATE_KEY, false);
109-
builder.setPositiveButton("Update", new DialogInterface.OnClickListener() {
110-
@Override
111-
public void onClick(DialogInterface dialog, int which) {
112-
if (isForceUpdate) {
113-
getActivity().finish();
114-
}
115-
final String appPackageName = getActivity().getPackageName(); // getPackageName() from Context or Activity object
116-
try {
117-
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + appPackageName)));
118-
} catch (android.content.ActivityNotFoundException anfe) {
119-
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + appPackageName)));
120-
}
121-
}
122-
});
123-
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
124-
@Override
125-
public void onClick(DialogInterface dialog, int which) {
126-
if (isForceUpdate) {
127-
getActivity().moveTaskToBack(true);
128-
}
129-
}
130-
});
131-
return builder.create();
132-
}
95+
private void showDialog(boolean forceUpdate, FragmentManager fragmentManager, DialogSettings dialogSettings) {
96+
UpdateDialog.newInstance(forceUpdate, dialogSettings).show(fragmentManager, UpdateDialog.class.getName());
13397
}
13498

13599
}

0 commit comments

Comments
 (0)