diff options
author | mvglasow <michael -at- vonglasow.com> | 2016-01-19 17:02:07 +0100 |
---|---|---|
committer | mvglasow <michael -at- vonglasow.com> | 2016-02-02 09:58:31 +0100 |
commit | 2309b377da6e89f1fc35bef42577b8de7a80ef85 (patch) | |
tree | b06de7bb910ea65c530e6df45bf72787a7958c87 /navit/android | |
parent | 97e493aaacf25e4a56cb9c8dae8b4e90615ca2c9 (diff) | |
download | navit-2309b377da6e89f1fc35bef42577b8de7a80ef85.tar.gz |
Add:graphics_android:Implement padding for areas obstructed by system UI
Signed-off-by: mvglasow <michael -at- vonglasow.com>
Diffstat (limited to 'navit/android')
-rw-r--r-- | navit/android/src/org/navitproject/navit/Navit.java | 46 | ||||
-rw-r--r-- | navit/android/src/org/navitproject/navit/NavitGraphics.java | 86 |
2 files changed, 125 insertions, 7 deletions
diff --git a/navit/android/src/org/navitproject/navit/Navit.java b/navit/android/src/org/navitproject/navit/Navit.java index d33425a76..920b79a98 100644 --- a/navit/android/src/org/navitproject/navit/Navit.java +++ b/navit/android/src/org/navitproject/navit/Navit.java @@ -34,6 +34,7 @@ import java.util.Map; import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import android.annotation.TargetApi;
import android.app.Activity;
import android.app.ActivityManager.TaskDescription;
import android.app.AlertDialog;
@@ -48,12 +49,15 @@ import android.content.SharedPreferences; import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
+import android.graphics.Point;
import android.media.AudioManager;
import android.net.Uri;
+import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Message;
@@ -83,6 +87,11 @@ public class Navit extends Activity private NavitActivityResult ActivityResults[];
public static InputMethodManager mgr = null;
public static DisplayMetrics metrics = null;
+ public static int status_bar_height = 0;
+ public static int action_bar_default_height = 0;
+ public static int navigation_bar_height = 0;
+ public static int navigation_bar_height_landscape= 0;
+ public static int navigation_bar_width = 0;
public static Boolean show_soft_keyboard = false;
public static Boolean show_soft_keyboard_now_showing = false;
public static long last_pressed_menu_key = 0L;
@@ -105,6 +114,7 @@ public class Navit extends Activity static final String NAVIT_DATA_SHARE_DIR = NAVIT_DATA_DIR + "/share";
static final String FIRST_STARTUP_FILE = NAVIT_DATA_SHARE_DIR + "/has_run_once.txt";
public static final String NAVIT_PREFS = "NavitPrefs";
+ Boolean isFullscreen = false;
public void removeFileIfExists(String source) {
File file = new File(source);
@@ -281,6 +291,23 @@ public class Navit extends Activity NavitNotification.flags|=Notification.FLAG_ONGOING_EVENT; // Ensure that the notification appears in Ongoing
nm.notify(R.string.app_name, NavitNotification); // Set the notification
+ // Status and navigation bar sizes
+ // These are platform defaults and do not change with rotation, but we have to figure out which ones apply
+ // (is the navigation bar visible? on the side or at the bottom?)
+ Resources resources = getResources();
+ int shid = resources.getIdentifier("status_bar_height", "dimen", "android");
+ int adhid = resources.getIdentifier("action_bar_default_height", "dimen", "android");
+ int nhid = resources.getIdentifier("navigation_bar_height", "dimen", "android");
+ int nhlid = resources.getIdentifier("navigation_bar_height_landscape", "dimen", "android");
+ int nwid = resources.getIdentifier("navigation_bar_width", "dimen", "android");
+ status_bar_height = (shid > 0) ? resources.getDimensionPixelSize(shid) : 0;
+ action_bar_default_height = (adhid > 0) ? resources.getDimensionPixelSize(adhid) : 0;
+ navigation_bar_height = (nhid > 0) ? resources.getDimensionPixelSize(nhid) : 0;
+ navigation_bar_height_landscape = (nhid > 0) ? resources.getDimensionPixelSize(nhlid) : 0;
+ navigation_bar_width = (nwid > 0) ? resources.getDimensionPixelSize(nwid) : 0;
+ Log.d(TAG, String.format("status_bar_height=%d, action_bar_default_height=%d, navigation_bar_height=%d, navigation_bar_height_landscape=%d, navigation_bar_width=%d",
+ status_bar_height, action_bar_default_height, navigation_bar_height, navigation_bar_height_landscape, navigation_bar_width));
+
// get the local language -------------
Locale locale = java.util.Locale.getDefault();
String lang = locale.getLanguage();
@@ -607,6 +634,7 @@ public class Navit extends Activity }
}
+
/**
* @brief Shows the Options menu.
*
@@ -717,7 +745,10 @@ public class Navit extends Activity }
public void fullscreen(int fullscreen) {
- if(fullscreen != 0) {
+ int w, h;
+
+ isFullscreen = (fullscreen != 0);
+ if (isFullscreen) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
}
@@ -725,6 +756,19 @@ public class Navit extends Activity getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
+
+ Display display_ = getWindowManager().getDefaultDisplay();
+ if (Build.VERSION.SDK_INT < 17) {
+ w = display_.getWidth();
+ h = display_.getHeight();
+ } else {
+ Point size = new Point();
+ display_.getRealSize(size);
+ w = size.x;
+ h = size.y;
+ }
+ Log.d(TAG, String.format("Toggle fullscreen, w=%d, h=%d", w, h));
+ N_NavitGraphics.handleResize(w, h);
}
public void disableSuspend()
diff --git a/navit/android/src/org/navitproject/navit/NavitGraphics.java b/navit/android/src/org/navitproject/navit/NavitGraphics.java index 08f4fbe3e..a0bdafed2 100644 --- a/navit/android/src/org/navitproject/navit/NavitGraphics.java +++ b/navit/android/src/org/navitproject/navit/NavitGraphics.java @@ -25,6 +25,8 @@ import java.util.ArrayList; import android.app.Activity; import android.content.Context; +import android.content.res.Configuration; +import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Matrix; @@ -199,11 +201,8 @@ public class NavitGraphics Log.e("Navit", "NavitGraphics -> onSizeChanged scaledDensity=" + Navit.metrics.scaledDensity); super.onSizeChanged(w, h, oldw, oldh); - draw_bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); - draw_canvas = new Canvas(draw_bitmap); - bitmap_w = w; - bitmap_h = h; - SizeChangedCallback(SizeChangedCallbackID, w, h); + + handleResize(w, h); } public void do_longpress_action() @@ -783,6 +782,7 @@ public class NavitGraphics }; public native void SizeChangedCallback(int id, int x, int y); + public native void PaddingChangedCallback(int id, int left, int right, int top, int bottom); public native void KeypressCallback(int id, String s); public native int CallbackMessageChannel(int i, String s); public native void ButtonCallback(int id, int pressed, int button, int x, int y); @@ -791,8 +791,74 @@ public class NavitGraphics public static native String[][] GetAllCountries(); private Canvas draw_canvas; private Bitmap draw_bitmap; - private int SizeChangedCallbackID, ButtonCallbackID, MotionCallbackID, KeypressCallbackID; + private int SizeChangedCallbackID, PaddingChangedCallbackID, ButtonCallbackID, MotionCallbackID, KeypressCallbackID; // private int count; + + /** + * @brief Handles resize events. + * + * This method is called whenever the main View is resized in any way. This is the case when its + * {@code onSizeChanged()} event handler fires or when toggling Fullscreen mode. + * + * It (re-)evaluates if and where the navigation bar is going to be shown, and calculates the + * padding for objects which should not be obstructed. + */ + public void handleResize(int w, int h) { + if (this.parent_graphics != null) + this.parent_graphics.handleResize(w, h); + else { + Log.d("NavitGraphics", String.format("handleResize w=%d h=%d", w, h)); + /* + * The code would work on API14+ but is meaningful only on API17+ + */ + if (Build.VERSION.SDK_INT >= 17) { + Navit navit = null; + if (activity instanceof Navit) { + navit = (Navit) activity; + /* + * Determine visibility of status bar. + * The status bar is always visible unless we are in fullscreen mode. + */ + Boolean isStatusShowing = !navit.isFullscreen; + + /* + * Determine visibility of navigation bar. + * This logic is based on the presence of a hardware menu button and is known to work on + * devices which allow switching between hw and sw buttons (OnePlus One running CyanogenMod). + */ + Boolean isNavShowing = !ViewConfiguration.get(navit.getApplication()).hasPermanentMenuKey(); + + Log.d("NavitGraphics", String.format("isStatusShowing=%b isNavShowing=%b", isStatusShowing, isNavShowing)); + + /* + * Determine where the navigation bar would be displayed. + * Logic is taken from AOSP RenderSessionImpl.findNavigationBar() + * (platform/frameworks/base/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java) + */ + Boolean isLandscape = (navit.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE); + Boolean isNavAtBottom = (!isLandscape) || (navit.getResources().getConfiguration().smallestScreenWidthDp >= 600); + Log.d("NavitGraphics", String.format("isNavAtBottom=%b (Configuration.smallestScreenWidthDp=%d, isLandscape=%b)", + isNavAtBottom, navit.getResources().getConfiguration().smallestScreenWidthDp, isLandscape)); + + int left = 0; + int top = isStatusShowing ? Navit.status_bar_height : 0; + int right = (isNavShowing && !isNavAtBottom) ? Navit.navigation_bar_width : 0; + int bottom = (!(isNavShowing && isNavAtBottom)) ? 0 : isLandscape ? Navit.navigation_bar_height_landscape : Navit.navigation_bar_height; + + Log.d("NavitGraphics", String.format("Padding left=%d top=%d right=%d bottom=%d", left, top, right, bottom)); + + PaddingChangedCallback(PaddingChangedCallbackID, left, top, right, bottom); + } else + Log.e("NavitGraphics", "Main Activity is not a Navit instance, cannot update padding"); + } + + draw_bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); + draw_canvas = new Canvas(draw_bitmap); + bitmap_w = w; + bitmap_h = h; + SizeChangedCallback(SizeChangedCallbackID, w, h); + } + } /** * @brief Returns whether the device has a hardware menu button. @@ -802,6 +868,10 @@ public class NavitGraphics * this method will always return {@code true}, as these Android versions relied on devices having a physical * Menu button. On API levels 11 through 13 (Honeycomb releases), this method will always return * {@code false}, as Honeycomb was a tablet-only release and did not require devices to have a Menu button. + * + * Note that this method is not aware of non-standard mechanisms on some customized builds of Android. For + * example, CyanogenMod has an option to add a menu button to the navigation bar. Even with that option, + * this method will still return `false`. */ public boolean hasMenuButton() { if (Build.VERSION.SDK_INT <= 10) @@ -816,6 +886,10 @@ public class NavitGraphics { SizeChangedCallbackID = id; } + public void setPaddingChangedCallback(int id) + { + PaddingChangedCallbackID = id; + } public void setButtonCallback(int id) { ButtonCallbackID = id; |