How to get current location from GPS in Blackberry application. I tried to get location from Locationmanager method in simulator its work fine but in my device (Storm 2 using wifi) I am not able to get current lat long.
my code
private class LocationListenerImpl implements LocationListener {
public void locationUpdated(LocationProvider provider, Location location) {
if (location.isValid()) {
heading = location.getCourse();
longitude = location.getQualifiedCoordinates().getLongitude();
latitude = location.getQualifiedCoordinates().getLatitude();
altitude = location.getQualifiedCoordinates().getAltitude();
speed = location.getSpeed();
// This is to get the Number of Satellites
String NMEA_MIME = "application/X-jsr179-location-nmea";
satCountStr = location.getExtraInfo("satellites");
if (satCountStr == null) {
satCountStr = location.getExtraInfo(NMEA_MIME);
}
// this is to get the accuracy of the GPS Cords
QualifiedCoordinates qc = location.getQualifiedCoordinates();
accuracy = qc.getHorizontalAccuracy();
}
}
public void providerStateChanged(LocationProvider provider, int newState) {
// no-op
}
}
I found this on the first place I looked for storm issues : If you run the above code on your BlackBerry device (for instance a Storm), you will get a "GPS not allowed" LocationProvider exception. You need to get your code signed if you want to use the BlackBerry Storm with GPS in your app. To do this, you need to buy a $20 certificate from RIM.
Related
I am working on a BlackBerry Application that is supposed to update the location at fixed intervals. The interval value can be selected/changed from a slider. It varies between 1 minute, 2 minutes, 5 minutes, 30 minutes etc. On the very first load (Start App), location interval is 30 seconds. After this, I store the slider value in a persistent store and location is updated accordingly with the set interval. Background thread running to update location is as follows:
private boolean startLocationUpdate()
{
boolean retval = false;
try
{
LocationProvider locationProvider = LocationProvider.getInstance(null);
if ( locationProvider == null )
{
Runnable showGpsUnsupportedDialog = new Runnable()
{
public void run()
{
Dialog.alert("GPS is not supported on this platform, exiting...");
//System.exit( 1 );
}
};
UiApplication.getUiApplication().invokeAndWait( showGpsUnsupportedDialog ); // Ask event-dispatcher thread to display dialog ASAP.
}
else
{
locationProvider.setLocationListener(new LocationListenerImpl(), interval, -1, -1);
retval = true;
}
}
catch (LocationException le)
{
System.err.println("Failed to instantiate the LocationProvider object, exiting...");
System.err.println(le);
System.exit(0);
}
return retval;
}
private class LocationListenerImpl implements LocationListener
{
public void locationUpdated(LocationProvider provider, Location location)
{
if(location.isValid())
{
double longitude = location.getQualifiedCoordinates().getLongitude();
double latitude = location.getQualifiedCoordinates().getLatitude();
updateLocationScreen(latitude, longitude);
}
}
public void providerStateChanged(LocationProvider provider, int newState)
{
}
}
private void updateLocationScreen(final double latitude, final double longitude)
{
UiApplication.getUiApplication().invokeAndWait(new Runnable()
{
public void run()
{
double lat = latitude;
double longi = longitude;
lblLatitude.setText(Double.toString(lat));
spacing.setText(", ");
lblLongitude.setText(Double.toString(longi));
}
});
}
Along with this, there is a "Refresh" button available that will start acquiring a location update immediately once clicked. This button calls a method is another class to acquire the location. The method is as follows:
try {
Criteria myCriteria = new Criteria();
myCriteria.setCostAllowed(false);
LocationProvider myLocationProvider = LocationProvider.getInstance(myCriteria);
double heading = 0;
double velocity = 0;
try {
Location myLocation = myLocationProvider.getLocation(6000);
if(myLocation.isValid())
{
double longitude = myLocation.getQualifiedCoordinates().getLongitude();
double latitude = myLocation.getQualifiedCoordinates().getLatitude();
}
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
//Dialog.alert("Location Updated");
}
});
setLocation(myLocation.getQualifiedCoordinates(),velocity,heading);
} catch ( InterruptedException iex ) {
System.out.println(iex.getMessage());
} catch ( LocationException lex ) {
System.out.println(lex.getMessage());
}
} catch ( LocationException lex ) {
System.out.println(lex.getMessage());
}
Problems I am facing:
1) Interval value not changing. I am implementing the change by picking the value from the persistent store as:
if (PersistentStoreHelper.persistentHashtable.containsKey("gpsInterval"))
{
String intervalValue=((String) PersistentStoreHelper.persistentHashtable.get("gpsInterval"));
MyScreen.interval=Integer.parseInt(intervalValue);
}
This is never empty as navigation to this page inserts a value of 30 minutes to it.
2) Once the "Refresh" button is clicked, the background thread seems to be cancelled. It no longer runs at any interval value.
I read that there is only one instance of the location provider created and with "Refresh" it is cancelled after acquiring the location and thus the background thread stops. Is this true? If yes, how can I achieve my desired result.
EDIT: The gpsInterval value is read as follows:
if (PersistentStoreHelper.persistentHashtable.containsKey("gpsInterval"))
{
String intervalValue=((String)PersistentStoreHelper.persistentHashtable.get("gpsInterval"));
interval=Integer.parseInt(intervalValue);
}
else
{
interval=10;
}
Saving the Interval
So, first of all, make sure that when you let the user change the update interval, via the slider, you properly save it to the PersistentStore. The code should look something like this:
// NOTE: I would recommend persisting the slider value as an Integer, not a String,
// but, the original code used String, so that's what this uses
hashtable.put("gpsInterval", (new Integer(intervalSlider.getValue())).toString());
PersistentObject po = PersistentStore.getPersistentObject(APP_BUNDLE_ID);
po.setContents(hashtable);
po.commit();
Since you didn't post that code, I just wanted to be sure that it was being saved to the persistent store correctly.
Updating the Location Provider / Listener
The other issue, that is a problem, is that you kick off the location updates in startLocationUpdate() with this code:
locationProvider.setLocationListener(new LocationListenerImpl(), interval, -1, -1);
That uses the value of the interval variable at the instant that setLocationListener() is called. If you later update the interval variable,
String intervalValue=((String) PersistentStoreHelper.persistentHashtable.get("gpsInterval"));
MyScreen.interval=Integer.parseInt(intervalValue);
this will have no effect on the location listener. It will keep updating with the original interval value, not the new one. You would have to call setLocationListener() again, with the new value of interval. With your code, you should probably just call startLocationUpdate() again:
String intervalValue=((String) PersistentStoreHelper.persistentHashtable.get("gpsInterval"));
MyScreen.interval=Integer.parseInt(intervalValue);
startLocationUpdate();
Refresh Problem
I'm not 100% sure, but my guess would be that in your existing code that's used when the Refresh button is pressed, you are changing to a different LocationProvider with different criteria. That's probably why the first one is cancelled.
Try changing your startLocationUpdate() method to save the provider as a member variable:
/** this is the one location provider used by this class! */
private LocationProvider _locationProvider;
private boolean startLocationUpdate()
{
boolean retval = false;
try
{
_locationProvider = LocationProvider.getInstance(null);
then, in your refresh code, use the same location provider to get the current location:
double heading = 0;
double velocity = 0;
try {
Location myLocation = _locationProvider.getLocation(6000);
if(myLocation.isValid())
Note: if you really do want to setCostAllowed(false), that's fine. Do that the first time that you assign the _locationProvider member variable. And use that provider/criteria both for normal periodic location updates, and your Refresh button handler. I think the key is to use the same provider, not create a new one with different criteria.
In my BB app, I try to fetch the location using the cell site.
But it always throws a Location exception:
Timed out while waiting for Geolocation.m=0
Here is my code
Criteria criteria = new Criteria();
criteria.setHorizontalAccuracy(Criteria.NO_REQUIREMENT);
criteria.setVerticalAccuracy(Criteria.NO_REQUIREMENT);
criteria.setCostAllowed(true);
criteria.setPreferredPowerConsumption(Criteria.POWER_USAGE_LOW);
LocationProvider provider = LocationProvider.getInstance(criteria);
Location location = provider.getLocation(-1);
QualifiedCoordinates qualifiedCoordinates = location.getQualifiedCoordinates();
double latitude = qualifiedCoordinates.getLatitude();
double longitude = qualifiedCoordinates.getLongitude();
But if i change the parameters to
criteria.setHorizontalAccuracy(50);
criteria.setVerticalAccuracy(50);
criteria.setCostAllowed(true);
criteria.setPreferredPowerConsumption(Criteria.POWER_USAGE_HIGH);
the assisted GPS works fine and I will get the correct location of device.
class LocationTracker{
private LocationProvider provider;
Criteria cr;
public LocationTracker() {
cr= new Criteria();
resetGPS();
}
public void resetGPS(){
try {
provider = LocationProvider.getInstance(cr);
if(provider != null) {
provider.setLocationListener(new MyLocationListener(),60, -1, -1);
}
}
catch (LocationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class MyLocationListener implements LocationListener {
public void locationUpdated(LocationProvider provider, Location location){
if(location != null && location.isValid()){
QualifiedCoordinates qc = location.getQualifiedCoordinates();
try {
LAT = location.getQualifiedCoordinates().getLatitude();
System.out.println("=============================lattitude :: "+LAT);
LONG= location.getQualifiedCoordinates().getLongitude();
System.out.println("==================================longitude ::"+LONG);
}
catch(Exception e){
}
}
}
public void providerStateChanged(LocationProvider provider, int newState){
if(newState == LocationProvider.TEMPORARILY_UNAVAILABLE){
provider.reset();
provider.setLocationListener(null, 0, 0, -1);
}
}
}
Like vijay, you can register to location update.
If you still want to use your solution, you have to be sure that
- It is threaded (and not just only not to get an ANR, it is a requirement)
- You have a SIM card with a Blackberry option
- You run on at least OS 5.0.0
I Write the following code in my application.
It will run successfully in Simulator but while i m trying to run in my device then it gives Lat & Lon (0.0,0.0).
What is the problem.
My Code is .
public class GetLatLon extends TimerTask{
public static Timer timer;
private double longitude;
private double latitude;
public GetLatLon(int duration) {
timer = new Timer();
try {
// TODO: update criteria with desired location distances, etc
LocationProvider.getInstance(new Criteria()).setLocationListener(
new MyLocationListener(), 1, 1, 1);
} catch (Exception e) {
System.err.println(e.toString());
}
timer.schedule(this, 0, 10000);
}
public void run() {
System.out.println("Lattitude :-"+ latitude);
System.out.println("Longitude :-"+ longitude);
}
public double getLongitude() {
return longitude;
}
public void setLongitude(double longitude) {
this.longitude = longitude;
}
public double getLatitude() {
return latitude;
}
public void setLatitude(double latitude) {
this.latitude = latitude;
}
private class MyLocationListener implements LocationListener {
public void locationUpdated(LocationProvider provider, Location location) {
if (location != null && location.isValid()) {
QualifiedCoordinates qc = location.getQualifiedCoordinates()
try {
GetLatLon.this.longitude = qc.getLongitude();
GetLatLon.this.latitude = qc.getLatitude();
} catch (Exception e) {
System.err.println("criccomini " + e.toString());
}
} else {
System.err.println("criccomini location not valid");
}
}
public void providerStateChanged(LocationProvider provider, int newState) {
}
}
}
I had also faced same problem with 9550 Storm-2.
I think you face the problem due to your device GPS value does not initiate properly. Try to use this tool :
http://appworld.blackberry.com/webstore/content/12255
this will initiate the GPS values(Plz don't close this tool just send it to background by pressing red key).After initiate the GPS value try to run you application.
i hope problem will be solved. ;)
Here No issue with code
Gps is not supported 5.0 OS with LAN ,so
I provide you some guides please verify.
Introduction to GPS and BlackBerry video.
The BlackBerry smartphone models and their corresponding GPS capabilities
How to detect whether my BB device has GPS support?
Some GPS Related Issues
Best practices for designing GPS applications for BlackBerry smartphones operating on CDMA networks
this is full information about blackberry GPS support
I want to test my app on the device. Is it possible to hard code the latitude and longitude values somewhere in the device settings so the app reads those instead of the current location?
I want to test my app for different locations other than my current location.
In the BB simulator you can go to Simulate > GPS Location. Click the Add button and enter in a name, latitude and longitude. Click save and the simulator will start feeding your new location to the apps. Note that whatever location is displayed in the drop down is the one that will be reported by the simulator.
Inside GPS mockup
If you have access to your application code, you can always create a mockup implementation for LocationProvider so it will read location and speed data from file or RecordStore and return it as a Location, something like
public class MockupLocationProvider extends LocationProvider {
public MockupLocationProvider() {
//prepare a file or RecordStore with locations here
}
public Location getLocation(int arg0) throws LocationException,
InterruptedException {
//read data from file or RecordStore
double latitude = 321;
double longitude = 34;
float altitude = 21;
//create and return location
Location result = new GPSLocation(latitude,
longitude, altitude);
return result;
}
public int getState() {
// mockup location provider always available
return LocationProvider.AVAILABLE;
}
public void reset() {
// your code
}
public void setLocationListener(LocationListener listener,
int interval, int timeout, int maxAge) {
// your code
}
}
and mockup for your Location
public class GPSLocation extends Location {
double _latitude, _longitude;
float _altitude, _horAcc = 0, _verAcc = 0, _speed;
public GPSLocation(double lat, double lon, float alt) {
init(lat, lon, alt);
}
public GPSLocation(double lat, double lon, float alt, float spd) {
init(lat, lon, alt);
_speed = spd;
}
private void init(double lat, double lon, float alt) {
_latitude = lat;
_longitude = lon;
_altitude = alt;
}
public QualifiedCoordinates getQualifiedCoordinates() {
QualifiedCoordinates c = new QualifiedCoordinates(_latitude,
_longitude, _altitude, _horAcc, _verAcc);
return c;
}
public float getSpeed() {
return _speed;
}
public String toString() {
String result = "Lat:" + String.valueOf(_latitude) + "|Lon:"
+ String.valueOf(_longitude) + "|Alt:"
+ String.valueOf(_altitude);
return result;
}
}
Then somewhere on the screen
MockupLocationProvider gpsProvider = new MockupLocationProvider();
GPSLocation loc = (GPSLocation)gpsProvider.getLocation(0);
add(new RichTextField(loc.toString()));
Outside GPS mockup
Another option is to generally mockup GPS signals.
Steps are:
configure device gps receiver for
bluetooth (for ex.)
setup some
opensource gps server on your desktop
to produce location data over
bluetooth
change configuration/code
of gps server to mockup location data
Other options
There is a possibility to uncontrolled change of location gps data by shielding gps receiver with some radio-material (like alluminium foil or so) :)
I want to know how to use our own logo to show the particular place in BBMap? Can anyone knows how to do this ?
BlackBerry Map
It's not possible in Blackberry Map to show custom icon for POI.
Things you can include in Location on Blackberry Map:
The latitude of the location * 100,000. South is negative.
The longitude of the location * 100,000. West is negative.
The label to be displayed beside the location.
The description displayed when the BlackBerry smartphone user selects
details.
Zoom level from 0 to MAX_ZOOM.
Address
City
Province or state
Country
Postal code
Phone
Fax
URL
Email address
Category
Rating information between 0 and 5
See What Is - BlackBerry Maps Location Document Format
Also see How To - Invoke BlackBerry Maps
Using MapField
As an alternative you can try MapField + manager/screen paint override.
Custom extension for MapField:
class CustomMapField extends MapField {
Bitmap mIcon;
XYRect mDest;
public void moveTo(Coordinates coordinates) {
super.moveTo(coordinates);
mDest = null;
}
protected void paint(Graphics graphics) {
super.paint(graphics);
if (null != mIcon) {
if (null == mDest) {
XYPoint fieldOut = new XYPoint();
convertWorldToField(getCoordinates(), fieldOut);
int imgW = mIcon.getWidth();
int imgH = mIcon.getHeight();
mDest = new XYRect(fieldOut.x - imgW / 2,
fieldOut.y - imgH, imgW, imgH);
}
graphics.drawBitmap(mDest, mIcon, 0, 0);
}
}
}
Example of use:
class Scr extends MainScreen {
CustomMapField mMapField;
Coordinates mCoordinates;
public Scr() {
LocationProvider provider = null;
Location location = null;
try {
provider = LocationProvider.getInstance(null);
} catch (LocationException e) {
e.printStackTrace();
}
try {
location = provider.getLocation(-1);
} catch (LocationException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
mCoordinates = location.getQualifiedCoordinates();
add(new LabelField("Latitude: "
+ String.valueOf(Coordinates.convert(
mCoordinates.getLatitude(),
Coordinates.DD_MM_SS))));
add(new LabelField("Longitude: "
+ String.valueOf(Coordinates.convert(
mCoordinates.getLongitude(),
Coordinates.DD_MM_SS))));
mMapField = new CustomMapField();
mMapField.mIcon = Bitmap.getBitmapResource("poi_icon.png");
mMapField.moveTo(mCoordinates);
add(mMapField);
}
}
See also
Using MapComponent in Blackberry
GPS and BlackBerry Maps Development Guide
Prepare GPS data
If it's real device, be sure GPS is available and turned on.
If it's simulator, then before you start program use simulator menu -> simulate -> GPS Location to set GPS data.
Other option is hardcode your own Coordinats and use them without GPS:
double latitude = 51.507778;
double longitude = -0.128056;
Coordinates mCoordinates = new Coordinates(latitude, longitude, 0);