I'm writing a small application that get your location every 10 seconds and puts Latitude and Longitude into a JSON object. Than it should write Lat and Lon into a file in External Storage. I made run the application and I can see the file.json but there's only a string Lon into. Instead it should write a couple of values Lon Lat every time the location changes. What is the problem?
Here is the code:
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.widget.TextView;
import android.util.Log;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.logging.Logger;
public class MainActivity extends AppCompatActivity implements LocationListener {
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;
JSONObject jsonObject;
FileOutputStream outputStream;
String latlon;
String filename;
File sdCardFile;
FileWriter fw;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txtLat = (TextView) findViewById(R.id.textview1);
filename="salvataggi.json";
sdCardFile = new File(getExternalFilesDir(null), filename);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000, 0, this);
}
#Override
public void onLocationChanged(Location location) {
txtLat = (TextView) findViewById(R.id.textview1);
txtLat.setText("Latitude:" + location.getLatitude() + ", Longitude:" + location.getLongitude());
try {
jsonObject = new JSONObject();
jsonObject.put("Lat", location.getLatitude());
jsonObject.put("Lon", location.getLongitude());
latlon=jsonObject.toString();
writeToFile(latlon, sdCardFile, fw);
}catch (JSONException je) { }
}
public static void writeToFile(String latlon, File sdCardFile, FileWriter fw) {
try{
fw = new FileWriter(sdCardFile, true);
fw.write(latlon);
fw.flush();
fw.close();
}catch(Exception e){
e.printStackTrace();
}
}
Where am I doing wrong?
When you request location updates at a certain interval, you have no guarantee that you will receive updates at exactly that interval. According to the javadoc, all you can be certain of is that the updates will occur no faster than the given time duration. If the GPS isn't getting updated locations, the listener may never be called at all. It can take some time to get a GPS lock in the first place.
If you really need to provide some coordinate every 10 seconds, consider using a Handler to schedule a Runnable every 10 seconds that polls the value of getLastKnownLocation and makes sure the return value is not null. That returned Location may not be accurate, but it's at least something.
Related
I am attempting to write longitude and latitude values to a text file each time the location changes. The result of which should be a text file, stored on an SD card, that contains a list of longitude and latitude values. The application successfully gets the longitude and latitude and the toast notification pops up saying the file has been saved successfully. However, I cannot find the text file in the root of the SD card.
Here is the code:
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity
{
TextView textlat;
TextView textlong;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textlat = (TextView)findViewById(R.id.textlat);
textlong = (TextView)findViewById(R.id.textlong);
LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
LocationListener ll = new mylocationlistener();
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER,
10000, 0, ll);
}
private class mylocationlistener implements LocationListener
{
#Override
public void onLocationChanged(Location location)
{
if (location != null)
{
double pLong = location.getLongitude();
double pLat = location.getLatitude();
textlat.setText(Double.toString(pLat));
textlong.setText(Double.toString(pLong));
try
{
File myFile = new File("/sdcard/mysdfile.txt");
myFile.createNewFile();
FileOutputStream fOut = new FileOutputStream(myFile);
OutputStreamWriter myOutWriter =
new OutputStreamWriter(fOut);
myOutWriter.append(textlat.getText());
myOutWriter.close();
fOut.close();
Toast.makeText(getBaseContext(),
"Done writing SD 'mysdfile.txt'",
Toast.LENGTH_SHORT).show();
}
catch (Exception e)
{
Toast.makeText(getBaseContext(), e.getMessage(),
Toast.LENGTH_SHORT).show();
}
}
}
#Override
public void onProviderDisabled(String provider)
{
}
#Override
public void onProviderEnabled(String provider)
{
}
#Override
public void onStatusChanged(String provider, int status,
Bundle extras)
{
}
}
}
So basically, where is the file with the location values? I feel I'm missing something really obvious here...
You should not try to write to the root folder of the sdcard. This will fail due to security issues. Try this instead:
File dir = Environment.getExternalStoragePublicDirectory();
File myFile = new File(dir, "mysdfile.txt");
You can then later find the file in the directory dir. If you want the file to be private to your app, use Context.getExternalFilesDir() instead of Environment.getExternalStoragePublicDirectory().
Also check out the guide topic on Storage Options
I am an android beginner and I need your help! I am building a very simple running app and would like to have gather information about the speed. For this I am trying to create a very simple GPS class in order to use the getspeed() method.
I have created a little test app to ensure that my code is sound. In this app I am using getLatitude() and getLongitude() too but these will not be useful for my final code - I only need the speed really.
So far, I have managed to successfully test the class on the emulator but not on the phone. I can see the coordinates being populated on the screen when using the DDMS coordinates (getspeed() remained 0 but I know I cant test that on the emulator). When I try the code on my phone I have no response at all - despite waiting for the GPS to "warm up" (I also see that he GPS works when I move to GoogleMaps).
The whole things is driving me crazy, I am not sure what is happening with the onLocationChanged() method so appreciate any help you can give me.
Thanks!
The code is as per below:
import android.app.Activity;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
TextView speedText1, speedText2, speedText3;
double speed = 0;
double latitude = 0;
double longitude = 0;
String speed1;
String latitude1;
String longitude1;
boolean gps_enabled;
Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
gps_enabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
Toast.makeText(getBaseContext(), "location not null" , Toast.LENGTH_SHORT).show();
speedText1 = (TextView) findViewById(R.id.textView1);
speedText2 = (TextView) findViewById(R.id.textView2);
speedText3 = (TextView) findViewById(R.id.textView3);
speed = location.getSpeed();
speed1 = Double.toString(speed);
speedText1.setText(speed1);
latitude = location.getLatitude();
latitude1 = Double.toString(latitude);
speedText2.setText(latitude1);
longitude = location.getLongitude();
longitude1 = Double.toString(longitude);
speedText3.setText(longitude1);
Toast.makeText(getBaseContext(), latitude1 + longitude1 + speed , Toast.LENGTH_SHORT).show();
}
public void onStatusChanged(String provider, int status, Bundle extras) {
}
public void onProviderEnabled(String provider) {
}
public void onProviderDisabled(String provider) {
} };
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
}
}
You are defining the LocationListener inside the onCreate() method, so you will not get location updates once that method finishes. You should try something like this:
import android.app.Activity;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity implements LocationListener {
TextView speedText1, speedText2, speedText3;
double speed = 0;
double latitude = 0;
double longitude = 0;
String speed1;
String latitude1;
String longitude1;
boolean gps_enabled;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1, 0.0f, this);
gps_enabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
Toast.makeText(this, "location not null" , Toast.LENGTH_SHORT).show();
speedText1 = (TextView) findViewById(R.id.textView1);
speedText2 = (TextView) findViewById(R.id.textView2);
speedText3 = (TextView) findViewById(R.id.textView3);
}
#Override
public void onLocationChanged(Location location) {
speed = location.getSpeed();
speed1 = Double.toString(speed);
speedText1.setText(speed1);
latitude = location.getLatitude();
latitude1 = Double.toString(latitude);
speedText2.setText(latitude1);
longitude = location.getLongitude();
longitude1 = Double.toString(longitude);
speedText3.setText(longitude1);
Toast.makeText(this, latitude1 + longitude1 + speed, Toast.LENGTH_SHORT).show();
}
}
}
Hi I want to get location from cell tower(Sim card) without internet. I had used below mentioned code it's give me only last location when network available.
my requirement is to get location without WiFi or internet. can it's possible?
package com.example.gpscelltower;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
public class CellTowerActivity1 extends Activity {
private static final String TAG = "Cell";
private static LocationManager locationManager;
private static LocationListener locationListener;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cell_tower);
locationManager=(LocationManager)getSystemService(Context.LOCATION_SERVICE);
String providerName=LocationManager.NETWORK_PROVIDER;
Location location=locationManager.getLastKnownLocation(providerName);
updateWithLocation(location);
//Cell-ID and WiFi location updates.
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000, 0, locationListener);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, locationListener);
locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
Log.d("TAG", "locationListner");
updateWithLocation(location);
String Text = "My current location is: " + "Latitude = "+ location.getLatitude() + "Longitude = " + location.getLongitude();
Toast.makeText(getApplicationContext(), Text, Toast.LENGTH_LONG).show();
Log.d("TAG", "Starting..");
}
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.d("TAG", "onSatatus");
}
public void onProviderEnabled(String provider) {
Log.d("TAG", "onProviderEnable");
}
public void onProviderDisabled(String provider) {
Log.d("TAG", "onProviderDisble");
}
};
}
private void updateWithLocation(Location location) {
Log.d("TAG", "UpdateWithLocation");
String displayString;
if(location!=null){
Double lat=location.getLatitude();
Double lng=location.getLongitude();
Long calTime=location.getTime();
DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss.SSS");
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(calTime);
String time=formatter.format(calendar.getTime()).toString();
displayString="The Lat: "+lat.toString()+" \nAnd Long: "+lng.toString()+"\nThe time of Calculation: "+time;
}else{
displayString="No details Found";
}
Toast.makeText(CellTowerActivity1.this, ""+displayString, Toast.LENGTH_LONG).show();
}
}
Cell geolocation works through sending Cell towers IDs to server which maps it to coordinates. So, unfortunately it's not posssible to get your coordinates w/o data connection with standard APIs.
I've been trying to work GPS coordinates but it's been a lot tougher than I thought. After a few hours of trial and error, I've managed to output the latitude and longitude (mocked) for my emulator. Below are the 2 ways I've done it:
First way:
import java.io.IOException;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;
import android.app.Activity;
import android.content.Context;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.widget.TextView;
public class MainActivity extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String text = "";
LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Location location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(location != null) {
showMyAddress(location);
}
final LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
showMyAddress(location);
}
public void onProviderDisabled(String arg0) {
}
public void onProviderEnabled(String arg0) {
}
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
}
};
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30000, 10, locationListener);
double longitude = location.getLongitude();
double latitude = location.getLatitude();
Log.i(TAG, "longitude: " + longitude);
Log.i(TAG, "latitude: " + latitude);
text = "longitude: " + longitude + ", " + "latitude: " + latitude;
TextView textView = (TextView) findViewById(R.id.txtvwMain);
textView.setText(text);
}
private void showMyAddress(Location location) {
double latitude = location.getLatitude();
double longitude = location.getLongitude();
Geocoder myLocation = new Geocoder(getApplicationContext(), Locale.getDefault());
List<Address> myList;
try {
myList = myLocation.getFromLocation(latitude, longitude, 1);
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
Second way:
import android.app.Activity;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
public class MainActivity extends Activity implements LocationListener
{
private LocationManager lm;
private TextView tv;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.txtvwMain);
lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 500, 1, this);
Location location = lm.getLastKnownLocation(lm.GPS_PROVIDER);
double longitude = location.getLongitude();
double latitude = location.getLatitude();
tv.setText("latitude="+latitude+", longitude="+longitude);
}
#Override
public void onLocationChanged(Location arg0) {
String lat = String.valueOf(arg0.getLatitude());
String lon = String.valueOf(arg0.getLongitude());
Log.e("GPS", "location changed: lat="+lat+", lon="+lon);
tv.setText("lat="+lat+", lon="+lon);
}
public void onProviderDisabled(String arg0) {
Log.e("GPS", "provider disabled " + arg0);
}
public void onProviderEnabled(String arg0) {
Log.e("GPS", "provider enabled " + arg0);
}
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
Log.e("GPS", "status changed to " + arg0 + " [" + arg1 + "]");
}
}
Both ways above work and print out the mock latitude and longitude onto a TextView in the emulator (running Android 4.2.2). However, when I upload the .apk file onto my device (tablet running Android 4.0.4), it just crashes. I don't know what's wrong because I can't see any error messages. What is the source of the problem and how may I go about solving it? Thanks.
Following is the coding i got from some one else work. I am trying to implement bit of his work with necessary changes in my app. The problem here is that it is not returning the proper address when the GET ADDRESS button is clicked. Besides, it works only with the wifi/mobile network but not with the GPS. Meanwhile, i wonder how to make auto-posting of data to sever when the call is making to a contact. Thank you!
package com.yang.address;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.app.Activity;
import android.content.Context;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class AddressActivity extends Activity {
/** Called when the activity is first created. */
Double lat, lon;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button btnLocation = (Button)findViewById(R.id.btnLocation);
btnLocation.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
// Acquire a reference to the system Location Manager
LocationManager locationManager = (LocationManager) AddressActivity.this.getSystemService(Context.LOCATION_SERVICE);
// Define a listener that responds to location updates
LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
// Called when a new location is found by the network location provider.
lat = location.getLatitude();
lon = location.getLongitude();
TextView tv = (TextView) findViewById(R.id.txtLoc);
tv.setText("Your Location is:" + lat + "--" + lon);
}
public void onStatusChanged(String provider, int status, Bundle extras) {}
public void onProviderEnabled(String provider) {}
public void onProviderDisabled(String provider) {}
};
// Register the listener with the Location Manager to receive location updates
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
}
});
Button btnSend = (Button)findViewById(R.id.btnSend);
btnSend.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
postData(lat, lon);
}
});
Button btnAdd = (Button)findViewById(R.id.btnAddress);
btnAdd.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
TextView tv = (TextView)findViewById(R.id.txtAddress);
tv.setText(GetAddress(lat, lon));
}
});
}
public void postData(Double lat2, Double lon2) {
// Create a new HttpClient and Post Header
HttpClient httpclient = new DefaultHttpClient();
HttpGet htget = new HttpGet("http://myappurl.com/Home/Book/"+lat2+"/"+lon2);
try {
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(htget);
String resp = response.getStatusLine().toString();
Toast.makeText(this, resp, 5000).show();
} catch (ClientProtocolException e) {
Toast.makeText(this, "Error", 5000).show();
} catch (IOException e) {
Toast.makeText(this, "Error", 5000).show();
}
}
public String GetAddress(Double lat2, Double lon2)
{
Geocoder geocoder = new Geocoder(this, Locale.ENGLISH);
String ret = "";
try {
List<Address> addresses = geocoder.getFromLocation(lat2,lon2, 1);
if(addresses != null) {
Address returnedAddress = addresses.get(0);
StringBuilder strReturnedAddress = new StringBuilder("Address:\n");
for(int i=0; i<returnedAddress.getMaxAddressLineIndex(); i++) {
strReturnedAddress.append(returnedAddress.getAddressLine(i)).append("\n");
}
ret = strReturnedAddress.toString();
}
else{
ret = "No Address returned!";
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
ret = "Can't get Address!";
}
return ret;
}
}
Looks like you've made some progress since your last question.
First off, the LocationManager system on androids is Listening Service in that you register it as a listener and allow the OS to notify when updates are made. This means you should have the code you put in your OnClick method run before you need it. Your best option is to have the OnCreate method of your Activity register the listener as the Activity starts and use the onLocationChanged callback as a way to store the new Location on a class variable.
private Location lastKnownLocation;
private TextView tv;
public void onCreate(Bundle savedInstanceState) {
//....
setupLocationServices();
//....
tv = (TextView) findViewById(R.id.txtLoc);
Button btnLocation = (Button)findViewById(R.id.btnLocation);
btnLocation.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
updateLocation();
}
});
//....
}
private void setupLocationServices() {
//....
LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
// Called when a new location is found by the network location provider.
lastKnownLocation = location;
updateLocation();
}
....
}
private void updateLocation() {
double lat = lastKnownLocation.getLatitude();
double lat = lastKnownLocation.getLongitude();
tv.setText("Your Location is:" + lat + "--" + lon);
}
As for your reasoning as to why it doesn't work with GPS it is because you never register the GPS listener. Where you have this line:
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
You would need to substitude in this value:
LocationManager.GPS_PROVIDER
Again, as I recommended before I really suggest taking the time to fully understand the Android Developer documentation
As for your other problem regarding listening to the state of incoming calls you should start off by checking the TelephonyManager documentation here. Specifically look for the use of ACTION_PHONE_STATE_CHANGED and its extras for incoming calls. For outgoing calls google the use of ACTION_NEW_OUTGOING_CALL Intents.