Skip to content

Commit

Permalink
Add support for product flavors
Browse files Browse the repository at this point in the history
Add support for third-party app stores like Samsung Galaxy Store.
Update `link` utils to accept an optional `flavor` parameter.
  • Loading branch information
pranavpandey committed Jul 21, 2024
1 parent d97a4c2 commit 5ef756c
Show file tree
Hide file tree
Showing 16 changed files with 300 additions and 28 deletions.
7 changes: 6 additions & 1 deletion dynamic-utils/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2017-2022 Pranav Pandey
Copyright 2017-2024 Pranav Pandey
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand All @@ -18,6 +18,11 @@
<manifest
xmlns:android="http://schemas.android.com/apk/res/android">

<!-- Query packages on API 30 and above. -->
<queries>
<package android:name="com.google.android.gms" />
</queries>

<!-- Query intents on API 30 and above. -->
<queries>
<intent>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2017-2022 Pranav Pandey
* Copyright 2017-2024 Pranav Pandey
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -72,6 +72,18 @@ public class DynamicLinkUtils {
private static final String URL_GOOGLE_PLAY_SEARCH_PUB =
"http://play.google.com/store/search?q=pub:";

/**
* Samsung Galaxy Store app URL template to open app details.
*/
private static final String URL_SAMSUNG_GALAXY_STORE =
"https://apps.samsung.com/appquery/appDetail.as?appId=";

/**
* Samsung Galaxy Store app search query template to search apps of a publisher.
*/
private static final String URL_SAMSUNG_GALAXY_STORE_SEARCH_PUB =
"https://apps.samsung.com/appquery/sellerProductList.as?SellerID=";

/**
* Constant for the bookmarks URI.
*/
Expand Down Expand Up @@ -173,13 +185,15 @@ public static boolean copyToClipboard(@NonNull Context context,
* <p>{@code null} to supply app and package name.
* @param uri The optional content URI to be shared.
* @param mimeType The optional mime type for the file.
* @param flavor The product flavor to be used.
*
* @return {@code true} on successful operation.
*
* @see Intent#ACTION_SEND
*/
public static boolean share(@Nullable Context context, @Nullable String title,
@Nullable String message, @Nullable Uri uri, @Nullable String mimeType) {
@Nullable String message, @Nullable Uri uri, @Nullable String mimeType,
@DynamicSdkUtils.DynamicFlavor String flavor) {
if (context == null) {
return false;
}
Expand All @@ -194,9 +208,17 @@ public static boolean share(@Nullable Context context, @Nullable String title,
}

if (message == null) {
message = String.format(context.getString(R.string.adu_share_desc),
context.getApplicationInfo().loadLabel(context.getPackageManager()),
context.getPackageName());
if (DynamicSdkUtils.DynamicFlavor.EXTERNAL.equals(flavor)
&& DynamicDeviceUtils.isSamsungOneUI()) {
message = String.format(context.getString(
R.string.adu_share_desc_samsung_galaxy_store),
context.getApplicationInfo().loadLabel(context.getPackageManager()),
context.getPackageName());
} else {
message = String.format(context.getString(R.string.adu_share_desc),
context.getApplicationInfo().loadLabel(context.getPackageManager()),
context.getPackageName());
}
}

intent.putExtra(Intent.EXTRA_TEXT, message);
Expand All @@ -219,6 +241,27 @@ public static boolean share(@Nullable Context context, @Nullable String title,
return false;
}

/**
* Share application via system default share intent so that user can select from the
* available apps if more than one apps are available.
*
* @param context The context to be used.
* @param title The application chooser title if more than one apps are available.
* @param message The default share message which user can modify.
* <p>{@code null} to supply app and package name.
* @param image The optional image bitmap URI to be shared.
* @param flavor The product flavor to be used.
*
* @return {@code true} on successful operation.
*
* @see Intent#ACTION_SEND
*/
public static boolean share(@Nullable Context context,
@Nullable String title, @Nullable String message, @Nullable Uri image,
@DynamicSdkUtils.DynamicFlavor String flavor) {
return share(context, title, message, image, "image/*", flavor);
}

/**
* Share application via system default share intent so that user can select from the
* available apps if more than one apps are available.
Expand All @@ -235,7 +278,26 @@ public static boolean share(@Nullable Context context, @Nullable String title,
*/
public static boolean share(@Nullable Context context, @Nullable String title,
@Nullable String message, @Nullable Uri image) {
return share(context, title, message, image, "image/*");
return share(context, title, message, image, DynamicSdkUtils.DynamicFlavor.GOOGLE);
}

/**
* Share application via system default share intent so that user can select from the
* available apps if more than one apps are available.
*
* @param context The context to be used.
* @param title The application chooser title if more than one apps are available.
* @param message The default share message which user can modify.
* <p>{@code null} to supply app and package name.
* @param flavor The product flavor to be used.
*
* @return {@code true} on successful operation.
*
* @see Intent#ACTION_SEND
*/
public static boolean share(@Nullable Context context, @Nullable String title,
@Nullable String message, @DynamicSdkUtils.DynamicFlavor String flavor) {
return share(context, title, message, null, flavor);
}

/**
Expand All @@ -253,7 +315,23 @@ public static boolean share(@Nullable Context context, @Nullable String title,
*/
public static boolean share(@Nullable Context context,
@Nullable String title, @Nullable String message) {
return share(context, title, message, null);
return share(context, title, message, DynamicSdkUtils.DynamicFlavor.GOOGLE);
}

/**
* Share application via system default share intent so that user can select from the
* available apps if more than one apps are available.
*
* @param context The context to be used.
* @param flavor The product flavor to be used.
*
* @return {@code true} on successful operation.
*
* @see #share(Context, String, String)
*/
public static boolean shareApp(@Nullable Context context,
@DynamicSdkUtils.DynamicFlavor String flavor) {
return share(context, null, null, flavor);
}

/**
Expand All @@ -267,7 +345,7 @@ public static boolean share(@Nullable Context context,
* @see #share(Context, String, String)
*/
public static boolean shareApp(@Nullable Context context) {
return share(context, null, null);
return shareApp(context, DynamicSdkUtils.DynamicFlavor.GOOGLE);
}

/**
Expand Down Expand Up @@ -301,7 +379,7 @@ public static boolean viewUrl(@Nullable Context context, @Nullable String url) {
* {@code https or http} in {@code AndroidManifest} to support API 30.
*
* @param context The context to be used.
* @param packageName Application package name to build the search query.
* @param packageName The app package name to build the search query.
*
* @return {@code true} on successful operation.
*
Expand All @@ -316,24 +394,140 @@ public static boolean viewInGooglePlay(@Nullable Context context,
return viewUrl(context, URL_PLAY_STORE + packageName);
}

/**
* View app on Samsung Galaxy Store.
* <p>Use {@code queries} tag for {@link Intent#ACTION_VIEW} with scheme
* {@code https or http} in {@code AndroidManifest} to support API 30.
*
* @param context The context to be used.
* @param packageName The app package name to build the search query.
*
* @return {@code true} on successful operation.
*
* @see Intent#ACTION_VIEW
*/
public static boolean viewInSamsungGalaxyStore(@Nullable Context context,
@NonNull String packageName) {
return viewUrl(context, URL_SAMSUNG_GALAXY_STORE + packageName);
}

/**
* View app on Google Play (or Android Market) or Samsung Galaxy Store if available.
* <p>Can be used to view app details within the supported stores.
* <p>Use {@code queries} tag for {@link Intent#ACTION_VIEW} with scheme
* {@code https or http} in {@code AndroidManifest} to support API 30.
*
* @param context The context to be used.
* @param packageName The app package name to build the search query.
* @param flavor The product flavor to be used.
*
* @return {@code true} on successful operation.
*
* @see #viewInGooglePlay(Context, String)
* @see #viewInSamsungGalaxyStore(Context, String)
* @see DynamicSdkUtils.DynamicFlavor
*/
public static boolean viewApp(@Nullable Context context, @NonNull String packageName,
@DynamicSdkUtils.DynamicFlavor String flavor) {
if (DynamicSdkUtils.DynamicFlavor.EXTERNAL.equals(flavor)) {
return viewAppExternal(context, packageName);
} else if (context == null) {
return false;
}

if (viewInGooglePlay(context, packageName)) {
return true;
} else if (DynamicDeviceUtils.isSamsungOneUI()) {
return viewInSamsungGalaxyStore(context, packageName);
}

return false;
}

/**
* View app on Google Play (or Android Market) or Samsung Galaxy Store if available.
* <p>Can be used to view app details within the supported stores.
* <p>Use {@code queries} tag for {@link Intent#ACTION_VIEW} with scheme
* {@code https or http} in {@code AndroidManifest} to support API 30.
*
* @param context The context to be used.
* @param packageName The app package name to build the search query.
*
* @return {@code true} on successful operation.
*
* @see #viewApp(Context, String, String)
* @see DynamicSdkUtils.DynamicFlavor#GOOGLE
*/
public static boolean viewApp(@Nullable Context context, @NonNull String packageName) {
return viewApp(context, packageName, DynamicSdkUtils.DynamicFlavor.GOOGLE);
}

/**
* View app on Google Play (or Android Market) or Samsung Galaxy Store if available.
* External stores will be preferred first.
* <p>Can be used to view app details within the supported stores.
* <p>Use {@code queries} tag for {@link Intent#ACTION_VIEW} with scheme
* {@code https or http} in {@code AndroidManifest} to support API 30.
*
* @param context The context to be used.
* @param packageName The app package name to build the search query.
*
* @return {@code true} on successful operation.
*
* @see #viewInGooglePlay(Context, String)
* @see #viewInSamsungGalaxyStore(Context, String)
*/
public static boolean viewAppExternal(@Nullable Context context, @NonNull String packageName) {
if (context == null) {
return false;
}


if (DynamicDeviceUtils.isSamsungOneUI()
&& viewInSamsungGalaxyStore(context, packageName)) {
return true;
} else {
return viewInGooglePlay(context, packageName);
}
}

/**
* View app on Google Play or Android Market.
* <p>Can be used for the quick feedback or rating from the user.
* <p>Use {@code queries} tag for {@link Intent#ACTION_VIEW} with scheme
* {@code https or http} in {@code AndroidManifest} to support API 30.
*
* @param context The context to be used.
* @param flavor The product flavor to be used.
*
* @return {@code true} on successful operation.
*
* @see #viewInGooglePlay(Context, String)
* @see #viewApp(Context, String, String)
* @see DynamicSdkUtils.DynamicFlavor
*/
public static boolean rateApp(@Nullable Context context) {
public static boolean rateApp(@Nullable Context context,
@DynamicSdkUtils.DynamicFlavor String flavor) {
if (context == null) {
return false;
}

return viewInGooglePlay(context, context.getPackageName());
return viewApp(context, context.getPackageName(), flavor);
}

/**
* View app on Google Play or Android Market.
* <p>Can be used for the quick feedback or rating from the user.
* <p>Use {@code queries} tag for {@link Intent#ACTION_VIEW} with scheme
* {@code https or http} in {@code AndroidManifest} to support API 30.
*
* @param context The context to be used.
*
* @return {@code true} on successful operation.
*
* @see #rateApp(Context, String)
*/
public static boolean rateApp(@Nullable Context context) {
return rateApp(context, DynamicSdkUtils.DynamicFlavor.GOOGLE);
}

/**
Expand All @@ -346,7 +540,7 @@ public static boolean rateApp(@Nullable Context context) {
*
* @return {@code true} on successful operation.
*
* @see Intent#ACTION_VIEW
* @see #viewUrl(Context, String)
*/
public static boolean moreApps(@Nullable Context context, @NonNull String publisher) {
if (viewUrl(context, URL_MARKET_SEARCH_PUB + publisher)) {
Expand All @@ -356,6 +550,22 @@ public static boolean moreApps(@Nullable Context context, @NonNull String publis
return viewUrl(context, URL_GOOGLE_PLAY_SEARCH_PUB + publisher);
}

/**
* View other apps of a Samsung Galaxy Store.
* <p>Use {@code queries} tag for {@link Intent#ACTION_VIEW} with scheme
* {@code https or http} in {@code AndroidManifest} to support API 30.
*
* @param context The context to be used.
* @param publisher The publisher name to build the search query.
*
* @return {@code true} on successful operation.
*
* @see #viewUrl(Context, String)
*/
public static boolean moreAppsSamsung(@Nullable Context context, @NonNull String publisher) {
return viewUrl(context, URL_SAMSUNG_GALAXY_STORE_SEARCH_PUB + publisher);
}

/**
* Send email according to the supplied parameters.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2017-2022 Pranav Pandey
* Copyright 2017-2024 Pranav Pandey
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -28,6 +28,22 @@
@TargetApi(Build.VERSION_CODES.M)
public class DynamicSdkUtils {

/**
* Product flavors to support external app stores.
*/
public @interface DynamicFlavor {

/**
* Constant for the Google Play Store.
*/
String GOOGLE = "google";

/**
* Constant for the external app store.
*/
String EXTERNAL = "external";
}

/**
* Detects if the current API version is a preview.
*
Expand Down
Loading

0 comments on commit 5ef756c

Please sign in to comment.