From 6d07c70933639f15c9743487e632bb78dd326976 Mon Sep 17 00:00:00 2001 From: Zahnstocher Date: Wed, 5 Nov 2014 01:09:59 +0100 Subject: [PATCH] lockNow for turn on screen feature --- OsmAnd/AndroidManifest.xml | 15 ++++- OsmAnd/res/values/strings.xml | 2 + OsmAnd/res/xml/device_admin.xml | 6 ++ OsmAnd/res/xml/navigation_settings.xml | 5 +- .../src/net/osmand/plus/DeviceAdminRecv.java | 24 +++++++ .../src/net/osmand/plus/OsmandSettings.java | 12 +++- .../osmand/plus/activities/MapActivity.java | 53 ++++++++++------ .../SettingsNavigationActivity.java | 62 ++++++++++++++++++- .../net/osmand/plus/routing/VoiceRouter.java | 4 +- 9 files changed, 156 insertions(+), 27 deletions(-) create mode 100644 OsmAnd/res/xml/device_admin.xml create mode 100644 OsmAnd/src/net/osmand/plus/DeviceAdminRecv.java diff --git a/OsmAnd/AndroidManifest.xml b/OsmAnd/AndroidManifest.xml index 6041398f06..4f5dcf9ba1 100644 --- a/OsmAnd/AndroidManifest.xml +++ b/OsmAnd/AndroidManifest.xml @@ -10,7 +10,6 @@ - @@ -238,5 +237,19 @@ + + + + + + + + + diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 4b9bc5e9e6..d96157e66b 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -9,8 +9,10 @@ 3. All your modified/created strings are in the top of the file (to make easier find what\'s translated). PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy --> + %1$s needs this permission to turn off the screen for the power saving feature. Turn on the screen Turn on the phone screen when approaching a turn + Never Select on map Avoid roads… Tram and train diff --git a/OsmAnd/res/xml/device_admin.xml b/OsmAnd/res/xml/device_admin.xml new file mode 100644 index 0000000000..817e7a3a9b --- /dev/null +++ b/OsmAnd/res/xml/device_admin.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/OsmAnd/res/xml/navigation_settings.xml b/OsmAnd/res/xml/navigation_settings.xml index 08944b4d2c..2ce38780c0 100644 --- a/OsmAnd/res/xml/navigation_settings.xml +++ b/OsmAnd/res/xml/navigation_settings.xml @@ -28,6 +28,9 @@ android:title="@string/speed_limit_exceed" android:summary="@string/speed_limit_exceed_message"/> - + diff --git a/OsmAnd/src/net/osmand/plus/DeviceAdminRecv.java b/OsmAnd/src/net/osmand/plus/DeviceAdminRecv.java new file mode 100644 index 0000000000..97387c9c85 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/DeviceAdminRecv.java @@ -0,0 +1,24 @@ +package net.osmand.plus; + +import android.app.admin.DeviceAdminReceiver; +import android.content.Context; +import android.content.Intent; +import android.util.Log; + +public class DeviceAdminRecv extends DeviceAdminReceiver { + + private static final String TAG = "DeviceAdminReceiver"; + + public void onEnabled(Context context, Intent intent) { + Log.d(TAG, "permission disabled"); + } + + public CharSequence onDisableRequested(Context context, Intent intent) { + return null; + } + + public void onDisabled(Context context, Intent intent) { + Log.d(TAG, "permission enabled"); + } + +} diff --git a/OsmAnd/src/net/osmand/plus/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/OsmandSettings.java index ea25e90e19..caa674e210 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/OsmandSettings.java @@ -929,6 +929,15 @@ public class OsmandSettings { KEEP_INFORMING.setModeDefaultValue(ApplicationMode.BICYCLE, 0); KEEP_INFORMING.setModeDefaultValue(ApplicationMode.PEDESTRIAN, 0); } + + // screen power save + public final CommonPreference WAKE_ON_VOICE = new IntPreference("wake_on_voice", 0).makeProfile(); + { + // 0 means never + WAKE_ON_VOICE.setModeDefaultValue(ApplicationMode.CAR, 0); + WAKE_ON_VOICE.setModeDefaultValue(ApplicationMode.BICYCLE, 0); + WAKE_ON_VOICE.setModeDefaultValue(ApplicationMode.PEDESTRIAN, 0); + } // this value string is synchronized with settings_pref.xml preference name // try without AUTO_FOLLOW_ROUTE_NAV (see forum discussion 'Simplify our navigation preference menu') @@ -988,9 +997,6 @@ public class OsmandSettings { public CommonPreference PREVIOUS_INSTALLED_VERSION = new StringPreference("previous_installed_version", "").makeGlobal(); - public CommonPreference WAKE_ON_VOICE = new BooleanPreference("wake_on_voice", true).makeGlobal(); - - public ITileSource getMapTileSource(boolean warnWhenSelected) { String tileName = MAP_TILE_SOURCES.get(); if (tileName != null) { diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java index f41b510533..92e4b4d602 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java @@ -22,6 +22,7 @@ import net.osmand.map.MapTileDownloader.DownloadRequest; import net.osmand.map.MapTileDownloader.IMapDownloaderCallback; import net.osmand.plus.ApplicationMode; import net.osmand.plus.BusyIndicator; +import net.osmand.plus.DeviceAdminRecv; import net.osmand.plus.OsmAndConstants; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; @@ -49,11 +50,12 @@ import net.osmand.plus.views.corenative.NativeQtLibrary; import net.osmand.render.RenderingRulesStorage; import net.osmand.util.Algorithms; import android.app.Dialog; -import android.app.KeyguardManager; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.ProgressDialog; +import android.app.admin.DevicePolicyManager; +import android.content.ComponentName; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; @@ -84,7 +86,6 @@ public class MapActivity extends AccessibleActivity implements private static final int SHOW_POSITION_MSG_ID = OsmAndConstants.UI_HANDLER_MAP_VIEW + 1; private static final int LONG_KEYPRESS_MSG_ID = OsmAndConstants.UI_HANDLER_MAP_VIEW + 2; private static final int LONG_KEYPRESS_DELAY = 500; - private static final int WAKE_ON_VOICE_INTERVAL = 10000; // 10 seconds private static MapViewTrackingUtilities mapViewTrackingUtilities; @@ -113,10 +114,12 @@ public class MapActivity extends AccessibleActivity implements private FrameLayout lockView; private GpxImportHelper gpxImportHelper; private PowerManager.WakeLock wakeLock = null; - private KeyguardManager.KeyguardLock keyguardLock = null; private ReleaseWakeLocksRunnable releaseWakeLocksRunnable = new ReleaseWakeLocksRunnable(); private boolean active = false; + private DevicePolicyManager mDevicePolicyManager; + private ComponentName mDeviceAdmin; + private Notification getNotification() { Intent notificationIndent = new Intent(this, getMyApplication().getAppCustomization().getMapActivity()); notificationIndent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); @@ -222,6 +225,9 @@ public class MapActivity extends AccessibleActivity implements gpxImportHelper = new GpxImportHelper(this, getMyApplication(), getMapView()); mapActions.prepareStartOptionsMenu(); + + mDeviceAdmin = new ComponentName(getApplicationContext(), DeviceAdminRecv.class); + mDevicePolicyManager = (DevicePolicyManager) getSystemService(DEVICE_POLICY_SERVICE); } public void addLockView(FrameLayout lockView) { @@ -292,7 +298,7 @@ public class MapActivity extends AccessibleActivity implements @Override protected void onResume() { super.onResume(); - if ((wakeLock != null) || (keyguardLock != null)) { + if (wakeLock != null) { return; } cancelNotification(); @@ -541,7 +547,7 @@ public class MapActivity extends AccessibleActivity implements protected void onStart() { super.onStart(); active = true; - if ((wakeLock == null) || (keyguardLock == null)) { + if (wakeLock == null) { VoiceRouter voiceRouter = app.getRoutingHelper().getVoiceRouter(); voiceRouter.removeVoiceMessageListener(this); } @@ -567,7 +573,7 @@ public class MapActivity extends AccessibleActivity implements progressDlg.dismiss(); progressDlg = null; } - if (!isFinishing() && settings.WAKE_ON_VOICE.get()) { + if (!isFinishing() && (settings.WAKE_ON_VOICE.get() > 0)) { VoiceRouter voiceRouter = app.getRoutingHelper().getVoiceRouter(); voiceRouter.addVoiceMessageListener(this); } @@ -788,36 +794,45 @@ public class MapActivity extends AccessibleActivity implements @Override public void onVoiceMessage() { - if (settings.WAKE_ON_VOICE.get()) { + final Integer screenPowerSave = settings.WAKE_ON_VOICE.get(); + if (screenPowerSave > 0) { uiHandler.removeCallbacks(releaseWakeLocksRunnable); - if (!active && (wakeLock == null)) { + if (!active && wakeLock == null) { PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE); wakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "OsmAndOnVoiceWakeupTag"); wakeLock.acquire(); - - if (keyguardLock == null) { - KeyguardManager km = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE); - keyguardLock = km.newKeyguardLock("OsmAndKeyguardLock"); - keyguardLock.disableKeyguard(); - } } - uiHandler.postDelayed(releaseWakeLocksRunnable, WAKE_ON_VOICE_INTERVAL); + uiHandler.postDelayed(releaseWakeLocksRunnable, + screenPowerSave * 1000L); } } private void releaseWakeLocks() { - if (keyguardLock != null) { - keyguardLock.reenableKeyguard(); - keyguardLock = null; - } if (wakeLock != null) { wakeLock.release(); wakeLock = null; } + + if (mDevicePolicyManager != null && mDeviceAdmin != null) { + final Integer screenPowerSave = settings.WAKE_ON_VOICE.get(); + if (screenPowerSave > 0) { + if (mDevicePolicyManager.isAdminActive(mDeviceAdmin)) { + try { + mDevicePolicyManager.lockNow(); + } catch (SecurityException e) { +// Log.d(TAG, +// "SecurityException: No device admin permission to lock the screen!"); + } + } else { +// Log.d(TAG, +// "No device admin permission to lock the screen!"); + } + } + } } private class ReleaseWakeLocksRunnable implements Runnable { diff --git a/OsmAnd/src/net/osmand/plus/activities/SettingsNavigationActivity.java b/OsmAnd/src/net/osmand/plus/activities/SettingsNavigationActivity.java index a081091e82..e65b1de4df 100644 --- a/OsmAnd/src/net/osmand/plus/activities/SettingsNavigationActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/SettingsNavigationActivity.java @@ -6,18 +6,23 @@ import java.util.List; import java.util.Map; import net.osmand.plus.ApplicationMode; +import net.osmand.plus.DeviceAdminRecv; import net.osmand.plus.OsmandSettings; import net.osmand.plus.OsmandSettings.AutoZoomMap; import net.osmand.plus.OsmandSettings.OsmandPreference; import net.osmand.plus.R; +import net.osmand.plus.Version; import net.osmand.plus.routing.RouteProvider.RouteService; import net.osmand.router.GeneralRouter; import net.osmand.router.GeneralRouter.RoutingParameter; import net.osmand.router.GeneralRouter.RoutingParameterType; import android.app.AlertDialog; import android.app.AlertDialog.Builder; +import android.app.admin.DevicePolicyManager; +import android.content.ComponentName; import android.content.DialogInterface; import android.content.DialogInterface.OnMultiChoiceClickListener; +import android.content.Intent; import android.os.Bundle; import android.preference.CheckBoxPreference; import android.preference.ListPreference; @@ -35,6 +40,8 @@ public class SettingsNavigationActivity extends SettingsBaseActivity { private ListPreference autoZoomMapPreference; private ListPreference speedLimitExceed; + private ComponentName mDeviceAdmin; + private static final int DEVICE_ADMIN_REQUEST = 5; private List avoidParameters = new ArrayList(); private List preferParameters = new ArrayList(); @@ -51,6 +58,40 @@ public class SettingsNavigationActivity extends SettingsBaseActivity { createUI(); } + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (requestCode == DEVICE_ADMIN_REQUEST) { + if (resultCode == RESULT_OK) { +// Log.d("DeviceAdmin", "Lock screen permission approved."); + } else { + settings.WAKE_ON_VOICE.set(0); +// Log.d("DeviceAdmin", "Lock screen permission refused."); + } + return; + } + } + + private void requestLockScreenAdmin() { + mDeviceAdmin = new ComponentName(getApplicationContext(), + DeviceAdminRecv.class); + + DevicePolicyManager mDevicePolicyManager = (DevicePolicyManager) getSystemService(DEVICE_POLICY_SERVICE); + + if (!mDevicePolicyManager.isAdminActive(mDeviceAdmin)) { + // request permission from user + Intent intent = new Intent( + DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN); + intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, + mDeviceAdmin); + intent.putExtra( + DevicePolicyManager.EXTRA_ADD_EXPLANATION, + getString(R.string.lock_screen_request_explanation, + Version.getAppName(getMyApplication()))); + startActivityForResult(intent, DEVICE_ADMIN_REQUEST); + } + }; + private void createUI() { addPreferencesFromResource(R.xml.navigation_settings); PreferenceScreen screen = getPreferenceScreen(); @@ -91,8 +132,17 @@ public class SettingsNavigationActivity extends SettingsBaseActivity { } registerListPreference(settings.KEEP_INFORMING, screen, keepInformingNames, keepInformingValues); + // screen power save option: + Integer[] screenPowerSaveValues = new Integer[] { 0, 5, 10, 15, 20, 30, 45, 60 }; + String[] screenPowerSaveNames = new String[screenPowerSaveValues.length]; + screenPowerSaveNames[0] = getString(R.string.wake_on_voice_never); + for (int i = 1; i < screenPowerSaveValues.length; i++) { + screenPowerSaveNames[i] = screenPowerSaveValues[i] + " " + + getString(R.string.int_seconds); + } + registerListPreference(settings.WAKE_ON_VOICE, screen, screenPowerSaveNames, screenPowerSaveValues); + registerBooleanPreference(settings.SHOW_ZOOM_BUTTONS_NAVIGATION, screen); - registerBooleanPreference(settings.WAKE_ON_VOICE, screen); autoZoomMapPreference = (ListPreference) screen.findPreference(settings.AUTO_ZOOM_MAP.getId()); autoZoomMapPreference.setOnPreferenceChangeListener(this); @@ -248,6 +298,16 @@ public class SettingsNavigationActivity extends SettingsBaseActivity { + settings.ROUTER_SERVICE.get() + "]"); prepareRoutingPrefs(getPreferenceScreen()); super.updateAllSettings(); + } else if (id.equals(settings.WAKE_ON_VOICE.getId())) { + Integer value; + try { + value = Integer.parseInt(newValue.toString()); + } catch (NumberFormatException e) { + value = 0; + } + if (value > 0) { + requestLockScreenAdmin(); + } } return true; } diff --git a/OsmAnd/src/net/osmand/plus/routing/VoiceRouter.java b/OsmAnd/src/net/osmand/plus/routing/VoiceRouter.java index a78f0ae57b..6b6e14143e 100644 --- a/OsmAnd/src/net/osmand/plus/routing/VoiceRouter.java +++ b/OsmAnd/src/net/osmand/plus/routing/VoiceRouter.java @@ -871,11 +871,11 @@ public class VoiceRouter { for (final VoiceMessageListener voiceMessageListener : voiceMessageListeners) { Runnable closure = new Runnable() { public void run() { - if (settings.WAKE_ON_VOICE.get()) { + if (settings.WAKE_ON_VOICE.get() > 0) { synchronized (voiceMessageListeners) { if (voiceMessageListeners .contains(voiceMessageListener) - && settings.WAKE_ON_VOICE.get()) { + && (settings.WAKE_ON_VOICE.get() > 0)) { voiceMessageListener .onVoiceMessage(); }