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();
}