Basically I have a android Service LogService which I trigger from my MainActivity. Inside service class I am creating a object of LocationListener class LocationFetcher with the name locationFetcher. The LocationFetcher class has a public string member FormattedResult. Now Inside the LogService.run() I want to fetch FormattedResult periodically. How to do That ?? Below is code for reference.
I have a LocationListener like This:
/*This is relevant content of LocationFetcher.java */
public class LocationFetcher extends TimerTask implements LocationListener{
public String FormattedResult;
private boolean availableFlag;
#Override
public void onLocationChanged(Location arg0) {
// TODO Auto-generated method stub
this.availableFlag=true;
this.FormattedResult=String.format(Locale.ENGLISH, "Lat=\t%f\nLong=\t%f", arg0.getLatitude(),arg0.getLongitude());
Log.d("LocationFetcher",this.FormattedResult);
}
#Override
public void run() {
// TODO Auto-generated method stub
Log.d("LocationFetcher","This is Timer Run !!!");
}}
My android service is like this :
/* This is the relevant pert from LogService.java file*/
public class LogService extends Service{
private Logger logger;
private LocationFetcher locationFetcher;
public LocationManager locationManager;
private Timer timer1;
#Override
public int onStartCommand(Intent intent,int flags, int startId){
super.onStartCommand(intent, flags, startId);
if(!this.running){
this.logger = new Logger(); //Initiated member from subclass
this.logger.start(); //Started
this.timer1 = new Timer(); //Timer for timed job
this.locationFetcher = new LocationFetcher();//THIS IS MY EXTERNAL CLASS in "LocationFetcher.java"
//I am using GPS data.
this.locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
if(this.locationFetcher != null){//NULLPointerException is thrown if I REMOVE this if ??WHY
this.locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this.locationFetcher);
this.timer1.scheduleAtFixedRate(this.locationFetcher, 5000, 2000);
//Below Line still throws NullPointrException ??WHY
//this.locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this.locationFetcher);
}else{
Log.d("GPS-Logger"," Found Null LocationFlecther !");
}
}
public void run(){
LogService ll = LogService.this;
LocationManager mgr = ll.locationManager; //THIS IS MY QUESTION
// HOW DO I ACCESS THE GPS LOCATION STORED in locationmanager.FormattedResult
// Which is a string
// //////////////////////////////////////////////////////////////////////////
while(ll.isActive){
try {
String temp ;
if(!temp.isEmpty()){
Log.d("GPS-Logger","data is :"+temp);
}
Log.d("GPS-Logger","data is :");
Thread.sleep(5000);
sec +=1 ;
if(sec >= 12){
Log.d("GPS-Logger","Sending Data Here");
sec = 0;
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
ll.isActive=false;
Log.d("GPS-Logged","EXIT Request Received");
}
}
}
I know that I have asked multiple Questions above but I didn't knew how to separate them.
NEED HELP!!!
You can have the location Fetcher modified as "LocationListenerClass" shown below:
The main concern to see in the modified class are as follows:
1.I have used a singleton class for registering and removing location updates from overall area.(i.e say our service etc).
2.You should initialize the location string say (FormattedResult as in you case ) from both onLocationChngaed() and getCurrentLocation(). Because onLocationChngaed() will only call when the distance and time changed as provided in requestLocationUpdates study more about this.
public class LocationListenerClass implements LocationListener{
private static LocationListenerClass instance;
private static Context context;
private LocationManager myLocationManager;
private LocationListener myLocationListener;
private Double latitude = 0d;
private Double longitude = 0d;
public static String FormattedResult;
public static LocationListenerClass getInstance(Context context) {
LocationListenerClass.context = context;
if (null == instance) {
instance = new LocationListenerClass();
}
return instance;
}
public void getCurrentLocation() {
try {
myLocationManager = (LocationManager) context
.getSystemService(Context.LOCATION_SERVICE);
myLocationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, 30000, 100,
this);
Location location;
location = myLocationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location == null) {
myLocationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, 30000, 100,
myLocationListener);
location = myLocationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
}
if (location != null) {
try {
latitude = location.getLatitude();
Data.CURENT_LATITUDE = latitude;
Log.v(ConstantLib.LOG, " latitude : "
+ Data.CURENT_LATITUDE);
longitude = location.getLongitude();
Data.CURENT_LONGITUDE = longitude;
Log.v(ConstantLib.LOG, " longitude : "
+ Data.CURENT_LONGITUDE);
**FormattedResult=String.format(Locale.ENGLISH, "Lat=\t%f\nLong=\t%f", latitude(),longitude());
Log.d("LocationFetcher",this.FormattedResult);**
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void removeLocationUpdates() {
try {
if (myLocationManager != null) {
myLocationManager.removeUpdates(myLocationListener);
}
} catch (Exception e) {
}
}
public void onLocationChanged(Location location) {
try {
if (location != null) {
Data.CURENT_LATITUDE = location.getLatitude();
Log.v(ConstantLib.LOG, "LOCATION CHANGED" + " latitude : "
+ Data.CURENT_LATITUDE);
longitude = location.getLongitude();
Data.CURENT_LONGITUDE = location.getLongitude();
Log.v(ConstantLib.LOG, "LOCATION CHANGED" + " longitude : "
+ Data.CURENT_LONGITUDE);
**FormattedResult=String.format(Locale.ENGLISH, "Lat=\t%f\nLong=\t%f", latitude(),longitude());
Log.d("LocationFetcher",this.FormattedResult);**
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
}
Related
i have two AsyncTask which works with Current user location data, the first goes well without any problem, but the second, stop the app works and app will crash.
notice that, just in real device the first task will works but in virtual devices even the first didn't work :|
code of mainActivity:
public class MainActivity extends AppCompatActivity {
Button btnShowLocation;
public static TextView txtTemperature;
public static TextView txtWindSpeed;
public static TextView txtHumidity;
public static TextView txtSummary;
public static TextView txtCityName;
GpsTracker gps;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnShowLocation = (Button)findViewById(R.id.btnupdate);
txtTemperature = (TextView) findViewById(R.id.txtTemperature);
txtWindSpeed = (TextView) findViewById(R.id.txtWindSpeed);
txtHumidity = (TextView) findViewById(R.id.txthumidity);
txtSummary = (TextView) findViewById(R.id.txtSummary);
txtSummary = (TextView) findViewById(R.id.txtCityName);
//find geoLocation
btnShowLocation.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
gps = new GpsTracker(MainActivity.this);
if(gps.canGetLocation()){
Double lat = gps.getLatitude();
Double lng = gps.getLongtitude();
Toast.makeText(getApplicationContext(),
"Your location is -\nLat:"+lat+"\nLng:"+lng,
Toast.LENGTH_LONG).show();
String url = "https://api.forecast.io/forecast/KEY/"+lat+","+lng+"?units=ca";
JsonTask task = new JsonTask(getApplicationContext());
task.execute(url);
String url2 = "http://maps.googleapis.com/maps/api/geocode/json?latlng="+lat+","+lng;
CityNameTask city = new CityNameTask(getApplicationContext());
city.execute(url2);
}
else {
gps.showSettingsAlert();
}
}
});
}
}
the First AsyncTask which work fine:
class JsonTask extends AsyncTask<String, String, String> {
private Context mContext;
public JsonTask (Context context){
mContext = context;
}
protected void onPreExecute() {
super.onPreExecute();
}
protected String doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer = new StringBuffer();
String line = "";
String data = "";
while ((line = reader.readLine()) != null) {
buffer.append(line+"\n");
//Log.d("Response: ", "> " + line); //here u ll get whole response...... :-)
try{
JSONObject jsonObject= new JSONObject(line).getJSONObject("currently");
data=
jsonObject.getString("temperature")+","+
jsonObject.getString("windSpeed")+","+
jsonObject.getString("humidity")+","+
jsonObject.getString("summary");
}
catch(JSONException e)
{
}
}
return data.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
String string = result;
String[] parts = string.split(",");
String temperature = parts[0];
String windSpeed = parts[1];
String humidity = parts[2];
String summary = parts[3];
MainActivity.txtTemperature.setText(temperature);
MainActivity.txtWindSpeed.setText(windSpeed);
MainActivity.txtHumidity.setText(humidity);
MainActivity.txtSummary.setText(summary);
}
}
the second Task which fails:
class CityNameTask extends AsyncTask<String, String, String> {
private Context mContext;
public CityNameTask (Context context){
mContext = context;
}
protected void onPreExecute() {
super.onPreExecute();
}
protected String doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer = new StringBuffer();
String line = "";
String data = "";
while ((line = reader.readLine()) != null) {
buffer.append(line+"\n");
}
Log.d("Response: ", "> " + line);
try {
JSONObject jsonRootObject = new JSONObject(line);
JSONArray jsonArray = jsonRootObject.optJSONArray("results");
for(int i=0; i < jsonArray.length(); i++){
JSONObject jsonObject = jsonArray.getJSONObject(i);
data = jsonObject.getString("formatted_address");
}
} catch (JSONException e) {e.printStackTrace();}
return data.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
MainActivity.txtCityName.setText(result);
}
}
-- edited: logcat:
06-03 22:00:07.998 2804-2804/com.mortezaaghili.havamoon E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.mortezaaghili.havamoon, PID: 2804
java.lang.NullPointerException: Attempt to invoke virtual method 'double android.location.Location.getLatitude()' on a null object reference
at com.mortezaaghili.havamoon.GpsTracker.getLatitude(GpsTracker.java:131)
at com.mortezaaghili.havamoon.MainActivity$1.onClick(MainActivity.java:54)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
edited again:
this is GPSTracker class:
public class GpsTracker extends Service implements LocationListener {
private final Context context;
boolean isGPSEnabled = false;
boolean isNetworkEnabled = false;
boolean canGetLocation = false;
Location location;
Double latitude;
Double longtitude;
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10;
private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1;
protected LocationManager locationManager;
public GpsTracker(Context context){
this.context = context;
getLocation();
}
public Location getLocation(){
try {
locationManager = (LocationManager) context.getSystemService(LOCATION_SERVICE);
isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnabled && !isNetworkEnabled){}
else{
this.canGetLocation = true;
if(isNetworkEnabled){
try {
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES,
this);
if (locationManager != null){
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if(location != null){
latitude = location.getLatitude();
longtitude = location.getLongitude();
}
}
}
catch (SecurityException e)
{
}
}
if(isGPSEnabled){
if (location == null){
try {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES,
this);
if (locationManager != null){
location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(location != null){
latitude = location.getLatitude();
longtitude = location.getLongitude();
}
}
}
catch (SecurityException e)
{
}
}
}
}
}
catch (Exception e){
e.printStackTrace();
}
return location;
}
public void stopUsingGPS(){
if (locationManager != null){
try{
locationManager.removeUpdates(GpsTracker.this);
}
catch(SecurityException e){
}
}
}
public double getLatitude(){
if (locationManager != null){
latitude = location.getLatitude();
}
return latitude;
}
public double getLongtitude(){
if (locationManager != null) {
longtitude = location.getLongitude();
}
return longtitude;
}
public boolean canGetLocation(){
return this.canGetLocation;
}
public void showSettingsAlert(){
AlertDialog.Builder alertDialog = new AlertDialog.Builder(context);
alertDialog.setTitle("GPS is setting");
alertDialog.setMessage("GPS is not enabled. do you want go to settings?");
alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
context.startActivity(intent);
}
});
alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
alertDialog.show();
}
#Override
public void onLocationChanged(Location location) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
What it seems like is that your location variable is not initialized from the GpsTracker class.
Therefore when you are extending Service class and implementing LocationListener you would have overridden a method called getLocation(), which should return Location object, but in your case is returning null.
If you could just post the code for that file, or debug it on your own.
probably your GpsTracker class must include something like:
public double getLatitude() {
if(location != null) { // here must be checked if location is available and it's not null, coz now you probably get crash coz this has not been checked
latitude = location.getLatitude();
}
return latitude;
}
In order to avoid getting Null Locations you need to use google play locations API
which is recommended by google.
Also Try
String line = "";
String data = "";
while ((line = reader.readLine()) != null) {
buffer.append(line+"\n");
}
At the end of this loop the line object is null
So save a copy of the last line element in some variable and
Then apply the following code on that.
Log.d("Response: ", "> " + line);
try {
JSONObject jsonRootObject = new JSONObject(line);
JSONArray jsonArray = jsonRootObject.optJSONArray("results");
for(int i=0; i < jsonArray.length(); i++){
JSONObject jsonObject = jsonArray.getJSONObject(i);
data = jsonObject.getString("formatted_address");
}
The relavent part of the stack trace is:
java.lang.NullPointerException: Attempt to invoke virtual method 'double android.location.Location.getLatitude()' on a null object
reference at com.mortezaaghili.havamoon.GpsTracker.getLatitude(GpsTracker.java:131)
Broken code mentioned:
public double getLatitude(){
if (locationManager != null){
latitude = location.getLatitude();
}
return latitude;
}
You're checking for a null locationManager but then calling a method on location which may have been null from the big try/catch swallowing in the getLocation() setup method called during the GPSTracker constructor.
Check for location null instead:
public double getLatitude(){
if (location != null){
latitude = location.getLatitude();
}
return latitude;
}
sorry, I know such questions happened here, but I cannot action them in my code, I am a beginner...
So, I am trying to get a GPS coordinates read from LocationManager and my code is throwing a "Can't create handler inside thread that has not called Looper.prepare()".
So my code works this way. I used a Timer and Timertask classes to create a scheduled task from which my coordinates are being read.
This is a timer class:
public class GeoLocationTimer extends Timer {
private List coords;
private Context context;
public GeoLocationTimer(Context context){
this.context = context;
this.coords = new ArrayList<Double>();
//Log.e("cont timer","content" + context);
}
public void addPosition(Double pos) {
this.coords.add(pos);
}
public void scheduleTasks(long interval) {
//Log.e("z schedule","cont"+context);
this.schedule(new GeoLocationTask(this, context), 0, interval);
}
public void cancelTasks() {
this.cancel();
}
public List getList(){
return coords;
}
This is task:
public class GeoLocationTask extends TimerTask{
private final GeoLocationTimer timerContext;
private final Context context;
private Pair<Double, Double> coordsSet;
public GeoLocationTask(GeoLocationTimer timerContext, Context context){
this.timerContext = timerContext;
this.context = context;
}
#Override
public void run() {
// TODO Auto-generated method stub
GeoActivity tracker = new GeoActivity(context);
coordsSet = tracker.getLocation();
Log.e("first","timertask");
if (coordsSet != null){
Log.e("first","a tu wartosc" + coordsSet.first);
Log.e("second","a tu wartosc" + coordsSet.second);
timerContext.addPosition(coordsSet.first);
timerContext.addPosition(coordsSet.second);
//context.addPosition(tracker.getLocationNow().get(1));
}
}
public boolean cancel() {
return false;
}
}
Here is context from which I am trying to run this task:
package com.example.gpstracking;
public class GeoActivity extends ContextWrapper {
Context context;
public GeoActivity(Context base) {
super(base);
this.context = base;
}
public Pair<Double, Double> getLocation(){
Tracking track = new Tracking(context);
return track.getLocation();
}
And tracking now:
public class Tracking extends Service implements LocationListener{
private final Context mContext;
Location location; // location
double latitude; // latitude
double longitude; // longitude
// The minimum distance to change Updates in meters
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters
// The minimum time between updates in milliseconds
private static final long MIN_TIME_BW_UPDATES = 1000 * 30 * 1; // 0.5 minute
// flag for GPS status
boolean isGPSEnabled = false;
// flag for network status
boolean isNetworkEnabled = false;
boolean canGetLocation = false;
protected LocationManager locationManager;
public Tracking(Context context) {
this.mContext = context;
}
public Pair<Double, Double> getLocation() {
try {
locationManager = (LocationManager) mContext.getSystemService(LOCATION_SERVICE);
// getting GPS status
isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
// getting network status
isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnabled && !isNetworkEnabled) {
// no network provider is enabled
Log.e("no provider","turn it on man!");
} else {
this.canGetLocation = true;
// First get location from Network Provider
if (isNetworkEnabled) {
Log.e("Network", "Network");
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
latitude = location.getLatitude();
longitude = location.getLongitude();
Log.e("latitude","latitude"+latitude);
Log.e("longitude","longitude"+longitude);
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
return new Pair(latitude,longitude);
}
// if GPS Enabled get lat/long using GPS Services
if (isGPSEnabled) {
Log.e("GPS", "GPS");
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
longitude = location.getLongitude();
return new Pair(latitude,longitude);
}
}
} catch (Exception e) {
Log.e("excepton:","exp" + e.getMessage());
e.printStackTrace();
e.getMessage();
}
return new Pair(0.0,0.0);
}
#Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
}
So, sorry for being stupid. Could someone help me with this?
Cheers
A
I probably found the issue: I really should not call requestlocationupdates in here, as I am calling for updates in the timer class. Need to go and test it outside :)
Cheers!
i am trying to make an application where it show the 5 closest places with multiple markers from my current location. On other topics i saw many examples, but, no one explained how to create app with multiple markers or HashMap where show the nearest place. Please help me to solve it.
Here is my Main activity.java
public class MainActivity extends Activity
{
private GoogleMap mMap;
private ArrayList<MyMarker> mMyMarkersArray = new ArrayList<MyMarker>();
private HashMap<Marker, MyMarker> mMarkersHashMap;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mMarkersHashMap = new HashMap<Marker, MyMarker>();
mMyMarkersArray.add(new MyMarker("Restaurant Zaplet", "Telephone: \n Address: ", "iconZaplet", Double.parseDouble("43.381499"), Double.parseDouble("19.808931")));
mMyMarkersArray.add(new MyMarker("Restaurant Oresac", "Telephone: \n Address: ","iconOresac", Double.parseDouble("43.796009"), Double.parseDouble("21.745934")));
mMyMarkersArray.add(new MyMarker("Restaurant Obilic","Telephone: \n Address: ", "iconObilic", Double.parseDouble("42.547670"), Double.parseDouble("19.660000")));
mMyMarkersArray.add(new MyMarker("Restaurant Dva sesira","Telephone: \n Address: XII vek", "iconDvaSesira", Double.parseDouble("41.486736"), Double.parseDouble("20.731670")));
mMyMarkersArray.add(new MyMarker("Manastir Lipov Lad", "Telephone: \n Address: ","iconLipovLad", Double.parseDouble("44.850546"), Double.parseDouble("20.479869")));
mMyMarkersArray.add(new MyMarker("Restaurant Slodes", "Telephone: nepoznato \n Address: ", "iconSlodes", Double.parseDouble("41.503238"), Double.parseDouble("19.791890")));
setUpMap();
plotMarkers(mMyMarkersArray);
}
private void plotMarkers(ArrayList<MyMarker> markers)
{
if(markers.size() > 0)
{
for (MyMarker myMarker : markers)
{
MarkerOptions markerOption = new MarkerOptions().position(new LatLng(myMarker.getmLatitude(), myMarker.getmLongitude()));
markerOption.icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_restaurant));
Marker currentMarker = mMap.addMarker(markerOption);
mMarkersHashMap.put(currentMarker, myMarker);
mMap.setInfoWindowAdapter(new MarkerInfoWindowAdapter());
}
}
}
private int manageMarkerIcon(String markerIcon)
{
if (markerIcon.equals("iconZaplet"))
return R.drawable.zaplet;
else if(markerIcon.equals("iconOresac"))
return R.drawable.oresac;
else if(markerIcon.equals("iconObilic"))
return R.drawable.obilic;
else if(markerIcon.equals("iconLipovLad"))
return R.drawable.lipovlad;
else if(markerIcon.equals("iconSlodes"))
return R.drawable.slodes;
else
return R.drawable.icondefault;
}
private void setUpMap()
{
if (mMap == null)
{
mMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
if (mMap != null)
{
mMap.setMyLocationEnabled(true);
LocationManager lm = (LocationManager) getSystemService (LOCATION_SERVICE);
String provider = lm.getBestProvider(new Criteria (), true);
if (provider == null) {
onProviderDisabled (provider);
}
Location loc = lm.getLastKnownLocation(provider);
if (loc != null) {
onLocationChanged (loc);
}
mMap.setOnMapLongClickListener(onLongClickMapSettings ());
mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener()
{
#Override
public boolean onMarkerClick(com.google.android.gms.maps.model.Marker marker)
{
marker.showInfoWindow();
return true;
}
});
}
else
Toast.makeText(getApplicationContext(), "Unable to create Maps", Toast.LENGTH_SHORT).show();
}
}
private OnMapLongClickListener onLongClickMapSettings() {
// TODO Auto-generated method stub
return new OnMapLongClickListener () {
#Override
public void onMapLongClick(LatLng arg0) {
// TODO Auto-generated method stub
Log.i(arg0.toString(), "User long clicked");
}
};
}
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
LatLng latlng = new LatLng (location.getLatitude(), location.getLongitude());
mMap.moveCamera(CameraUpdateFactory.newLatLng(latlng));
mMap.animateCamera(CameraUpdateFactory.zoomTo(10));
}
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
public class MarkerInfoWindowAdapter implements GoogleMap.InfoWindowAdapter
{
public MarkerInfoWindowAdapter()
{
}
#Override
public View getInfoWindow(Marker marker)
{
return null;
}
#SuppressLint("InflateParams") #Override
public View getInfoContents(Marker marker)
{
View v = getLayoutInflater().inflate(R.layout.info_window_layout, null);
MyMarker myMarker = mMarkersHashMap.get(marker);
ImageView markerIcon = (ImageView) v.findViewById(R.id.marker_icon);
TextView markerLabel = (TextView)v.findViewById(R.id.marker_label);
TextView anotherLabel = (TextView)v.findViewById(R.id.another_label);
markerIcon.setImageResource(manageMarkerIcon(myMarker.getmIcon()));
markerLabel.setText(myMarker.getmLabel());
anotherLabel.setText(myMarker.getmIstorijat());
return v;
}
}
}
Here is code of MyMarker.java
> public class MyMarker
{
private String mLabel;
private String mIstorijat;
private String mIcon;
private Double mLatitude;
private Double mLongitude;
public MyMarker(String label, String istorijat, String icon, Double latitude, Double longitude)
{
this.mLabel = label;
this.mIstorijat = istorijat;
this.mLatitude = latitude;
this.mLongitude = longitude;
this.mIcon = icon;
}
public String getmLabel()
{
return mLabel;
}
public void setmLabel(String mLabel)
{
this.mLabel = mLabel;
}
public String getmIstorijat()
{
return mIstorijat;
}
public void setmIstorijat(String mIstorijat)
{
this.mIstorijat = mIstorijat;
}
public String getmIcon()
{
return mIcon;
}
public void setmIcon(String icon)
{
this.mIcon = icon;
}
public Double getmLatitude()
{
return mLatitude;
}
public void setmLatitude(Double mLatitude)
{
this.mLatitude = mLatitude;
}
public Double getmLongitude()
{
return mLongitude;
}
public void setmLongitude(Double mLongitude)
{
this.mLongitude = mLongitude;
}
}
I'm sorry but I don't really understand your problem here. It seems that you know how to recover the map marker with you MyMarker object using HashMap. And you are also able to create all the markers you need. Since your question is about creating an application with HashMap and multiple markers, it seems that you already have done that. Unless your code doesn't work but in this situation it would be helpfull if you told us about what it does exactly.
I'm not sure about what you are asking, but I believe that you have 5 marker, and you want to get the closest one. If your question is how to do that then I think you just have to loop on every marker and calculate their distance with the user's position to find the smallest one.
If you don't know how to calculate the distance, I personnaly use the distanceTo(Location) method of Location. Maybe it is not the best code but here is what it looks like :
public static double distanceTo(LatLng from, LatLng to) {
Location locationA = new Location("");
locationA.setLatitude(from.latitude);
locationA.setLongitude(from.longitude);
Location locationB = new Location("");
locationB.setLatitude(to.latitude);
locationB.setLongitude(to.longitude);
return locationA.distanceTo(locationB) / 1000;
}
You can for example do something like that :
Marker closest = null;
double minDistance;
for(Marker m : mMarkersHashMap.keySet()){
double distance = distanceTo(currentPos, m.getPosition())
if(closest == null || minDistance > distance){
closest = m;
minDistance = distance;
}
}
Wrote it quickly and haven't tested it but if you want to do it for the 5 closest markers I think this works :
Marker[] closest = new Marker[5];
double[] minDistance = new double[5];
for(Marker m : mMarkersHashMap.keySet()){
double distance = distanceTo(currentPos, m.getPosition())
for(int i = 4; i >=0; i--){
if(closest[i] == null || minDistance[i] > distance){
if(i < 4){
closest[i+1] = closest[i];
minDistance[i+1] = minDistance[i];
}
closest[i] = m;
minDistance[i] = distance;
} else {
break;
}
}
}
I am trying to build an app for an individual project. I have a database of latitude and longitude coordinates with associated levels of radioactivity. The app checks the users location and checks the distance between them and the points in the database. If this distance is less than say 15 meters, it will trigger a warning light.
I was able to get the app to read in the database and store it in an arraylist of classes. I was also able to get the GPS to update location every 2 meters. I want to add a for loop in the onLocationChange method so that the app checks against the database but I am not sure how to do this... how can I pass the "dataPoints" arraylist to the locationlistener method so that the onLocationChange can access it?? Is this completed incorrect? I have included my code below:
public class MainActivity extends Activity{
protected LocationManager locationManager;
protected LocationListener locationListener;
protected Context context;
TextView txtLat;
String lat;
String provider;
protected String latitude,longitude;
protected boolean gps_enabled,network_enabled;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txtLat = (TextView) findViewById(R.id.textview1);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 2, mLocationListener);
//read in datapoints from text file in assets folder and store in class "radioactivityData" in arrayList "dataPoints"
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(getAssets().open("combinedorderedData.txt")));
} catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
//Define and initialize the ArrayList
ArrayList<radioactivityData> dataPoints = new ArrayList<radioactivityData>(); //The ArrayList stores strings
String inLine; //Buffer to store the current line
try {
while ((inLine = reader.readLine()) != null) //Read line-by-line, until end of file
{
String[] parts = inLine.split(" ");
radioactivityData rad = new radioactivityData();
rad.setlatitude(Double.parseDouble(parts[0]));
rad.setlongitude(Double.parseDouble(parts[1]));
rad.setradioactivity(Integer.parseInt(parts[2]));
dataPoints.add(rad);
}
} catch (NumberFormatException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
reader.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} //We've finished reading the file
}
//I think I just need to pass the dataPoints array to the LocationListener method... how? is this wrong?
LocationListener mLocationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
txtLat = (TextView) findViewById(R.id.textview1);
txtLat.setText("Latitude:" + location.getLatitude() + ", Longitude:" + location.getLongitude());
//Here I want to calculate the distance between current location and the data in the dataPoints array
for(int i=0; i<dataPoints.size(); i++){
if(getdistance(dataPoints.get(i).getlatitude(), dataPoints.get(i).getlongitude(),
location.getLatitude(), location.getLongitude())<15 && dataPoints.get(i).getradiation()>5000)
{
txtLat.setText("Turn on the green LED!");
break;
}
else
{
txtLat.setText("No radioactive areas nearby!");
}
}
}
#Override
public void onProviderDisabled(String provider) {
Log.d("Latitude","disable");
}
#Override
public void onProviderEnabled(String provider) {
Log.d("Latitude","enable");
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.d("Latitude","status");
}
private double getDistance(double lat1, double lon1, double lat2, double lon2){
double theta, dist;
theta = lon1 - lon2;
dist = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2)) + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.cos(deg2rad(theta));
dist = Math.acos(dist);
dist = rad2deg(dist);
dist = dist * 60 * 1.1515;
dist = dist * 1.609344 * 1000;
return (dist);
}
private double deg2rad(double deg) {
return (deg * Math.PI / 180);
}
private double rad2deg(double rad) {
return (rad * 180 / Math.PI);
}
};
}
Here is the radioactivityData class in case that would be helpful
public class radioactivityData {
private double latitude;
private double longitude;
private int radioactivity;
public double getlatitude()
{
return latitude;
}
public void setlatitude(double latitude) {
this.latitude = latitude;
}
public double getlongitude()
{
return longitude;
}
public void setlongitude(double longitude) {
this.longitude = longitude;
}
public int getradioactivity()
{
return radioactivity;
}
public void setradioactivity(int radioactivity) {
this.radioactivity = radioactivity;
}
}
from onLocationChanged call a method to which you will pass current location in that method itself get All Location with which you want to compare.
I want to run my Async Task which fetches the co-odinates with a certain accuracy and fires up a different activity if it gets co-ordinates.
Now I want to setup a time so that if it doesn't gets the co-ordinates with a set accuracy then the Async task should destroy itself (remove location updates etc.) and the default value for Lattitude/Longitude is passed.
I tried using this:
new GetGPShotfix().execute().get(1, TimeUnit.MINUTES); so as to set a timeout for this async for a min and then proceed onto the next line/task below this async execute call.
But in my case it skips over to the next line without waiting for the timeout set by Async.
How can I make it execute the way I want? I also tried using thread's join() but apparently results were same :(
Update:
Here's my code (for gpshotfix() Async):
private class GetGPShotfix extends AsyncTask<Void, Void, Void> {
// ProgressDialog progressDialogGPS;
#Override
protected void onPreExecute() {
super.onPreExecute();
Log.i("GPSfixer", "Ready to get GPS Hotfix");
}
#Override
protected Void doInBackground(Void... params) {
try {
LocationRetriever myLoc = new LocationRetriever();
// myLoc.getUserLoc();
//if (gotLoc == 0 && (firstLoc.getAccuracy() > 10)) {
if (gotLoc == 0) {
myLoc.getUserLoc();
}
} catch (Exception e) {
Log.i("GPSfixer", "GPS Hotfix Failed!", e);
}
finally {
Log.i("GPSfixer", "Get GPS Hotfix Completed...");
}
return null;
}
#Override
protected void onCancelled() {
Log.i("GPSfixer", "Get GPS Hotfix Cancelled");
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
Log.i("GPSfixer", "GPS Hotfix cycle completed");
System.out.println("Lon :" + myCurrentLon + "Lon2: " + finalLonNow);
System.out.println("Lat :" + myCurrentLat + "Lat2: " + finalLatNow);
//pDialog2.dismiss();
// progressDialogGPS.dismiss();
}
}
public class LocationRetriever {
final LocationManager locationManager = (LocationManager) StoreSelection.this.getSystemService(Context.LOCATION_SERVICE);
final LocationListener locationListener = new LocationListener() {
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(),
provider + " is disabled!", Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(),
"Please standby..enabling " + provider,
Toast.LENGTH_SHORT).show();
// explicitly enable GPS
Intent enableGPS = new Intent("android.location.GPS_ENABLED_CHANGE");
enableGPS.putExtra("enabled", true);
sendBroadcast(enableGPS);
// explictly disable GPS
/*
* Intent intent = new
* Intent("android.location.GPS_ENABLED_CHANGE");
* intent.putExtra("enabled", false); sendBroadcast(intent);
*/
}
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(),
provider + " is enabled..", Toast.LENGTH_SHORT).show();
}
public void onStatusChanged(String provider, int status,
Bundle extras) {
// TODO Auto-generated method stub
/*
* System.out.println("val of status: " + status + " provider: "
* + provider);
*/
if (status == 1) {
Toast.makeText(getApplicationContext(),
provider + " is enabled & available..",
Toast.LENGTH_SHORT).show();
System.out.println(provider + " is NOT available!");
} else {
System.out.println(provider + " is NOT available!");
}
/* progressDialogGPS.dismiss(); */
}
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
// ORIG CODE --BELOW--
// moved lat/lon vars to top ^
myCurrentLon = location.getLongitude();
myCurrentLat = location.getLatitude();
firstLoc = location;
myCurrentLon = Double.parseDouble(new DecimalFormat("##.#########")
.format(myCurrentLon));
myCurrentLat = Double.parseDouble(new DecimalFormat("##.#########")
.format(myCurrentLat));
/*Toast.makeText(getApplicationContext(),
myCurrentLat + " " + myCurrentLon, Toast.LENGTH_SHORT)
.show();*/
System.out.println(myCurrentLat + " " + myCurrentLon);
float acc=location.getAccuracy();
/*Toast.makeText(getApplicationContext(), "Acc.: " + acc,Toast.LENGTH_SHORT).show();*/
// --
// get best out of 2 locs. --BEGINS--
/*
* makeUseOfNewLocation(location);
*
* if(currentBestLocation == null){ currentBestLocation =
* location; }
*/
if (myCurrentLon != null && myCurrentLat != null && (firstLoc.getAccuracy() <= 10)) { // added
// chk
// for
// online..
gotLoc = 1;
System.out.println("OK GOTLOC == 1 !");
System.out.println("Got your Current Location..disabling GPS to save Battery Power..");
Toast.makeText(getApplicationContext(), "Got your Current Location..disabling GPS to save Battery Power..", Toast.LENGTH_SHORT).show();
// removing updates
// locationManager.removeUpdates(locationListener);
// explicitly turning off GPS
Intent intent = new Intent("android.location.GPS_ENABLED_CHANGE");
intent.putExtra("enabled", false);
sendBroadcast(intent);
System.out.println("GPS disabled!");
finalLatNow = myCurrentLat;
finalLonNow = myCurrentLon;
//
// if(gotLoc == 0){
if (myCurrentLon != null
&& myCurrentLat != null && (firstLoc.getAccuracy() <= 10)) {
// locationManager.removeUpdates(locationListener);
gotLoc = 1;
Intent i = new Intent(StoreSelection.this, LastVisitDetails.class);
i.putExtra("currUsrLon", myCurrentLon); // 2nd
i.putExtra("currUsrLat", myCurrentLat); // 1st
i.putExtra("storeID", selStoreID);
i.putExtra("selStoreName", selStoreName);
i.putExtra("imei", uuid);
i.putExtra("date", userDate);
runOnUiThread(new Runnable() {
public void run() {
try {
// stuff here
pDialog2.dismiss();
} catch (Exception e) {
e.printStackTrace();
}
}
});
System.out.println("--Removing Loc. Updates--");
remUpdates();
syncTIMESTAMP = System.currentTimeMillis();
Date dateobj = new Date(syncTIMESTAMP);
SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
fullFileName1 = df.format(dateobj);
dbengine.open();
dbengine.UpdateStoreStartVisit(selStoreID, fullFileName1);
dbengine.close();
startActivity(i);
finish();
} else {
if (myCurrentLon == null && myCurrentLat == null) {
// alert + GPS not locking on..do something()
} else {
}
/*if (!isOnline()) {
// alert + not online...do something()
showNoConnAlert();
} else {
}*/
}
//
/*
* } else{}
*/
} else {
System.out.println("INSIDE ELSE -- GOTLOC");
}
}
};
// locationManager.requestLocationUpdates(locationManager.getBestProvider(new
// Criteria(), true), 2000, 4, locationListener);
// enable gps everytime we request location update
/*
* Intent enableGPS = new Intent("android.location.GPS_ENABLED_CHANGE");
* enableGPS.putExtra("enabled", true); sendBroadcast(enableGPS);
*/
// ** ORIG Grequest location updates from GPS string
/*
* locationManager.requestLocationUpdates(locationManager.GPS_PROVIDER,
* ONE_MIN, 4, locationListener);
*/
// ** now remove updating of co-ordinates
// locationManager.removeUpdates(locationListener);
/*public Location getBestLoc(){
if(firstLoc.getAccuracy() <= newLoc.getAccuracy() && newLoc.getAccuracy() <= 10) {
return firstLoc;
}
else if(newLoc.getAccuracy() <= firstLoc.getAccuracy() && newLoc.getAccuracy() <= 10){
return newLoc;
}
else {
return newLoc;
}
}*/
void getUserLoc() {
if (gotLoc == 1 && (firstLoc.getAccuracy() <= 10)) {
locationManager.removeUpdates(locationListener);
} else {
}
final Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setHorizontalAccuracy(Criteria.ACCURACY_FINE);
// criteria.setVerticalAccuracy(Criteria.NO_REQUIREMENT);
criteria.setAltitudeRequired(false);
// criteria.setBearingAccuracy(Criteria.NO_REQUIREMENT);
criteria.setBearingRequired(false);
criteria.setCostAllowed(true);
criteria.setPowerRequirement(Criteria.POWER_HIGH);
runOnUiThread(new Runnable() {
public void run() {
try {
// stuff here
/*
* progressDialogGPS = ProgressDialog.show(_activity,
* null, null);
* progressDialogGPS.setContentView(R.layout.loader);
* progressDialogGPS
* .getWindow().setType(WindowManager.LayoutParams
* .TYPE_KEYGUARD_DIALOG);
*/
/*locationManager
.requestLocationUpdates(locationManager
.getBestProvider(criteria, true),
TEN_SECS, 4, locationListener);*/
locationManager.requestLocationUpdates(locationManager.GPS_PROVIDER, 0l, 0.0f, locationListener);
// remove updates #
if (gotLoc == 1 && (firstLoc.getAccuracy() <= 10)) {
locationManager.removeUpdates(locationListener);
} else {
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
/*
* try { Thread.currentThread().sleep(2000); } catch
* (InterruptedException e) { // TODO Auto-generated catch block
* e.printStackTrace(); }
*/
}
void remUpdates() {
//if(firstLoc.getAccuracy() <= 10){
locationManager.removeUpdates(locationListener);
//}
//else {}
}
}
Any help is appreciable..
When using execute.get(1, TimeUnit.MINUTES) it converts async task to synchronus. Using async task is of no use in that case. You can start a separate thread when starting asynctask to keep a watch for time and do the required operation after that. You can create a class implmenting runnable and pass asyctask as constructor argument and cancel it inside.
class checkAyscTask implements Runnable {
AsyncTask<Void, Void, Boolean> mAT;
Context context;
public checkAyscTask(AsyncTask<Void, Void, Boolean> at) {
mAT = at;
}
#Override
public void run() {
mHandler.postDelayed(runnable, 60000);
// After 60sec the task in run() of runnable will be done
}
Handler mHandler = new Handler();
Runnable runnable = new Runnable() {
#Override
public void run() {
if (mAT.getStatus() == Status.RUNNING || mAT.getStatus() == Status.PENDING) {
mAT.cancel(true); //Cancel Async task or do the operation you want after 1 minute
}
}
};
}
task_GetGPS = new GetGPShotfix();
task_GetGPS.execute();
checkAyscTask chk = new checkAyscTask(task_GetGPS);
// Thread keeping 1 minute time watch
(new Thread(chk)).start();