Getting a bit lost here: I need to update Mapbox's API from 4.x.x-beta to 5.x.x and a number of things, such as xml attributes' names, way of getting access token and location services has been changed. I dealt with the first two thanks to the documentation but cannot seem to make LocationServices methods work. Android Studio tells me that it cannot resolve methods such as getLocationServices() or getLastLocation(). Here's what my code looks like, that's what used to work with Mapbox 4.x:
package com.example.myapp.interactor;
import android.location.Location;
import com.mapbox.mapboxsdk.location.LocationServices;
import com.example.myapp.MyApp;
public class GpsInteractor {
private LocationServices locationServices;
public GpsInteractor() {
locationServices = LocationServices.getLocationServices(MyApp.applicationContext());
}
public Location lastKnownLocation() {
return locationServices.getLastLocation();
}
}
So, as per documentation here ("Getting Location Updates" section), I should copy LostLocationEngine class to my project. When I did so, it cannot access some of the fields from LocationRequest.java LOST API class, namely interval, fastestInterval and smallestDisplacement.
I found this question with really similar problem and tried to compile several combinations of Mapbox APIs, but no luck.
Am I missing something?
If you haven't modified the maps locationSource yet,
LocationEngine locationEngine = LocationSource.getLocationEngine(this) will return the default LOST location engine being used. Starting in 5.0.0 LocationEngine replaces the LocationServices class. For example, to get the last known user location, you can do this:
LocationEngine locationEngine = LocationSource.getLocationEngine(this)
locationEngine.getLastLocation();
You can read more on the LocationEngine in the new documentation here.
Related
I just updated my Google dependencies to 12.0.1 and now I'm getting this error where I'm using FusedLocationProviderClient.
Any idea why is this happening? Looking into source code, I can see the the constructors are now hidden:
#Hide
public FusedLocationProviderClient(#NonNull Context var1) {
super(var1, LocationServices.API, (ApiOptions)null, new zzg());
}
#Hide
public FusedLocationProviderClient(#NonNull Activity var1) {
super(var1, LocationServices.API, (ApiOptions)null, new zzg());
}
But it doesn't make sense. Why? Google obviously wanted people to migrate to this new Location Provider. Why would they suddenly make it unavailable? I've checked out the docs and I can't find anything about this.
Luckily the code still compiles and location works. But still...why?
The documentation could have been clearer, but it seems the intention is for you to call LocationServices.getFusedLocationProviderClient(). See the API here.
Upgrade to version 15.0.0 released on the 12th it will clear the warning for you. I don't see anything in release notes or bug reports mentioning this, so it is probably just a bug introduced in 12.0.1.
val client = GoogleApiClient.Builder(context)
.addApi(Awareness.API)
.build()
client.connect()
I am learning google api's where I found Awareness API but when I am importing it in android studio, It displays deprecated. What is alternative way for accessing location and activity from same api.
Is it okay to go with Activity Recognition? and Fused Location?
It's actually stated in the release notes of Google API Services
release notes
Awareness
Updated the Awareness API for the new GoogleApi-based clients, which automatically manage connections to services and require less boilerplate code to use:
Added the FenceClient class and the Awareness.getFenceClient() methods. Use FenceClient instead of FenceApi.
Added the SnapshotClient class and the Awareness.getSnapshotClient() methods. Use SnapshotClient instead of SnapshotApi.
FenceClient has below method which is similar to the original API
public Task<Void> updateFences(FenceUpdateRequest var1) {
return zzbj.zzb(Awareness.FenceApi.updateFences(this.zzago(), var1));
}
public Task<FenceQueryResponse> queryFences(FenceQueryRequest var1) {
return zzbj.zza(Awareness.FenceApi.queryFences(this.zzago(), var1), new FenceQueryResponse());
}
I'm trying to set some protection against people using mock locations to manipulate my app. I realise that it's impossible to prevent 100%... I'm just trying to do what I can.
The app uses Google location services (part of play services) in its main activity.
The onLocationChanged() method is:
public void onLocationChanged(Location location) {
this.mCurrentLocation = location;
if (Build.VERSION.SDK_INT > 17 && mCurrentLocation.isFromMockProvider()) {
Log.i(TAG, "QQ Location is MOCK");
// TODO: add code to stop app
// otherwise, currently, location will never be updated and app will never start
} else {
Double LAT = mCurrentLocation.getLatitude();
Double LON = mCurrentLocation.getLongitude();
if ((LAT.doubleValue() > 33.309171) || (LAT.doubleValue() < 33.226442) || (LON.doubleValue() < -90.790165) || (LON.doubleValue() > -90.707081)) {
buildAlertMessageOutOfBounds();
} else if (waiting4FirstLocationUpdate) {
Log.i(TAG, "YYY onLocationChanged() determines this is the FIRST update.");
waiting4FirstLocationUpdate = false;
setContentView(R.layout.activity_main);
startDisplayingLists();
}
}
}
The location services work perfectly and all is well with the app in general, but when I run the app in an emulator with Android Studio (Nexus One API 23), and I set the location using extended controls (mock), the app just continues to work as normal, and so it seems that the condition:
if (Build.VERSION.SDK_INT > 17 && mCurrentLocation.isFromMockProvider())
Is returning false.
This doesn't make any sense to me. Does anyone know why this would happen?
Thanks!
The short answer: .isFromMockProvider is unreliable. Some fake locations are not properly detected as such.
I have spent an extensive amount of time researching this and written a detailed blog post about it.
I also spent time to find a solution to reliably suppress mock locations across all recent/relevant Android versions and made a utility class, called the LocationAssistant, that does the job.
In a nutshell (using the aforementioned LocationAssistant):
Set up permissions in your manifest and Google Play Services in your gradle file.
Copy the file LocationAssistant.java to your project.
In the onCreate() method of your Activity, instantiate a LocationAssistant with the desired parameters. For example, to receive high-accuracy location updates roughly every 5 seconds and reject mock locations, call new LocationAssistant(this, this, LocationAssistant.Accuracy.HIGH, 5000, false). The last argument specifies that mock locations shouldn't be allowed.
Start/stop the assistant with your Activity and notify it of permission/location settings changes (see the documentation for details).
Enjoy location updates in onNewLocationAvailable(Location location). If you chose to reject mock locations, the callback is only invoked with non-mock locations.
There are some more methods to implement, but essentially this is it. Obviously, there are some ways to get around mock provider detection with rooted devices, but on stock, non-rooted devices the rejection should work reliably.
I have a requirement for building an Android mapping application onto which I will plot archaeological POIs (Points of interest). The requirement is to have aerial photographs much like Google Maps Satellite view. However, the other requirement is offline mapping capability when data connectivity is unavailable, so that rules out using Google Maps.
So I have two questions.
Does OSMDroid have free access to tile sources supporting Arial Photography or Satellite without using Bing?.
I know OSM can support Bing which does have an Ariel Photography map, but I can't get it to work. Are there any bing specific tutorials you can point me to, or a simple example of how to get a bing map to show in OSMDroid as I've been looking for some hours and pulling my hair out.
In eclise I have been able to build a simple app to show the default maps of OSMDroid (Mapink). To try and use Bing I added into my project source three classes. BingMapTileSource.Java, ImageryMetaData.Java and ImageryMetaDataResouce.Java. I got these from the Bing sub folder of the TileProvider directory on the OSMDroid SVN (Link here)
However, when I use this in the onCreate as follows, I get null pointer errors in the BingMapTileSource.java class.
MapView mapView = new MapView(this, 256);
mapView.setClickable(true);
mapView.setBuiltInZoomControls(true);
String m_locale=Locale.getDefault().getISO3Language()+"-"+Locale.getDefault().getISO3Language();
mapView.setTileSource(new BingMapTileSource("Bing",m_locale));
mapView.getController().setZoom(10);
mapView.getController().setCenter(new GeoPoint(39.461078, 2.856445));
setContentView(mapView);
I beleive the cause of this problem is that the following class variables are never initialised before they are first used.
s_roadMetaData = null;
s_aerialMetaData = null;
s_aerialwithLabelsMetaData = null;
The only place I can see them being initialised is in a static method called InitMetaData which never gets called.
public static synchronized void initMetaData(final Context aContext)
Though some clue as to its purpose is provided in its Javadoc which states.
/**
* Initialize BingMap tile source.<br>
* This method should be invoked before class instantiation.<br>
* It get dynamically the REST service url to be used to get tile in each supported map view mode.
* #param a_BingMapKey The user's BingMap key.
* #throws Exception
*/
However, I've no idea how to use this. Any advice or pointers to tutorials, examples, or some code would be greatly appreciated.
updated 22.07.2015
How to add Bing maps to osmdroid
Here are step by step instructions. Perhaps someone this will save a lot of time.
1.Add dependency to gradle
compile 'org.slf4j:slf4j-android:1.6.1-RC1'
compile 'org.osmdroid:osmdroid-android:4.3'
2.add library osmdroid-third-party from here
OR
add three classes in our project (BingMapTileSource.java, ImageryMetaData.java, ImageryMetaDataResource.java). from here
3.Getting a Bing Maps Key. Instructions here
4.Add the Bing Maps Key to the manifest.
<meta-data android:name="BING_KEY" android:value="ApEqyap8rTa4WTNCNv-3pAGQc7XUsHS6595tuDI3MHR59QlahJ5bqYGYhMYJq6Ae" />
5.The last step. Add map code
ResourceProxyImpl mResourceProxy = new ResourceProxyImpl(getContext().getApplicationContext());
MapView mMapView = new MapView(getContext(), 256, mResourceProxy);
mMapView.setBuiltInZoomControls(true);
mMapView.setMultiTouchControls(true);
try{
BingMapTileSource.retrieveBingKey(getContext());
String m_locale = Locale.getDefault().getDisplayName();
BingMapTileSource bing = new BingMapTileSource(m_locale);
bing.setStyle(BingMapTileSource.IMAGERYSET_AERIAL);
mMapView.setTileSource(bing);
}
catch(Exception e){
e.printStackTrace();
}
mapContent.addView(mMapView);
The requirement for offline satellite images means that you will have to license the imagery separately. I don't think any of the providers allow such usage without a specific agreement.
There are many commercial providers for aerials: Digitalglobe, Geoeye etc. Check from Google Earth, they mention their providers in bottom of the map.
There are also some lower resolution free images like OpenAerialMap, which itself is not working anymore. But it is worth to check their original sources (http://openaerialmap.org/Data_Sources). Also at least some of their remaining archive is available in MapQuest Open Tiles API. Maybe they even allow downloading to offline, check their terms.
Two warnings through - aerial imagery from commercial providers can be quite expensive, especially for offline case. And aerials from any source will take a lot of space, several times more than raster tiles. So just downloading them to the device can be a challenge.
Ok well I figured the problem with getting the Bing maps to work. What was needed was to precede the instantiation of the BingMapTileSouce with the following static method that instantiates the three Meta Data objects discussed earlier.
try
{
BingMapTileSource.initMetaData(this);
}
catch (Exception e)
{
e.printStackTrace();
}
I want to use Flickr API for downloading the images on Android Phone, can any one give or tell, me about the working sample of Flickr API on Andorid.
I have add the flickr.jar as the external library, and i have the "Key"and "Secret" but i do not know how to download the images.
All it takes is just 3 steps and you will have it implemented.
Step 1: Find your user id.
The easiest way is to use this service http://idgettr.com/
Step 2: Acquire you flickr api key
Just log-in to you account and click this link http://www.flickr.com/services/api/misc.api_keys.html
Step 3: Get the code from the example project from our blog
http://www.quintostdio.com/blog/archives/1117
Add you user id and api key on the FlickrActivity class (in the package com.quintostdio.test.flickr.ui) and run the example. You can copy paste the classes and add it to your project, with no more changes and it will work.
Hi I have built a Flickr Java library for Android: http://code.google.com/p/flickrj-android/
You'll need to look in their documentation on the Flickr site. Most likely will use the Java library and import it into your Android project.
Probably have to instantiate an object, using the Key and Secret. Once you have a valid authentication object, you'll use a provided method (from the docs) to get a picture.
Have a look here: http://www.flickr.com/services/api/
#Todd DeLand answer is pretty accurate even nowadays.
However, I'll speed you up the search and tell you that the flickrj-android is not anymore up to date, as you can check in the Downloads page https://code.google.com/archive/p/flickrj-android/downloads
The other project that is listed in the Flickr API page ( http://www.flickr.com/services/api/ ), Flickr4Java, it's definitely working nowadays since I just tested it today and so far is doing it's job pretty nicely.
Github repo: https://github.com/boncey/Flickr4Java
Gradle config to add in your project (be careful, since in the README it appears another Gradle configuration, which is for the project that Flickr4Java is based on, and is NOT working):
implementation "com.flickr4java:flickr4java:2.17"
As of today, Flickr4Java was last updated on Nov 11, 2017, which is not bad.
This is an example of how I sent a query to get the pictures around a certain location (latitude,longitude):
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
String apiKey = "MY_API_KEY";
String sharedSecret = "MI_API_SECRET";
REST rest = new REST();
Flickr flickrClient = new Flickr(apiKey, sharedSecret, rest);
SearchParameters searchParameters = new SearchParameters();
searchParameters.setLatitude(exampleLatitude);
searchParameters.setLongitude(exampleLongitude);
searchParameters.setRadius(3); // Km around the given location where to search pictures
PhotoList photos = flickrClient.getPhotosInterface().search(searchParameters,5,1);
} catch (Exception ex) {
Log.d(MapApplication.LOG_TAG, ex.getLocalizedMessage());
}
}
});
thread.start();
I would avoid flickr4java. I assumed it worked at first but after incorporating it in to my project I have found that it crashes the app intermittently. very annoying and has been a big waste of time :(. probably works fine under other java apps but does not seem to play well with android :(