Android 6.0 permissions handling for location and Audio-Video notes plugin
This commit is contained in:
parent
233cec7962
commit
8ca050b01b
6 changed files with 196 additions and 84 deletions
|
@ -25,5 +25,7 @@
|
||||||
<string name="tag_poi_name">name</string>
|
<string name="tag_poi_name">name</string>
|
||||||
<string name="hint_tag">Tag</string>
|
<string name="hint_tag">Tag</string>
|
||||||
<string name="hint_value">Value</string>
|
<string name="hint_value">Value</string>
|
||||||
|
<string name="no_location_permission">App have no permission to access location data.</string>
|
||||||
|
<string name="no_camera_permission">App have no permission to access camera.</string>
|
||||||
|
<string name="no_microphone_permission">App have no permission to access microphone.</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
package net.osmand.plus;
|
package net.osmand.plus;
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.hardware.GeomagneticField;
|
import android.hardware.GeomagneticField;
|
||||||
import android.hardware.Sensor;
|
import android.hardware.Sensor;
|
||||||
import android.hardware.SensorEvent;
|
import android.hardware.SensorEvent;
|
||||||
|
@ -17,8 +19,11 @@ import android.location.LocationManager;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
|
import android.support.v4.app.ActivityCompat;
|
||||||
import android.support.v7.app.AlertDialog;
|
import android.support.v7.app.AlertDialog;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import net.osmand.GeoidAltitudeCorrection;
|
import net.osmand.GeoidAltitudeCorrection;
|
||||||
import net.osmand.PlatformUtil;
|
import net.osmand.PlatformUtil;
|
||||||
import net.osmand.ResultMatcher;
|
import net.osmand.ResultMatcher;
|
||||||
|
@ -40,7 +45,9 @@ import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class OsmAndLocationProvider implements SensorEventListener {
|
public class OsmAndLocationProvider implements SensorEventListener {
|
||||||
|
|
||||||
|
public static final int REQUEST_LOCATION_PERMISSION = 100;
|
||||||
|
|
||||||
private static final String SIMULATED_PROVIDER = "OsmAnd";
|
private static final String SIMULATED_PROVIDER = "OsmAnd";
|
||||||
|
|
||||||
|
|
||||||
|
@ -76,7 +83,7 @@ public class OsmAndLocationProvider implements SensorEventListener {
|
||||||
|
|
||||||
private static final boolean USE_KALMAN_FILTER = true;
|
private static final boolean USE_KALMAN_FILTER = true;
|
||||||
private static final float KALMAN_COEFFICIENT = 0.04f;
|
private static final float KALMAN_COEFFICIENT = 0.04f;
|
||||||
|
|
||||||
float avgValSin = 0;
|
float avgValSin = 0;
|
||||||
float avgValCos = 0;
|
float avgValCos = 0;
|
||||||
float lastValSin = 0;
|
float lastValSin = 0;
|
||||||
|
@ -86,7 +93,7 @@ public class OsmAndLocationProvider implements SensorEventListener {
|
||||||
private int previousCompassIndA = 0;
|
private int previousCompassIndA = 0;
|
||||||
private int previousCompassIndB = 0;
|
private int previousCompassIndB = 0;
|
||||||
private boolean inUpdateValue = false;
|
private boolean inUpdateValue = false;
|
||||||
|
|
||||||
private Float heading = null;
|
private Float heading = null;
|
||||||
|
|
||||||
// Current screen orientation
|
// Current screen orientation
|
||||||
|
@ -94,22 +101,22 @@ public class OsmAndLocationProvider implements SensorEventListener {
|
||||||
|
|
||||||
private OsmandApplication app;
|
private OsmandApplication app;
|
||||||
private OsmandSettings settings;
|
private OsmandSettings settings;
|
||||||
|
|
||||||
private NavigationInfo navigationInfo;
|
private NavigationInfo navigationInfo;
|
||||||
private CurrentPositionHelper currentPositionHelper;
|
private CurrentPositionHelper currentPositionHelper;
|
||||||
private OsmAndLocationSimulation locationSimulation;
|
private OsmAndLocationSimulation locationSimulation;
|
||||||
|
|
||||||
private net.osmand.Location location = null;
|
private net.osmand.Location location = null;
|
||||||
|
|
||||||
private GPSInfo gpsInfo = new GPSInfo();
|
private GPSInfo gpsInfo = new GPSInfo();
|
||||||
|
|
||||||
private List<OsmAndLocationListener> locationListeners = new ArrayList<OsmAndLocationProvider.OsmAndLocationListener>();
|
private List<OsmAndLocationListener> locationListeners = new ArrayList<OsmAndLocationProvider.OsmAndLocationListener>();
|
||||||
private List<OsmAndCompassListener> compassListeners = new ArrayList<OsmAndLocationProvider.OsmAndCompassListener>();
|
private List<OsmAndCompassListener> compassListeners = new ArrayList<OsmAndLocationProvider.OsmAndCompassListener>();
|
||||||
private Listener gpsStatusListener;
|
private Listener gpsStatusListener;
|
||||||
private float[] mRotationM = new float[9];
|
private float[] mRotationM = new float[9];
|
||||||
private OsmandPreference<Boolean> USE_MAGNETIC_FIELD_SENSOR_COMPASS;
|
private OsmandPreference<Boolean> USE_MAGNETIC_FIELD_SENSOR_COMPASS;
|
||||||
private OsmandPreference<Boolean> USE_FILTER_FOR_COMPASS;
|
private OsmandPreference<Boolean> USE_FILTER_FOR_COMPASS;
|
||||||
private static final long AGPS_TO_REDOWNLOAD = 16 * 60 * 60 * 1000; // 16 hours
|
private static final long AGPS_TO_REDOWNLOAD = 16 * 60 * 60 * 1000; // 16 hours
|
||||||
|
|
||||||
|
|
||||||
public class SimulationProvider {
|
public class SimulationProvider {
|
||||||
|
@ -118,14 +125,14 @@ public class OsmAndLocationProvider implements SensorEventListener {
|
||||||
private QuadPoint currentPoint;
|
private QuadPoint currentPoint;
|
||||||
private net.osmand.Location startLocation;
|
private net.osmand.Location startLocation;
|
||||||
private List<RouteSegmentResult> roads;
|
private List<RouteSegmentResult> roads;
|
||||||
|
|
||||||
|
|
||||||
public void startSimulation(List<RouteSegmentResult> roads,
|
public void startSimulation(List<RouteSegmentResult> roads,
|
||||||
net.osmand.Location currentLocation) {
|
net.osmand.Location currentLocation) {
|
||||||
this.roads = roads;
|
this.roads = roads;
|
||||||
startLocation = new net.osmand.Location(currentLocation);
|
startLocation = new net.osmand.Location(currentLocation);
|
||||||
long ms = System.currentTimeMillis();
|
long ms = System.currentTimeMillis();
|
||||||
if(ms - startLocation.getTime() > 5000 ||
|
if (ms - startLocation.getTime() > 5000 ||
|
||||||
ms < startLocation.getTime()) {
|
ms < startLocation.getTime()) {
|
||||||
startLocation.setTime(ms);
|
startLocation.setTime(ms);
|
||||||
}
|
}
|
||||||
|
@ -133,14 +140,14 @@ public class OsmAndLocationProvider implements SensorEventListener {
|
||||||
int px = MapUtils.get31TileNumberX(currentLocation.getLongitude());
|
int px = MapUtils.get31TileNumberX(currentLocation.getLongitude());
|
||||||
int py = MapUtils.get31TileNumberY(currentLocation.getLatitude());
|
int py = MapUtils.get31TileNumberY(currentLocation.getLatitude());
|
||||||
double dist = 1000;
|
double dist = 1000;
|
||||||
for(int i = 0; i < roads.size(); i++) {
|
for (int i = 0; i < roads.size(); i++) {
|
||||||
RouteSegmentResult road = roads.get(i);
|
RouteSegmentResult road = roads.get(i);
|
||||||
boolean plus = road.getStartPointIndex() < road.getEndPointIndex();
|
boolean plus = road.getStartPointIndex() < road.getEndPointIndex();
|
||||||
for(int j = road.getStartPointIndex() + 1; j <= road.getEndPointIndex(); ) {
|
for (int j = road.getStartPointIndex() + 1; j <= road.getEndPointIndex(); ) {
|
||||||
RouteDataObject obj = road.getObject();
|
RouteDataObject obj = road.getObject();
|
||||||
QuadPoint proj = MapUtils.getProjectionPoint31(px, py, obj.getPoint31XTile(j-1), obj.getPoint31YTile(j-1),
|
QuadPoint proj = MapUtils.getProjectionPoint31(px, py, obj.getPoint31XTile(j - 1), obj.getPoint31YTile(j - 1),
|
||||||
obj.getPoint31XTile(j), obj.getPoint31YTile(j));
|
obj.getPoint31XTile(j), obj.getPoint31YTile(j));
|
||||||
double dd = MapUtils.squareRootDist31((int)proj.x, (int)proj.y, px, py);
|
double dd = MapUtils.squareRootDist31((int) proj.x, (int) proj.y, px, py);
|
||||||
if (dd < dist) {
|
if (dd < dist) {
|
||||||
dist = dd;
|
dist = dd;
|
||||||
currentRoad = i;
|
currentRoad = i;
|
||||||
|
@ -151,26 +158,26 @@ public class OsmAndLocationProvider implements SensorEventListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private float proceedMeters(float meters, net.osmand.Location l) {
|
private float proceedMeters(float meters, net.osmand.Location l) {
|
||||||
for(int i = currentRoad; i < roads.size(); i++) {
|
for (int i = currentRoad; i < roads.size(); i++) {
|
||||||
RouteSegmentResult road = roads.get(i);
|
RouteSegmentResult road = roads.get(i);
|
||||||
boolean firstRoad = i == currentRoad;
|
boolean firstRoad = i == currentRoad;
|
||||||
boolean plus = road.getStartPointIndex() < road.getEndPointIndex();
|
boolean plus = road.getStartPointIndex() < road.getEndPointIndex();
|
||||||
for(int j = firstRoad ? currentSegment : road.getStartPointIndex() + 1; j <= road.getEndPointIndex(); ) {
|
for (int j = firstRoad ? currentSegment : road.getStartPointIndex() + 1; j <= road.getEndPointIndex(); ) {
|
||||||
RouteDataObject obj = road.getObject();
|
RouteDataObject obj = road.getObject();
|
||||||
int st31x = obj.getPoint31XTile(j-1);
|
int st31x = obj.getPoint31XTile(j - 1);
|
||||||
int st31y = obj.getPoint31YTile(j-1);
|
int st31y = obj.getPoint31YTile(j - 1);
|
||||||
int end31x = obj.getPoint31XTile(j);
|
int end31x = obj.getPoint31XTile(j);
|
||||||
int end31y = obj.getPoint31YTile(j);
|
int end31y = obj.getPoint31YTile(j);
|
||||||
boolean last = i == roads.size() - 1 && j == road.getEndPointIndex();
|
boolean last = i == roads.size() - 1 && j == road.getEndPointIndex();
|
||||||
boolean first = firstRoad && j == currentSegment;
|
boolean first = firstRoad && j == currentSegment;
|
||||||
if(first) {
|
if (first) {
|
||||||
st31x = (int) currentPoint.x;
|
st31x = (int) currentPoint.x;
|
||||||
st31y = (int) currentPoint.y;
|
st31y = (int) currentPoint.y;
|
||||||
}
|
}
|
||||||
double dd = MapUtils.measuredDist31(st31x, st31y, end31x, end31y);
|
double dd = MapUtils.measuredDist31(st31x, st31y, end31x, end31y);
|
||||||
if(meters > dd && !last){
|
if (meters > dd && !last) {
|
||||||
meters -= dd;
|
meters -= dd;
|
||||||
} else {
|
} else {
|
||||||
int prx = (int) (st31x + (end31x - st31x) * (meters / dd));
|
int prx = (int) (st31x + (end31x - st31x) * (meters / dd));
|
||||||
|
@ -184,32 +191,32 @@ public class OsmAndLocationProvider implements SensorEventListener {
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return null if it is not available of far from boundaries
|
* @return null if it is not available of far from boundaries
|
||||||
*/
|
*/
|
||||||
public net.osmand.Location getSimulatedLocation() {
|
public net.osmand.Location getSimulatedLocation() {
|
||||||
if(!isSimulatedDataAvailable()) {
|
if (!isSimulatedDataAvailable()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
net.osmand.Location loc = new net.osmand.Location(SIMULATED_PROVIDER);
|
net.osmand.Location loc = new net.osmand.Location(SIMULATED_PROVIDER);
|
||||||
loc.setSpeed(startLocation.getSpeed());
|
loc.setSpeed(startLocation.getSpeed());
|
||||||
loc.setAltitude(startLocation.getAltitude());
|
loc.setAltitude(startLocation.getAltitude());
|
||||||
loc.setTime(System.currentTimeMillis());
|
loc.setTime(System.currentTimeMillis());
|
||||||
float meters = startLocation.getSpeed() * ((System.currentTimeMillis() - startLocation.getTime()) / 1000);
|
float meters = startLocation.getSpeed() * ((System.currentTimeMillis() - startLocation.getTime()) / 1000);
|
||||||
float proc = proceedMeters(meters, loc);
|
float proc = proceedMeters(meters, loc);
|
||||||
if(proc < 0 || proc >= 100){
|
if (proc < 0 || proc >= 100) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return loc;
|
return loc;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSimulatedDataAvailable() {
|
public boolean isSimulatedDataAvailable() {
|
||||||
return startLocation != null && startLocation.getSpeed() > 0 && currentRoad >= 0;
|
return startLocation != null && startLocation.getSpeed() > 0 && currentRoad >= 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public OsmAndLocationProvider(OsmandApplication app) {
|
public OsmAndLocationProvider(OsmandApplication app) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
navigationInfo = new NavigationInfo(app);
|
navigationInfo = new NavigationInfo(app);
|
||||||
|
@ -219,39 +226,41 @@ public class OsmAndLocationProvider implements SensorEventListener {
|
||||||
currentPositionHelper = new CurrentPositionHelper(app);
|
currentPositionHelper = new CurrentPositionHelper(app);
|
||||||
locationSimulation = new OsmAndLocationSimulation(app, this);
|
locationSimulation = new OsmAndLocationSimulation(app, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resumeAllUpdates() {
|
public void resumeAllUpdates() {
|
||||||
final LocationManager service = (LocationManager) app.getSystemService(Context.LOCATION_SERVICE);
|
final LocationManager service = (LocationManager) app.getSystemService(Context.LOCATION_SERVICE);
|
||||||
if(app.getSettings().isInternetConnectionAvailable()) {
|
if (app.getSettings().isInternetConnectionAvailable()) {
|
||||||
if(System.currentTimeMillis() - app.getSettings().AGPS_DATA_LAST_TIME_DOWNLOADED.get() > AGPS_TO_REDOWNLOAD) {
|
if (System.currentTimeMillis() - app.getSettings().AGPS_DATA_LAST_TIME_DOWNLOADED.get() > AGPS_TO_REDOWNLOAD) {
|
||||||
//force an updated check for internet connectivity here before destroying A-GPS-data
|
//force an updated check for internet connectivity here before destroying A-GPS-data
|
||||||
if(app.getSettings().isInternetConnectionAvailable(true)) {
|
if (app.getSettings().isInternetConnectionAvailable(true)) {
|
||||||
redownloadAGPS();
|
redownloadAGPS();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
service.addGpsStatusListener(getGpsStatusListener(service));
|
if (isLocationPermissionAvailable(app)) {
|
||||||
try {
|
service.addGpsStatusListener(getGpsStatusListener(service));
|
||||||
service.requestLocationUpdates(LocationManager.GPS_PROVIDER, GPS_TIMEOUT_REQUEST, GPS_DIST_REQUEST, gpsListener);
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
Log.d(PlatformUtil.TAG, "GPS location provider not available"); //$NON-NLS-1$
|
|
||||||
}
|
|
||||||
// try to always ask for network provide : it is faster way to find location
|
|
||||||
|
|
||||||
List<String> providers = service.getProviders(true);
|
|
||||||
if(providers == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (String provider : providers) {
|
|
||||||
if (provider == null || provider.equals(LocationManager.GPS_PROVIDER)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
NetworkListener networkListener = new NetworkListener();
|
service.requestLocationUpdates(LocationManager.GPS_PROVIDER, GPS_TIMEOUT_REQUEST, GPS_DIST_REQUEST, gpsListener);
|
||||||
service.requestLocationUpdates(provider, GPS_TIMEOUT_REQUEST, GPS_DIST_REQUEST, networkListener);
|
|
||||||
networkListeners.add(networkListener);
|
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
Log.d(PlatformUtil.TAG, provider + " location provider not available"); //$NON-NLS-1$
|
Log.d(PlatformUtil.TAG, "GPS location provider not available"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
// try to always ask for network provide : it is faster way to find location
|
||||||
|
|
||||||
|
List<String> providers = service.getProviders(true);
|
||||||
|
if (providers == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (String provider : providers) {
|
||||||
|
if (provider == null || provider.equals(LocationManager.GPS_PROVIDER)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
NetworkListener networkListener = new NetworkListener();
|
||||||
|
service.requestLocationUpdates(provider, GPS_TIMEOUT_REQUEST, GPS_DIST_REQUEST, networkListener);
|
||||||
|
networkListeners.add(networkListener);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
Log.d(PlatformUtil.TAG, provider + " location provider not available"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -332,6 +341,9 @@ public class OsmAndLocationProvider implements SensorEventListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
public net.osmand.Location getFirstTimeRunDefaultLocation() {
|
public net.osmand.Location getFirstTimeRunDefaultLocation() {
|
||||||
|
if (!isLocationPermissionAvailable(app)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
LocationManager service = (LocationManager) app.getSystemService(Context.LOCATION_SERVICE);
|
LocationManager service = (LocationManager) app.getSystemService(Context.LOCATION_SERVICE);
|
||||||
List<String> ps = service.getProviders(true);
|
List<String> ps = service.getProviders(true);
|
||||||
if(ps == null) {
|
if(ps == null) {
|
||||||
|
@ -914,4 +926,12 @@ public class OsmAndLocationProvider implements SensorEventListener {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isLocationPermissionAvailable(Context context) {
|
||||||
|
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION)
|
||||||
|
!= PackageManager.PERMISSION_GRANTED) {
|
||||||
|
Toast.makeText(context, R.string.no_location_permission, Toast.LENGTH_LONG).show();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -211,6 +211,17 @@ public abstract class OsmandPlugin {
|
||||||
public void mapActivityScreenOff(MapActivity activity) {
|
public void mapActivityScreenOff(MapActivity activity) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void handleRequestPermissionsResult(int requestCode, String[] permissions,
|
||||||
|
int[] grantResults, MapActivity activity) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final void onRequestPermissionsResult(int requestCode, String[] permissions,
|
||||||
|
int[] grantResults, MapActivity activity) {
|
||||||
|
for (OsmandPlugin plugin : getAvailablePlugins()) {
|
||||||
|
plugin.handleRequestPermissionsResult(requestCode, permissions, grantResults, activity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public boolean destinationReached() {
|
public boolean destinationReached() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -443,5 +454,4 @@ public abstract class OsmandPlugin {
|
||||||
p.addMyPlacesTab(favoritesActivity, mTabs, intent);
|
p.addMyPlacesTab(favoritesActivity, mTabs, intent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ import android.os.Bundle;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
|
import android.support.v4.app.ActivityCompat;
|
||||||
import android.support.v4.app.NotificationCompat.Builder;
|
import android.support.v4.app.NotificationCompat.Builder;
|
||||||
import android.support.v4.widget.DrawerLayout;
|
import android.support.v4.widget.DrawerLayout;
|
||||||
import android.support.v7.app.NotificationCompat;
|
import android.support.v7.app.NotificationCompat;
|
||||||
|
@ -95,7 +96,8 @@ import java.util.Map;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
public class MapActivity extends AccessibleActivity implements DownloadEvents {
|
public class MapActivity extends AccessibleActivity implements DownloadEvents,
|
||||||
|
ActivityCompat.OnRequestPermissionsResultCallback {
|
||||||
private static final int SHOW_POSITION_MSG_ID = OsmAndConstants.UI_HANDLER_MAP_VIEW + 1;
|
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_MSG_ID = OsmAndConstants.UI_HANDLER_MAP_VIEW + 2;
|
||||||
private static final int LONG_KEYPRESS_DELAY = 500;
|
private static final int LONG_KEYPRESS_DELAY = 500;
|
||||||
|
@ -176,7 +178,7 @@ public class MapActivity extends AccessibleActivity implements DownloadEvents {
|
||||||
|
|
||||||
mapView = new OsmandMapTileView(this, getWindow().getDecorView().getWidth(),
|
mapView = new OsmandMapTileView(this, getWindow().getDecorView().getWidth(),
|
||||||
getWindow().getDecorView().getHeight());
|
getWindow().getDecorView().getHeight());
|
||||||
if(app.getAppInitializer().checkAppVersionChanged(this)) {
|
if (app.getAppInitializer().checkAppVersionChanged(this)) {
|
||||||
new WhatsNewDialogFragment().show(getSupportFragmentManager(), null);
|
new WhatsNewDialogFragment().show(getSupportFragmentManager(), null);
|
||||||
}
|
}
|
||||||
mapActions = new MapActivityActions(this);
|
mapActions = new MapActivityActions(this);
|
||||||
|
@ -668,7 +670,7 @@ public class MapActivity extends AccessibleActivity implements DownloadEvents {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
wakeLockHelper.onStop(this);
|
wakeLockHelper.onStop(this);
|
||||||
if(getMyApplication().getNavigationService() == null) {
|
if (getMyApplication().getNavigationService() == null) {
|
||||||
getMyApplication().getNotificationHelper().removeServiceNotificationCompletely();
|
getMyApplication().getNotificationHelper().removeServiceNotificationCompletely();
|
||||||
}
|
}
|
||||||
super.onStop();
|
super.onStop();
|
||||||
|
@ -687,7 +689,6 @@ public class MapActivity extends AccessibleActivity implements DownloadEvents {
|
||||||
if (atlasMapRendererView != null) {
|
if (atlasMapRendererView != null) {
|
||||||
atlasMapRendererView.handleOnDestroy();
|
atlasMapRendererView.handleOnDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cancelNotification() {
|
private void cancelNotification() {
|
||||||
|
@ -1054,6 +1055,12 @@ public class MapActivity extends AccessibleActivity implements DownloadEvents {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
|
||||||
|
OsmandPlugin.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
|
||||||
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||||
|
}
|
||||||
|
|
||||||
private class ScreenOffReceiver extends BroadcastReceiver {
|
private class ScreenOffReceiver extends BroadcastReceiver {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package net.osmand.plus.audionotes;
|
package net.osmand.plus.audionotes;
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
|
@ -7,6 +8,7 @@ import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.DialogInterface.OnClickListener;
|
import android.content.DialogInterface.OnClickListener;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
import android.graphics.BitmapFactory.Options;
|
import android.graphics.BitmapFactory.Options;
|
||||||
|
@ -23,6 +25,7 @@ import android.media.SoundPool;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.provider.MediaStore;
|
import android.provider.MediaStore;
|
||||||
|
import android.support.v4.app.ActivityCompat;
|
||||||
import android.view.Display;
|
import android.view.Display;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.Surface;
|
import android.view.Surface;
|
||||||
|
@ -93,6 +96,9 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
|
||||||
public static final String MPEG4_EXTENSION = "mp4";
|
public static final String MPEG4_EXTENSION = "mp4";
|
||||||
public static final String IMG_EXTENSION = "jpg";
|
public static final String IMG_EXTENSION = "jpg";
|
||||||
private static final Log log = PlatformUtil.getLog(AudioVideoNotesPlugin.class);
|
private static final Log log = PlatformUtil.getLog(AudioVideoNotesPlugin.class);
|
||||||
|
public static final int CAMERA_FOR_VIDEO_REQUEST_CODE = 101;
|
||||||
|
public static final int CAMERA_FOR_PHOTO_REQUEST_CODE = 102;
|
||||||
|
public static final int AUDIO_REQUEST_CODE = 103;
|
||||||
private static Method mRegisterMediaButtonEventReceiver;
|
private static Method mRegisterMediaButtonEventReceiver;
|
||||||
private static Method mUnregisterMediaButtonEventReceiver;
|
private static Method mUnregisterMediaButtonEventReceiver;
|
||||||
private OsmandApplication app;
|
private OsmandApplication app;
|
||||||
|
@ -140,6 +146,8 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
|
||||||
private File lastTakingPhoto;
|
private File lastTakingPhoto;
|
||||||
|
|
||||||
private final static char SPLIT_DESC = ' ';
|
private final static char SPLIT_DESC = ' ';
|
||||||
|
private double tempLat;
|
||||||
|
private double tempLon;
|
||||||
|
|
||||||
public static class Recording {
|
public static class Recording {
|
||||||
public Recording(File f) {
|
public Recording(File f) {
|
||||||
|
@ -463,6 +471,7 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
|
||||||
public String getHelpFileName() {
|
public String getHelpFileName() {
|
||||||
return "feature_articles/audio-video-notes-plugin.html";
|
return "feature_articles/audio-video-notes-plugin.html";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean init(final OsmandApplication app, Activity activity) {
|
public boolean init(final OsmandApplication app, Activity activity) {
|
||||||
initializeRemoteControlRegistrationMethods();
|
initializeRemoteControlRegistrationMethods();
|
||||||
|
@ -722,7 +731,7 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
|
||||||
((AudioManager) activity.getSystemService(Context.AUDIO_SERVICE)).registerMediaButtonEventReceiver(
|
((AudioManager) activity.getSystemService(Context.AUDIO_SERVICE)).registerMediaButtonEventReceiver(
|
||||||
new ComponentName(activity, MediaRemoteControlReceiver.class));
|
new ComponentName(activity, MediaRemoteControlReceiver.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mapActivityPause(MapActivity activity) {
|
public void mapActivityPause(MapActivity activity) {
|
||||||
this.mapActivity = null;
|
this.mapActivity = null;
|
||||||
|
@ -733,7 +742,18 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
|
||||||
if (AV_EXTERNAL_RECORDER.get()) {
|
if (AV_EXTERNAL_RECORDER.get()) {
|
||||||
captureVideoExternal(lat, lon, mapActivity);
|
captureVideoExternal(lat, lon, mapActivity);
|
||||||
} else {
|
} else {
|
||||||
recordVideoCamera(lat, lon, mapActivity);
|
if (ActivityCompat.checkSelfPermission(mapActivity, Manifest.permission.CAMERA)
|
||||||
|
== PackageManager.PERMISSION_GRANTED
|
||||||
|
&& ActivityCompat.checkSelfPermission(mapActivity, Manifest.permission.RECORD_AUDIO)
|
||||||
|
== PackageManager.PERMISSION_GRANTED) {
|
||||||
|
recordVideoCamera(lat, lon, mapActivity);
|
||||||
|
} else {
|
||||||
|
tempLat = lat;
|
||||||
|
tempLon = lon;
|
||||||
|
ActivityCompat.requestPermissions(mapActivity,
|
||||||
|
new String[]{Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO},
|
||||||
|
CAMERA_FOR_VIDEO_REQUEST_CODE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -830,34 +850,55 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void recordAudio(double lat, double lon, final MapActivity mapActivity) {
|
public void recordAudio(double lat, double lon, final MapActivity mapActivity) {
|
||||||
MediaRecorder mr = new MediaRecorder();
|
if (ActivityCompat.checkSelfPermission(mapActivity, Manifest.permission.RECORD_AUDIO)
|
||||||
final File f = getBaseFileName(lat, lon, app, THREEGP_EXTENSION);
|
== PackageManager.PERMISSION_GRANTED) {
|
||||||
mr.setAudioSource(MediaRecorder.AudioSource.MIC);
|
MediaRecorder mr = new MediaRecorder();
|
||||||
mr.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
|
final File f = getBaseFileName(lat, lon, app, THREEGP_EXTENSION);
|
||||||
mr.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
|
mr.setAudioSource(MediaRecorder.AudioSource.MIC);
|
||||||
mr.setOutputFile(f.getAbsolutePath());
|
mr.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
|
||||||
try {
|
mr.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
|
||||||
runMediaRecorder(mapActivity, mr, f);
|
mr.setOutputFile(f.getAbsolutePath());
|
||||||
} catch (Exception e) {
|
try {
|
||||||
log.error("Error starting audio recorder ", e);
|
runMediaRecorder(mapActivity, mr, f);
|
||||||
AccessibleToast.makeText(app, app.getString(R.string.recording_error) + " : " + e.getMessage(), Toast.LENGTH_LONG).show();
|
} catch (Exception e) {
|
||||||
|
log.error("Error starting audio recorder ", e);
|
||||||
|
AccessibleToast.makeText(app, app.getString(R.string.recording_error) + " : " + e.getMessage(), Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tempLat = lat;
|
||||||
|
tempLon = lon;
|
||||||
|
ActivityCompat.requestPermissions(mapActivity,
|
||||||
|
new String[]{Manifest.permission.RECORD_AUDIO},
|
||||||
|
AUDIO_REQUEST_CODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void takePhoto(final double lat, final double lon, final MapActivity mapActivity) {
|
public void takePhoto(final double lat, final double lon, final MapActivity mapActivity) {
|
||||||
if (AV_EXTERNAL_PHOTO_CAM.get()) {
|
if (AV_EXTERNAL_PHOTO_CAM.get()) {
|
||||||
takeIntentPhoto(lat, lon, mapActivity);
|
takePhotoExternal(lat, lon, mapActivity);
|
||||||
} else {
|
} else {
|
||||||
final Camera cam = openCamera();
|
if (ActivityCompat.checkSelfPermission(mapActivity, Manifest.permission.CAMERA)
|
||||||
if (cam != null) {
|
== PackageManager.PERMISSION_GRANTED) {
|
||||||
takePhotoWithCamera(lat, lon, mapActivity, cam);
|
takePhotoInternalOrExternal(lat, lon, mapActivity);
|
||||||
} else {
|
} else {
|
||||||
takeIntentPhoto(lat, lon, mapActivity);
|
tempLat = lat;
|
||||||
|
tempLon = lon;
|
||||||
|
ActivityCompat.requestPermissions(mapActivity,
|
||||||
|
new String[]{Manifest.permission.CAMERA},
|
||||||
|
CAMERA_FOR_PHOTO_REQUEST_CODE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void takePhotoInternalOrExternal(double lat, double lon, MapActivity mapActivity) {
|
||||||
|
final Camera cam = openCamera();
|
||||||
|
if (cam != null) {
|
||||||
|
takePhotoWithCamera(lat, lon, mapActivity, cam);
|
||||||
|
} else {
|
||||||
|
takePhotoExternal(lat, lon, mapActivity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void takePhotoWithCamera(final double lat, final double lon, final MapActivity mapActivity, final Camera cam) {
|
private void takePhotoWithCamera(final double lat, final double lon, final MapActivity mapActivity, final Camera cam) {
|
||||||
try {
|
try {
|
||||||
final Dialog dlg = new Dialog(mapActivity);
|
final Dialog dlg = new Dialog(mapActivity);
|
||||||
|
@ -1012,7 +1053,7 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void takeIntentPhoto(double lat, double lon, final MapActivity mapActivity) {
|
private void takePhotoExternal(double lat, double lon, final MapActivity mapActivity) {
|
||||||
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
|
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
|
||||||
final File f = getBaseFileName(lat, lon, app, IMG_EXTENSION);
|
final File f = getBaseFileName(lat, lon, app, IMG_EXTENSION);
|
||||||
lastTakingPhoto = f;
|
lastTakingPhoto = f;
|
||||||
|
@ -1327,6 +1368,31 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleRequestPermissionsResult(int requestCode, String[] permissions,
|
||||||
|
int[] grantResults, MapActivity activity) {
|
||||||
|
if (requestCode == CAMERA_FOR_VIDEO_REQUEST_CODE) {
|
||||||
|
if (grantResults[0] == PackageManager.PERMISSION_GRANTED
|
||||||
|
&& grantResults[1] == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
recordVideoCamera(tempLat, tempLon, activity);
|
||||||
|
} else {
|
||||||
|
app.showToastMessage(R.string.no_camera_permission);
|
||||||
|
}
|
||||||
|
} else if (requestCode == CAMERA_FOR_PHOTO_REQUEST_CODE) {
|
||||||
|
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
takePhotoInternalOrExternal(tempLat, tempLon, activity);
|
||||||
|
} else {
|
||||||
|
app.showToastMessage(R.string.no_camera_permission);
|
||||||
|
}
|
||||||
|
} else if (requestCode == AUDIO_REQUEST_CODE) {
|
||||||
|
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
recordAudio(tempLat, tempLon, activity);
|
||||||
|
} else {
|
||||||
|
app.showToastMessage(R.string.no_microphone_permission);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class AudioVideoPhotoHandler implements PictureCallback {
|
public class AudioVideoPhotoHandler implements PictureCallback {
|
||||||
private File pictureFile;
|
private File pictureFile;
|
||||||
private Dialog dlg;
|
private Dialog dlg;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package net.osmand.plus.views;
|
package net.osmand.plus.views;
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
@ -11,6 +12,7 @@ import android.graphics.drawable.Drawable;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.v4.app.ActivityCompat;
|
||||||
import android.support.v7.app.AlertDialog;
|
import android.support.v7.app.AlertDialog;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
@ -28,6 +30,7 @@ import net.osmand.core.android.MapRendererContext;
|
||||||
import net.osmand.data.LatLon;
|
import net.osmand.data.LatLon;
|
||||||
import net.osmand.data.RotatedTileBox;
|
import net.osmand.data.RotatedTileBox;
|
||||||
import net.osmand.plus.ApplicationMode;
|
import net.osmand.plus.ApplicationMode;
|
||||||
|
import net.osmand.plus.OsmAndLocationProvider;
|
||||||
import net.osmand.plus.OsmandApplication;
|
import net.osmand.plus.OsmandApplication;
|
||||||
import net.osmand.plus.OsmandPlugin;
|
import net.osmand.plus.OsmandPlugin;
|
||||||
import net.osmand.plus.OsmandSettings;
|
import net.osmand.plus.OsmandSettings;
|
||||||
|
@ -406,7 +409,13 @@ public class MapControlsLayer extends OsmandMapLayer {
|
||||||
backToLocation.setOnClickListener(new View.OnClickListener() {
|
backToLocation.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
mapActivity.getMapViewTrackingUtilities().backToLocationImpl();
|
if(OsmAndLocationProvider.isLocationPermissionAvailable(mapActivity)) {
|
||||||
|
mapActivity.getMapViewTrackingUtilities().backToLocationImpl();
|
||||||
|
} else {
|
||||||
|
ActivityCompat.requestPermissions(mapActivity,
|
||||||
|
new String[] {Manifest.permission.ACCESS_FINE_LOCATION},
|
||||||
|
OsmAndLocationProvider.REQUEST_LOCATION_PERMISSION);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
controls.add(createHudButton(mapActivity.findViewById(R.id.map_app_mode_shadow), 0).setBg(
|
controls.add(createHudButton(mapActivity.findViewById(R.id.map_app_mode_shadow), 0).setBg(
|
||||||
|
@ -444,7 +453,7 @@ public class MapControlsLayer extends OsmandMapLayer {
|
||||||
zoomText = (TextView) mapActivity.findViewById(R.id.map_app_mode_text);
|
zoomText = (TextView) mapActivity.findViewById(R.id.map_app_mode_text);
|
||||||
|
|
||||||
View routePlanButton = mapActivity.findViewById(R.id.map_route_info_button);
|
View routePlanButton = mapActivity.findViewById(R.id.map_route_info_button);
|
||||||
routePlanningBtn = createHudButton((ImageView) routePlanButton, R.drawable.map_directions).setBg(
|
routePlanningBtn = createHudButton(routePlanButton, R.drawable.map_directions).setBg(
|
||||||
R.drawable.btn_round, R.drawable.btn_round_night);
|
R.drawable.btn_round, R.drawable.btn_round_night);
|
||||||
controls.add(routePlanningBtn);
|
controls.add(routePlanningBtn);
|
||||||
routePlanButton.setOnClickListener(new View.OnClickListener() {
|
routePlanButton.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@ -1021,6 +1030,4 @@ public class MapControlsLayer extends OsmandMapLayer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue