diff --git a/OsmAnd/res/layout/bottom_sheet_item_title_big.xml b/OsmAnd/res/layout/bottom_sheet_item_title_big.xml index ad594bb7d8..7037293289 100644 --- a/OsmAnd/res/layout/bottom_sheet_item_title_big.xml +++ b/OsmAnd/res/layout/bottom_sheet_item_title_big.xml @@ -6,7 +6,7 @@ android:layout_width="match_parent" android:layout_height="@dimen/bottom_sheet_title_height" android:ellipsize="end" - android:gravity="bottom" + android:gravity="center_vertical" android:letterSpacing="@dimen/text_button_letter_spacing" android:maxLines="1" android:minHeight="@dimen/bottom_sheet_title_height" diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 5a63fd362a..faffea069e 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -11,6 +11,9 @@ Thx - Hardy --> + Open settings + Plugin disabled + This plugin is a separate application, you will need to remove it separately if you no longer plan to use it.\n\nThe plugin will remain on the device after removing OsmAnd. Menu %1$s — %2$s — %3$s Direct-to-point diff --git a/OsmAnd/src/net/osmand/AndroidUtils.java b/OsmAnd/src/net/osmand/AndroidUtils.java index 9f0a4c4add..f60e069c4c 100644 --- a/OsmAnd/src/net/osmand/AndroidUtils.java +++ b/OsmAnd/src/net/osmand/AndroidUtils.java @@ -4,6 +4,7 @@ package net.osmand; import android.app.Activity; import android.app.KeyguardManager; import android.content.Context; +import android.content.Intent; import android.content.res.ColorStateList; import android.content.res.Configuration; import android.content.res.Resources; @@ -158,6 +159,10 @@ public class AndroidUtils { } } + public static boolean isIntentSafe(Context context, Intent intent) { + return intent.resolveActivity(context.getPackageManager()) != null; + } + public static Spannable replaceCharsWithIcon(String text, Drawable icon, String[] chars) { Spannable spannable = new SpannableString(text); for (String entry : chars) { diff --git a/OsmAnd/src/net/osmand/plus/OsmandPlugin.java b/OsmAnd/src/net/osmand/plus/OsmandPlugin.java index 7af27f0c17..5e5d4afedd 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandPlugin.java +++ b/OsmAnd/src/net/osmand/plus/OsmandPlugin.java @@ -24,9 +24,9 @@ import net.osmand.plus.activities.TabActivity.TabItem; import net.osmand.plus.audionotes.AudioVideoNotesPlugin; import net.osmand.plus.dashboard.tools.DashFragmentData; import net.osmand.plus.development.OsmandDevelopmentPlugin; +import net.osmand.plus.dialogs.PluginDisabledBottomSheet; import net.osmand.plus.dialogs.PluginInstalledBottomSheetDialog; import net.osmand.plus.download.IndexItem; -import net.osmand.plus.inapp.InAppPurchaseHelper; import net.osmand.plus.mapcontextmenu.MenuBuilder; import net.osmand.plus.mapcontextmenu.MenuController; import net.osmand.plus.mapillary.MapillaryPlugin; @@ -166,6 +166,15 @@ public abstract class OsmandPlugin { } } + public void showDisableDialog(@Nullable Activity activity) { + if (activity instanceof FragmentActivity) { + FragmentManager fragmentManager = ((FragmentActivity) activity).getSupportFragmentManager(); + if (fragmentManager != null) { + PluginDisabledBottomSheet.showInstance(fragmentManager, getId(), activity instanceof MapActivity); + } + } + } + public void disable(OsmandApplication app) { } @@ -247,7 +256,7 @@ public abstract class OsmandPlugin { private static boolean updateMarketPlugin(@NonNull OsmandApplication app, @NonNull Set enabledPlugins, @NonNull OsmandPlugin plugin) { boolean marketEnabled = Version.isMarketEnabled(app); - boolean pckg = checkPluginPackage(app, plugin); + boolean pckg = plugin.pluginAvailable(app); boolean paid = plugin.isPaid(); if ((Version.isDeveloperVersion(app) || !Version.isProductionVersion(app)) && !paid) { // for test reasons @@ -276,7 +285,7 @@ public abstract class OsmandPlugin { public static void checkInstalledMarketPlugins(@NonNull OsmandApplication app, @Nullable Activity activity) { Set enabledPlugins = app.getSettings().getEnabledPlugins(); for (OsmandPlugin plugin : OsmandPlugin.getMarketPlugins()) { - if (plugin.getInstallURL() != null && checkPluginPackage(app, plugin)) { + if (plugin.getInstallURL() != null && plugin.pluginAvailable(app)) { plugin.onInstall(app, activity); initPlugin(app, plugin); } @@ -284,13 +293,12 @@ public abstract class OsmandPlugin { } } - private static boolean checkPluginPackage(OsmandApplication app, OsmandPlugin plugin) { - return plugin.checkPluginPackage(app); - + protected boolean pluginAvailable(OsmandApplication app) { + return checkPluginPackage(app, this); } - protected boolean checkPluginPackage(OsmandApplication app) { - return isPackageInstalled(getComponentId1(), app) || isPackageInstalled(getComponentId2(), app); + public static boolean checkPluginPackage(@NonNull OsmandApplication app, @NonNull OsmandPlugin plugin) { + return isPackageInstalled(plugin.getComponentId1(), app) || isPackageInstalled(plugin.getComponentId2(), app); } public static boolean enablePlugin(@Nullable Activity activity, OsmandApplication app, OsmandPlugin plugin, boolean enable) { @@ -306,17 +314,27 @@ public abstract class OsmandPlugin { plugin.setActive(false); } app.getSettings().enablePlugin(plugin.getId(), enable); - if (activity != null && activity instanceof MapActivity) { - final MapActivity mapActivity = (MapActivity) activity; - plugin.updateLayers(mapActivity.getMapView(), mapActivity); - mapActivity.getDashboard().refreshDashboardFragments(); + if (activity != null) { + if (activity instanceof MapActivity) { + final MapActivity mapActivity = (MapActivity) activity; + plugin.updateLayers(mapActivity.getMapView(), mapActivity); + mapActivity.getDashboard().refreshDashboardFragments(); - DashFragmentData fragmentData = plugin.getCardFragment(); - if (!enable && fragmentData != null) { - FragmentManager fm = mapActivity.getSupportFragmentManager(); - Fragment fragment = fm.findFragmentByTag(fragmentData.tag); - if (fragment != null) { - fm.beginTransaction().remove(fragment).commit(); + DashFragmentData fragmentData = plugin.getCardFragment(); + if (!enable && fragmentData != null) { + FragmentManager fm = mapActivity.getSupportFragmentManager(); + Fragment fragment = fm.findFragmentByTag(fragmentData.tag); + if (fragment != null) { + fm.beginTransaction().remove(fragment).commit(); + } + } + } + + if (plugin.isMarketPlugin()) { + if (plugin.isActive()) { + plugin.showInstallDialog(activity); + } else if (OsmandPlugin.checkPluginPackage(app, plugin)) { + plugin.showDisableDialog(activity); } } } diff --git a/OsmAnd/src/net/osmand/plus/activities/PluginsActivity.java b/OsmAnd/src/net/osmand/plus/activities/PluginsActivity.java index d6eb6f1319..69aa72e5d9 100644 --- a/OsmAnd/src/net/osmand/plus/activities/PluginsActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/PluginsActivity.java @@ -81,9 +81,6 @@ public class PluginsActivity extends OsmandListActivity implements DownloadIndex listModified = true; } getListAdapter().notifyDataSetChanged(); - if (plugin.isActive() && plugin.isMarketPlugin()) { - plugin.showInstallDialog(this); - } } } @@ -206,7 +203,7 @@ public class PluginsActivity extends OsmandListActivity implements DownloadIndex if (active) { pluginLogo.setBackgroundResource(isLightTheme ? R.drawable.bg_plugin_logo_enabled_light : R.drawable.bg_plugin_logo_enabled_dark); } else { - TypedArray attributes = getTheme().obtainStyledAttributes(new int[]{R.attr.bg_plugin_logo_disabled}); + TypedArray attributes = getTheme().obtainStyledAttributes(new int[] {R.attr.bg_plugin_logo_disabled}); pluginLogo.setBackgroundDrawable(attributes.getDrawable(0)); attributes.recycle(); } diff --git a/OsmAnd/src/net/osmand/plus/base/bottomsheetmenu/BottomSheetItemTitleWithDescrAndButton.java b/OsmAnd/src/net/osmand/plus/base/bottomsheetmenu/BottomSheetItemTitleWithDescrAndButton.java index 49c366dac0..6899c3cb3c 100644 --- a/OsmAnd/src/net/osmand/plus/base/bottomsheetmenu/BottomSheetItemTitleWithDescrAndButton.java +++ b/OsmAnd/src/net/osmand/plus/base/bottomsheetmenu/BottomSheetItemTitleWithDescrAndButton.java @@ -32,7 +32,7 @@ public class BottomSheetItemTitleWithDescrAndButton extends BottomSheetItemWithD int position, Drawable icon, Drawable background, - String title, + CharSequence title, @ColorRes int titleColorId, CharSequence description, @ColorRes int descriptionColorId, diff --git a/OsmAnd/src/net/osmand/plus/base/bottomsheetmenu/BottomSheetItemWithCompoundButton.java b/OsmAnd/src/net/osmand/plus/base/bottomsheetmenu/BottomSheetItemWithCompoundButton.java index 7f50b0d5ed..cd8d46239e 100644 --- a/OsmAnd/src/net/osmand/plus/base/bottomsheetmenu/BottomSheetItemWithCompoundButton.java +++ b/OsmAnd/src/net/osmand/plus/base/bottomsheetmenu/BottomSheetItemWithCompoundButton.java @@ -37,7 +37,7 @@ public class BottomSheetItemWithCompoundButton extends BottomSheetItemWithDescri int position, Drawable icon, Drawable background, - String title, + CharSequence title, @ColorRes int titleColorId, CharSequence description, @ColorRes int descriptionColorId, diff --git a/OsmAnd/src/net/osmand/plus/base/bottomsheetmenu/BottomSheetItemWithDescription.java b/OsmAnd/src/net/osmand/plus/base/bottomsheetmenu/BottomSheetItemWithDescription.java index 6144b11e3a..15d8448766 100644 --- a/OsmAnd/src/net/osmand/plus/base/bottomsheetmenu/BottomSheetItemWithDescription.java +++ b/OsmAnd/src/net/osmand/plus/base/bottomsheetmenu/BottomSheetItemWithDescription.java @@ -30,7 +30,7 @@ public class BottomSheetItemWithDescription extends SimpleBottomSheetItem { int position, Drawable icon, Drawable background, - String title, + CharSequence title, @ColorRes int titleColorId, CharSequence description, @ColorRes int descriptionColorId, diff --git a/OsmAnd/src/net/osmand/plus/base/bottomsheetmenu/SimpleBottomSheetItem.java b/OsmAnd/src/net/osmand/plus/base/bottomsheetmenu/SimpleBottomSheetItem.java index 4a4c9746fd..0366a00192 100644 --- a/OsmAnd/src/net/osmand/plus/base/bottomsheetmenu/SimpleBottomSheetItem.java +++ b/OsmAnd/src/net/osmand/plus/base/bottomsheetmenu/SimpleBottomSheetItem.java @@ -17,7 +17,7 @@ public class SimpleBottomSheetItem extends BaseBottomSheetItem { private Drawable background; private Drawable icon; - protected String title; + protected CharSequence title; @ColorRes protected int titleColorId = INVALID_ID; @@ -32,7 +32,7 @@ public class SimpleBottomSheetItem extends BaseBottomSheetItem { int position, Drawable icon, Drawable background, - String title, + CharSequence title, @ColorRes int titleColorId) { super(customView, layoutId, tag, disabled, onClickListener, position); this.icon = icon; @@ -83,7 +83,7 @@ public class SimpleBottomSheetItem extends BaseBottomSheetItem { protected Drawable icon; protected Drawable background; - protected String title; + protected CharSequence title; @ColorRes protected int titleColorId = INVALID_ID; @@ -97,7 +97,7 @@ public class SimpleBottomSheetItem extends BaseBottomSheetItem { return this; } - public Builder setTitle(String title) { + public Builder setTitle(CharSequence title) { this.title = title; return this; } diff --git a/OsmAnd/src/net/osmand/plus/dialogs/PluginDisabledBottomSheet.java b/OsmAnd/src/net/osmand/plus/dialogs/PluginDisabledBottomSheet.java new file mode 100644 index 0000000000..259933f367 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/dialogs/PluginDisabledBottomSheet.java @@ -0,0 +1,147 @@ +package net.osmand.plus.dialogs; + +import android.content.Context; +import android.content.Intent; +import android.graphics.Typeface; +import android.net.Uri; +import android.os.Bundle; +import android.provider.Settings; +import android.support.annotation.NonNull; +import android.support.v4.app.FragmentManager; +import android.text.SpannableString; + +import net.osmand.AndroidUtils; +import net.osmand.PlatformUtil; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.OsmandPlugin; +import net.osmand.plus.R; +import net.osmand.plus.base.MenuBottomSheetDialogFragment; +import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; +import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem; +import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem; +import net.osmand.plus.helpers.FontCache; +import net.osmand.plus.widgets.style.CustomTypefaceSpan; + +import org.apache.commons.logging.Log; + +import static net.osmand.plus.OsmandPlugin.PLUGIN_ID_KEY; + +public class PluginDisabledBottomSheet extends MenuBottomSheetDialogFragment { + + public static final String TAG = PluginDisabledBottomSheet.class.getName(); + + private static final Log LOG = PlatformUtil.getLog(PluginDisabledBottomSheet.class); + + private String pluginId; + + @Override + public void createMenuItems(Bundle savedInstanceState) { + final OsmandApplication app = getMyApplication(); + Context context = getContext(); + if (context == null || app == null) { + return; + } + + if (savedInstanceState != null) { + pluginId = savedInstanceState.getString(PLUGIN_ID_KEY); + } else { + Bundle args = getArguments(); + if (args != null) { + pluginId = args.getString(PLUGIN_ID_KEY); + } + } + + OsmandPlugin plugin = OsmandPlugin.getPlugin(pluginId); + if (plugin == null) { + return; + } + + BaseBottomSheetItem titleItem = new TitleItem.Builder() + .setTitle(getString(R.string.plugin_disabled)) + .setLayoutId(R.layout.bottom_sheet_item_title_big) + .create(); + items.add(titleItem); + + Typeface typeface = FontCache.getRobotoMedium(getContext()); + SpannableString pluginTitleSpan = new SpannableString(plugin.getName()); + pluginTitleSpan.setSpan(new CustomTypefaceSpan(typeface), 0, pluginTitleSpan.length(), 0); + + BaseBottomSheetItem pluginTitle = new SimpleBottomSheetItem.Builder() + .setTitle(pluginTitleSpan) + .setTitleColorId(nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light) + .setIcon(getContentIcon(R.drawable.ic_extension_dark)) + .setLayoutId(R.layout.bottom_sheet_item_simple_56dp) + .create(); + items.add(pluginTitle); + + BaseBottomSheetItem descrItem = new SimpleBottomSheetItem.Builder() + .setTitle(getString(R.string.plugin_disabled_descr)) + .setLayoutId(R.layout.bottom_sheet_item_title_long) + .create(); + items.add(descrItem); + + } + + @Override + protected int getDismissButtonTextId() { + return R.string.shared_string_close; + } + + @Override + protected int getRightBottomButtonTextId() { + return R.string.open_settings; + } + + @Override + protected void onRightBottomButtonClick() { + OsmandApplication app = getMyApplication(); + Intent intent = getPluginSettingsIntent(); + if (app != null && AndroidUtils.isIntentSafe(app, intent)) { + startActivity(intent); + } + dismiss(); + } + + @Override + public void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + outState.putString(PLUGIN_ID_KEY, pluginId); + } + + private Intent getPluginSettingsIntent() { + Intent intent = null; + + OsmandApplication app = getMyApplication(); + OsmandPlugin plugin = OsmandPlugin.getPlugin(pluginId); + if (plugin != null && app != null) { + String installedPackage = null; + if (OsmandPlugin.isPackageInstalled(plugin.getComponentId1(), app)) { + installedPackage = plugin.getComponentId1(); + } + if (OsmandPlugin.isPackageInstalled(plugin.getComponentId2(), app)) { + installedPackage = plugin.getComponentId2(); + } + if (installedPackage != null) { + intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + Uri uri = Uri.fromParts("package", installedPackage, null); + intent.setData(uri); + } + } + return intent; + } + + public static void showInstance(@NonNull FragmentManager fm, String pluginId, Boolean usedOnMap) { + try { + Bundle args = new Bundle(); + args.putString(PLUGIN_ID_KEY, pluginId); + + PluginDisabledBottomSheet dialog = new PluginDisabledBottomSheet(); + dialog.setArguments(args); + dialog.setUsedOnMap(usedOnMap); + dialog.show(fm, PluginDisabledBottomSheet.TAG); + } catch (RuntimeException e) { + LOG.error("showInstance", e); + } + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/dialogs/PluginInstalledBottomSheetDialog.java b/OsmAnd/src/net/osmand/plus/dialogs/PluginInstalledBottomSheetDialog.java index 546b2c3dcd..aa8ad430a7 100644 --- a/OsmAnd/src/net/osmand/plus/dialogs/PluginInstalledBottomSheetDialog.java +++ b/OsmAnd/src/net/osmand/plus/dialogs/PluginInstalledBottomSheetDialog.java @@ -2,9 +2,11 @@ package net.osmand.plus.dialogs; import android.app.Activity; import android.content.Context; +import android.graphics.Typeface; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.v4.app.FragmentManager; +import android.text.SpannableString; import android.view.View; import android.widget.ImageView; import android.widget.LinearLayout; @@ -29,7 +31,9 @@ import net.osmand.plus.download.DownloadIndexesThread; import net.osmand.plus.download.DownloadValidationManager; import net.osmand.plus.download.IndexItem; import net.osmand.plus.helpers.AndroidUiHelper; +import net.osmand.plus.helpers.FontCache; import net.osmand.plus.settings.BaseSettingsFragment; +import net.osmand.plus.widgets.style.CustomTypefaceSpan; import org.apache.commons.logging.Log; @@ -79,8 +83,12 @@ public class PluginInstalledBottomSheetDialog extends MenuBottomSheetDialogFragm .create(); items.add(titleItem); + Typeface typeface = FontCache.getRobotoMedium(getContext()); + SpannableString pluginTitleSpan = new SpannableString(plugin.getName()); + pluginTitleSpan.setSpan(new CustomTypefaceSpan(typeface), 0, pluginTitleSpan.length(), 0); + BaseBottomSheetItem pluginTitle = new SimpleBottomSheetItem.Builder() - .setTitle(plugin.getName()) + .setTitle(pluginTitleSpan) .setTitleColorId(nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light) .setIcon(getContentIcon(R.drawable.ic_extension_dark)) .setLayoutId(R.layout.bottom_sheet_item_simple_56dp) diff --git a/OsmAnd/src/net/osmand/plus/srtmplugin/SRTMPlugin.java b/OsmAnd/src/net/osmand/plus/srtmplugin/SRTMPlugin.java index 219c0b5b0b..b733d3e94f 100644 --- a/OsmAnd/src/net/osmand/plus/srtmplugin/SRTMPlugin.java +++ b/OsmAnd/src/net/osmand/plus/srtmplugin/SRTMPlugin.java @@ -89,8 +89,8 @@ public class SRTMPlugin extends OsmandPlugin { } @Override - protected boolean checkPluginPackage(OsmandApplication app) { - return super.checkPluginPackage(app) || InAppPurchaseHelper.isSubscribedToLiveUpdates(app); + protected boolean pluginAvailable(OsmandApplication app) { + return super.pluginAvailable(app) || InAppPurchaseHelper.isSubscribedToLiveUpdates(app); } @Override