summaryrefslogtreecommitdiff
path: root/navit/android
diff options
context:
space:
mode:
authormvglasow <michael -at- vonglasow.com>2016-01-19 17:02:07 +0100
committermvglasow <michael -at- vonglasow.com>2016-02-02 09:58:31 +0100
commit2309b377da6e89f1fc35bef42577b8de7a80ef85 (patch)
treeb06de7bb910ea65c530e6df45bf72787a7958c87 /navit/android
parent97e493aaacf25e4a56cb9c8dae8b4e90615ca2c9 (diff)
downloadnavit-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.java46
-rw-r--r--navit/android/src/org/navitproject/navit/NavitGraphics.java86
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;