changelogSingle = rxMagneto.grabPlayStoreRecentChangelog(packageName);
316 | changelogSingle.observeOn(AndroidSchedulers.mainThread())
317 | .subscribe(s -> {
318 | if (progressDialog != null && progressDialog.isShowing()) {
319 | progressDialog.dismiss();
320 | }
321 | showResult(featureModelList.get(FeaturesConfig.FEATURE_RECENT_CHANGELOG)
322 | .getTitle(), s);
323 | }, throwable -> {
324 | if (progressDialog != null && progressDialog.isShowing()) {
325 | progressDialog.dismiss();
326 | }
327 | showResult(getResources().getString(R.string.label_error),
328 | throwable.getMessage());
329 | });
330 | }
331 |
332 | private void showResult(String title, String result) {
333 | new MaterialDialog.Builder(this)
334 | .title(title)
335 | .content(result)
336 | .positiveText(R.string.label_ok)
337 | .show();
338 | }
339 |
340 | public static MaterialDialog showLoading(Activity activity, String message) {
341 | return new MaterialDialog.Builder(activity)
342 | .content(message)
343 | .cancelable(false)
344 | .progress(true, 0)
345 | .show();
346 | }
347 | }
--------------------------------------------------------------------------------
/rxmagneto/src/main/java/com/aritraroy/rxmagneto/core/RxMagneto.java:
--------------------------------------------------------------------------------
1 | package com.aritraroy.rxmagneto.core;
2 |
3 | import static android.content.pm.PackageManager.NameNotFoundException;
4 | import static android.text.TextUtils.isEmpty;
5 |
6 | import static com.aritraroy.rxmagneto.core.RxMagnetoErrorCodeMap.ERROR_APP_RATING;
7 | import static com.aritraroy.rxmagneto.core.RxMagnetoErrorCodeMap.ERROR_APP_RATING_COUNT;
8 | import static com.aritraroy.rxmagneto.core.RxMagnetoErrorCodeMap.ERROR_CHANGELOG;
9 | import static com.aritraroy.rxmagneto.core.RxMagnetoErrorCodeMap.ERROR_CONTENT_RATING;
10 | import static com.aritraroy.rxmagneto.core.RxMagnetoErrorCodeMap.ERROR_DOWNLOADS;
11 | import static com.aritraroy.rxmagneto.core.RxMagnetoErrorCodeMap.ERROR_OS_REQUIREMENTS;
12 | import static com.aritraroy.rxmagneto.core.RxMagnetoErrorCodeMap.ERROR_PUBLISHED_DATE;
13 | import static com.aritraroy.rxmagneto.core.RxMagnetoErrorCodeMap.ERROR_UPDATE;
14 | import static com.aritraroy.rxmagneto.core.RxMagnetoErrorCodeMap.ERROR_URL;
15 | import static com.aritraroy.rxmagneto.core.RxMagnetoErrorCodeMap.ERROR_VERIFIED_ERROR;
16 | import static com.aritraroy.rxmagneto.core.RxMagnetoErrorCodeMap.ERROR_VERSION;
17 | import static com.aritraroy.rxmagneto.core.RxMagnetoInternal.MARKET_PLAY_STORE_URL;
18 | import static com.aritraroy.rxmagneto.core.RxMagnetoTags.TAG_PLAY_STORE_CONTENT_RATING;
19 | import static com.aritraroy.rxmagneto.core.RxMagnetoTags.TAG_PLAY_STORE_DOWNLOADS;
20 | import static com.aritraroy.rxmagneto.core.RxMagnetoTags.TAG_PLAY_STORE_LAST_PUBLISHED_DATE;
21 | import static com.aritraroy.rxmagneto.core.RxMagnetoTags.TAG_PLAY_STORE_OS_REQUIREMENTS;
22 | import static com.aritraroy.rxmagneto.core.RxMagnetoTags.TAG_PLAY_STORE_VERSION;
23 | import static com.aritraroy.rxmagneto.util.Constants.APP_VERSION_VARIES_WITH_DEVICE;
24 |
25 | import android.content.Context;
26 |
27 | import com.aritraroy.rxmagneto.R;
28 | import com.aritraroy.rxmagneto.exceptions.AppVersionNotFoundException;
29 | import com.aritraroy.rxmagneto.exceptions.RxMagnetoException;
30 |
31 | import java.util.List;
32 |
33 | import io.reactivex.Single;
34 | import io.reactivex.schedulers.Schedulers;
35 |
36 | /**
37 | * A fast, simple and powerful Play Store information fetcher for Android. This library allows
38 | * you to fetch various live information from Play Store of your app or any other app of your
39 | * choice. With just a few lines of code, you can get access to a lot of useful app data fetched
40 | * fresh from the Play Store.
41 | *
42 | * It has been named after the famous anti-villain from X-Men. This library has been completely
43 | * written using RxJava giving you powerful controls to make the most use of it.
44 | */
45 | public class RxMagneto {
46 |
47 | private static volatile RxMagneto INSTANCE = null;
48 |
49 | private Context context;
50 | private RxMagnetoInternal rxMagnetoInternal;
51 |
52 | private RxMagneto() {
53 | if (INSTANCE != null) {
54 | throw new RuntimeException("Cannot instantiate singleton object using constructor. " +
55 | "Use its #getInstance() method");
56 | }
57 | }
58 |
59 | public static RxMagneto getInstance() {
60 | if (INSTANCE == null) {
61 | synchronized (RxMagneto.class) {
62 | if (INSTANCE == null) {
63 | INSTANCE = new RxMagneto();
64 | }
65 | }
66 | }
67 | return INSTANCE;
68 | }
69 |
70 | public void initialize(Context context) {
71 | this.context = context;
72 | this.rxMagnetoInternal = new RxMagnetoInternal(context);
73 | }
74 |
75 | /**
76 | * Grab the Play Store url of the current package
77 | *
78 | * @return A Single emitting the url
79 | */
80 | public Single grabUrl() {
81 | if (context != null) {
82 | return grabUrl(context.getPackageName());
83 | }
84 | return Single.error(new RxMagnetoException(ERROR_URL.getErrorCode(),
85 | context.getString(R.string.message_url_failed)));
86 | }
87 |
88 | /**
89 | * Grab the Play Store url of the specified package
90 | *
91 | * @param packageName A particular package name
92 | * @return A Single emitting the url
93 | */
94 | public Single grabUrl(String packageName) {
95 | if (!isEmpty(packageName)) {
96 | return Single.just(MARKET_PLAY_STORE_URL + packageName)
97 | .subscribeOn(Schedulers.trampoline());
98 | }
99 | return Single.error(new RxMagnetoException(ERROR_URL.getErrorCode(),
100 | context.getString(R.string.message_url_failed)));
101 | }
102 |
103 | /**
104 | * Grab the verified Play Store url of the current package
105 | *
106 | * @return A Single emitting the verified url of the current package
107 | */
108 | public Single grabVerifiedUrl() {
109 | if (context != null) {
110 | return grabVerifiedUrl(context.getPackageName());
111 | }
112 | return Single.error(new RxMagnetoException(ERROR_VERIFIED_ERROR.getErrorCode(),
113 | context.getString(R.string.message_verified_url_failed)));
114 | }
115 |
116 | /**
117 | * Grab the verified Play Store url of the specified package
118 |
119 | * @param packageName A particular package name*
120 | * @return A Single emitting the verified url of the specified package
121 | */
122 | public Single grabVerifiedUrl(String packageName) {
123 | if (context != null && !isEmpty(packageName)) {
124 | return rxMagnetoInternal.getPlayPackageInfoWithValidation(packageName)
125 | .subscribeOn(Schedulers.io())
126 | .flatMap(playPackageInfo -> Single.just(playPackageInfo.getPackageUrl()));
127 | }
128 | return Single.error(new RxMagnetoException(ERROR_VERIFIED_ERROR.getErrorCode(),
129 | context.getString(R.string.message_verified_url_failed)));
130 | }
131 |
132 | /**
133 | * Grab the latest version of the current package available on Play Store
134 | *
135 | * @return A Single emitting the current version
136 | */
137 | public Single grabVersion() {
138 | if (context != null) {
139 | return grabVersion(context.getPackageName());
140 | }
141 | return Single.error(new RxMagnetoException(ERROR_VERSION.getErrorCode(),
142 | context.getString(R.string.message_package_version_failed)));
143 | }
144 |
145 | /**
146 | * Grab the latest version of the specified package available on Play Store
147 | *
148 | * @param packageName A particular package name
149 | * @return A Single emitting the current version
150 | */
151 | public Single grabVersion(String packageName) {
152 | if (context != null && !isEmpty(packageName)) {
153 | return rxMagnetoInternal.getPlayPackageInfoWithValidation(packageName)
154 | .subscribeOn(Schedulers.io())
155 | .flatMap(playPackageInfo -> rxMagnetoInternal.getPlayPackageInfoForTag(packageName,
156 | TAG_PLAY_STORE_VERSION))
157 | .flatMap(playPackageInfo -> Single.just(playPackageInfo.getPackageVersion()));
158 | }
159 | return Single.error(new RxMagnetoException(ERROR_VERSION.getErrorCode(),
160 | context.getString(R.string.message_package_version_failed)));
161 | }
162 |
163 | /**
164 | * Check if an upgrade is available for the current package
165 | *
166 | * @return A Single emitting if an app upgrade is available
167 | */
168 | public Single isUpgradeAvailable() {
169 | if (context != null) {
170 | return isUpgradeAvailable(context.getPackageName());
171 | }
172 | return Single.error(new RxMagnetoException(ERROR_VERSION.getErrorCode(),
173 | context.getString(R.string.message_package_update_failed)));
174 | }
175 |
176 | /**
177 | * Check if an upgrade is available for the specified package
178 | *
179 | * @param packageName A particular package name
180 | * @return A Single emitting if an app upgrade is available
181 | */
182 | public Single isUpgradeAvailable(String packageName) {
183 | if (context != null && !isEmpty(packageName)) {
184 | String currentVersionStr;
185 | try {
186 | currentVersionStr = context.getPackageManager().getPackageInfo(packageName, 0)
187 | .versionName;
188 | } catch (NameNotFoundException e) {
189 | return Single.error(new NameNotFoundException(
190 | context.getString(R.string.message_app_not_installed, packageName)));
191 | }
192 |
193 | return rxMagnetoInternal.getPlayPackageInfoForTag(packageName, TAG_PLAY_STORE_VERSION)
194 | .subscribeOn(Schedulers.io())
195 | .flatMap(playPackageInfo -> {
196 | String currentVersion = playPackageInfo.getPackageVersion();
197 | if (APP_VERSION_VARIES_WITH_DEVICE.equals(currentVersion)) {
198 | return Single.error(new AppVersionNotFoundException(context
199 | .getString(R.string.message_app_version_varies)));
200 | }
201 | return Single.just(!currentVersionStr.equals(currentVersion));
202 | });
203 | }
204 | return Single.error(new RxMagnetoException(ERROR_UPDATE.getErrorCode(),
205 | context.getString(R.string.message_package_update_failed)));
206 | }
207 |
208 | /**
209 | * Grab the no of downloads for the current package
210 | *
211 | * @return A Single emitting the total downloads of the app
212 | */
213 | public Single grabDownloads() {
214 | if (context != null) {
215 | return grabDownloads(context.getPackageName());
216 | }
217 | return Single.error(new RxMagnetoException(ERROR_DOWNLOADS.getErrorCode(),
218 | context.getString(R.string.message_downloads_failed)));
219 | }
220 |
221 | /**
222 | * Grab the no of downloads for the specified package
223 | *
224 | * @param packageName A particular package name
225 | * @return A Single emitting the total downloads of the app
226 | */
227 | public Single grabDownloads(String packageName) {
228 | if (context != null && !isEmpty(packageName)) {
229 | return rxMagnetoInternal.getPlayPackageInfoForTag(packageName, TAG_PLAY_STORE_DOWNLOADS)
230 | .subscribeOn(Schedulers.io())
231 | .flatMap(playPackageInfo -> Single.just(playPackageInfo.getDownloads()));
232 | }
233 | return Single.error(new RxMagnetoException(ERROR_DOWNLOADS.getErrorCode(),
234 | context.getString(R.string.message_downloads_failed)));
235 | }
236 |
237 | /**
238 | * Grab the published date for the current package
239 | *
240 | * @return A Single emitting the published date of the app
241 | */
242 | public Single grabPublishedDate() {
243 | if (context != null) {
244 | return grabPublishedDate(context.getPackageName());
245 | }
246 | return Single.error(new RxMagnetoException(ERROR_PUBLISHED_DATE.getErrorCode(),
247 | context.getString(R.string.message_published_date_failed)));
248 | }
249 |
250 | /**
251 | * Grab the published date for the specified package
252 | *
253 | * @param packageName A particular package name
254 | * @return A Single emitting the published date of the app
255 | */
256 | public Single grabPublishedDate(String packageName) {
257 | if (context != null && !isEmpty(packageName)) {
258 | return rxMagnetoInternal.getPlayPackageInfoForTag(packageName, TAG_PLAY_STORE_LAST_PUBLISHED_DATE)
259 | .subscribeOn(Schedulers.io())
260 | .flatMap(playPackageInfo -> Single.just(playPackageInfo.getPublishedDate()));
261 | }
262 | return Single.error(new RxMagnetoException(ERROR_PUBLISHED_DATE.getErrorCode(),
263 | context.getString(R.string.message_published_date_failed)));
264 | }
265 |
266 | /**
267 | * Grab the minimum OS requirements for the given package
268 | *
269 | * @return A Single emitting the OS requirements of the app
270 | */
271 | public Single grabOsRequirements() {
272 | if (context != null) {
273 | return grabOsRequirements(context.getPackageName());
274 | }
275 | return Single.error(new RxMagnetoException(ERROR_OS_REQUIREMENTS.getErrorCode(),
276 | context.getString(R.string.message_os_requirement_failed)));
277 | }
278 |
279 | /**
280 | * Grab the minimum OS requirements for the specified package
281 | *
282 | * @param packageName A particular package name
283 | * @return A Single emitting the OS requirements of the app
284 | */
285 | public Single grabOsRequirements(String packageName) {
286 | if (context != null && !isEmpty(packageName)) {
287 | return rxMagnetoInternal.getPlayPackageInfoForTag(packageName, TAG_PLAY_STORE_OS_REQUIREMENTS)
288 | .subscribeOn(Schedulers.io())
289 | .flatMap(playPackageInfo -> Single.just(playPackageInfo.getOsRequirements()));
290 | }
291 | return Single.error(new RxMagnetoException(ERROR_OS_REQUIREMENTS.getErrorCode(),
292 | context.getString(R.string.message_os_requirement_failed)));
293 | }
294 |
295 | /**
296 | * Grab the content rating for the current package
297 | *
298 | * @return A Single emitting the content rating of the app
299 | */
300 | public Single grabContentRating() {
301 | if (context != null) {
302 | return grabContentRating(context.getPackageName());
303 | }
304 | return Single.error(new RxMagnetoException(ERROR_CONTENT_RATING.getErrorCode(),
305 | context.getString(R.string.message_content_rating_failed)));
306 | }
307 |
308 | /**
309 | * Grab the content rating for the specified package
310 | *
311 | * @param packageName A particular package name
312 | * @return A Single emitting the content rating of the app
313 | */
314 | public Single grabContentRating(String packageName) {
315 | if (context != null && !isEmpty(packageName)) {
316 | return rxMagnetoInternal.getPlayPackageInfoForTag(packageName, TAG_PLAY_STORE_CONTENT_RATING)
317 | .subscribeOn(Schedulers.io())
318 | .flatMap(playPackageInfo -> Single.just(playPackageInfo.getContentRating()));
319 | }
320 | return Single.error(new RxMagnetoException(ERROR_CONTENT_RATING.getErrorCode(),
321 | context.getString(R.string.message_content_rating_failed)));
322 | }
323 |
324 | /**
325 | * Grab the app rating for the current package
326 | *
327 | * @return A Single emitting the app rating
328 | */
329 | public Single grabAppRating() {
330 | if (context != null) {
331 | return grabAppRating(context.getPackageName());
332 | }
333 | return Single.error(new RxMagnetoException(ERROR_APP_RATING.getErrorCode(),
334 | context.getString(R.string.message_app_rating_failed)));
335 | }
336 |
337 | /**
338 | * Grab the app rating for the specified package
339 | *
340 | * @param packageName A particular package name
341 | * @return A Single emitting the app rating
342 | */
343 | public Single grabAppRating(String packageName) {
344 | if (context != null && !isEmpty(packageName)) {
345 | return rxMagnetoInternal.getPlayPackageInfoWithAppRating(packageName)
346 | .subscribeOn(Schedulers.io())
347 | .flatMap(playPackageInfo -> Single.just(playPackageInfo.getAppRating()));
348 | }
349 | return Single.error(new RxMagnetoException(ERROR_APP_RATING.getErrorCode(),
350 | context.getString(R.string.message_app_rating_failed)));
351 | }
352 |
353 | /**
354 | * Grab the no. of app ratings for the current package
355 | *
356 | * @return A Single emitting the app rating count
357 | */
358 | public Single grabAppRatingsCount() {
359 | if (context != null) {
360 | return grabAppRatingsCount(context.getPackageName());
361 | }
362 | return Single.error(new RxMagnetoException(ERROR_APP_RATING_COUNT.getErrorCode(),
363 | context.getString(R.string.message_app_rating_count_failed)));
364 | }
365 |
366 | /**
367 | * Grab the no. of app ratings for the specified package
368 | *
369 | * @param packageName A particular package name
370 | * @return A Single emitting the app rating count
371 | */
372 | public Single grabAppRatingsCount(String packageName) {
373 | if (context != null && !isEmpty(packageName)) {
374 | return rxMagnetoInternal.getPlayPackageInfoWithAppRatingsCount(packageName)
375 | .subscribeOn(Schedulers.io())
376 | .flatMap(playPackageInfo -> Single.just(playPackageInfo.getAppRatingCount()));
377 | }
378 | return Single.error(new RxMagnetoException(ERROR_APP_RATING_COUNT.getErrorCode(),
379 | context.getString(R.string.message_app_rating_count_failed)));
380 | }
381 |
382 | /**
383 | * Grab the changelog or "What's New" section of the current app in the form of a String
384 | * array
385 | *
386 | * @return A Single emitting the changelog array
387 | */
388 | public Single> grabPlayStoreRecentChangelogArray() {
389 | if (context != null) {
390 | return grabPlayStoreRecentChangelogArray(context.getPackageName());
391 | }
392 | return Single.error(new RxMagnetoException(ERROR_CHANGELOG.getErrorCode(),
393 | context.getString(R.string.message_app_changelog_failed)));
394 | }
395 |
396 | /**
397 | * Grab the changelog or "What's New" section of the specified app in the form of a String
398 | * array
399 | *
400 | * @param packageName A particular package name
401 | * @return A Single emitting the changelog array
402 | */
403 | public Single> grabPlayStoreRecentChangelogArray(String packageName) {
404 | if (context != null && !isEmpty(packageName)) {
405 | return rxMagnetoInternal.getPlayPackageInfoWithRecentChangelogArray(packageName)
406 | .subscribeOn(Schedulers.io())
407 | .flatMap(playPackageInfo -> Single.just(playPackageInfo.getChangelogArray()));
408 | }
409 | return Single.error(new RxMagnetoException(ERROR_CHANGELOG.getErrorCode(),
410 | context.getString(R.string.message_app_changelog_failed)));
411 | }
412 |
413 | /**
414 | * Grab the changelog or "What's New" section of the current app
415 | *
416 | * @return A Single emitting the changelog
417 | */
418 | public Single grabPlayStoreRecentChangelog() {
419 | if (context != null) {
420 | return grabPlayStoreRecentChangelog(context.getPackageName());
421 | }
422 | return Single.error(new RxMagnetoException(ERROR_CHANGELOG.getErrorCode(),
423 | context.getString(R.string.message_app_changelog_failed)));
424 | }
425 |
426 | /**
427 | * Grab the changelog or "What's New" section of the specified app
428 | *
429 | * @param packageName A particular package name
430 | * @return A Single emitting the changelog
431 | */
432 | public Single grabPlayStoreRecentChangelog(String packageName) {
433 | if (context != null && !isEmpty(packageName)) {
434 | return rxMagnetoInternal.getPlayPackageInfoWithRecentChangelogArray(packageName)
435 | .subscribeOn(Schedulers.io())
436 | .flatMap(playPackageInfo -> Single.just(playPackageInfo.getChangelogArray())
437 | .flatMap(strings -> {
438 | StringBuilder stringBuilder = new StringBuilder();
439 | for (int i = 0; i < strings.size(); i++) {
440 | String string = strings.get(i);
441 | stringBuilder.append(string);
442 | if (i < strings.size() - 1) {
443 | stringBuilder.append("\n\n");
444 | }
445 | }
446 | return Single.just(stringBuilder.toString());
447 | }));
448 | }
449 | return Single.error(new RxMagnetoException(ERROR_CHANGELOG.getErrorCode(),
450 | context.getString(R.string.message_app_changelog_failed)));
451 | }
452 | }
453 |
--------------------------------------------------------------------------------