from this i'm getting latitude and longitude in a single textview. But I want the latitude to be in 1 textview and longitude in another text view. Please help me on this.
My main activity
package com.shopping.myapplication;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
Button addressButton;
TextView addressTV;
TextView latLongTV;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
addressTV = (TextView) findViewById(R.id.addressTV);
addressButton = (Button) findViewById(R.id.addressButton);
addressButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
EditText editText = (EditText) findViewById(R.id.addressET);
String address = editText.getText().toString();
GeocodingLocation locationAddress = new GeocodingLocation();
locationAddress.getAddressFromLocation(address,
getApplicationContext(), new GeocoderHandler());
}
});
}
private class GeocoderHandler extends Handler {
@Override
public void handleMessage(Message message) {
String locationAddress;
switch (message.what) {
case 1:
Bundle bundle = message.getData();
locationAddress = bundle.getString("address");
break;
default:
locationAddress = null;
}
latLongTV.setText(locationAddress);
}
}
}
my geocodinglocation class.java
package com.shopping.myapplication;
import android.content.Context;
import android.location.Address;
import android.location.Geocoder;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
public class GeocodingLocation {
private static final String TAG = "GeocodingLocation";
public static void getAddressFromLocation(final String locationAddress,
final Context context, final Handler handler) {
Thread thread = new Thread() {
@Override
public void run() {
Geocoder geocoder = new Geocoder(context, Locale.getDefault());
String result = null;
try {
List
addressList = geocoder.getFromLocationName(locationAddress, 1);
if (addressList != null && addressList.size() > 0) {
Address address = (Address) addressList.get(0);
StringBuilder sb = new StringBuilder();
sb.append(address.getLatitude()).append("\n");
sb.append(address.getLongitude()).append("\n");
result = sb.toString();
}
} catch (IOException e) {
Log.e(TAG, "Unable to connect to Geocoder", e);
} finally {
Message message = Message.obtain();
message.setTarget(handler);
if (result != null) {
message.what = 1;
Bundle bundle = new Bundle();
result = "Address: " locationAddress
"\n\nLatitude and Longitude :\n" result;
bundle.putString("address", result);
message.setData(bundle);
} else {
message.what = 1;
Bundle bundle = new Bundle();
result = "Address: " locationAddress
"\n Unable to get Latitude and Longitude for this address location.";
bundle.putString("address", result);
message.setData(bundle);
}
message.sendToTarget();
}
}
};
thread.start();
}
}
from this i'm getting latitude and longitude in a single textview. But I want the latitude to be in 1 textview and longitude in another text view. Please help me on this.
CodePudding user response:
Please correct me if I'm wrong, but it appears that you are getting lat long as a single string for the address. Inside run()
method for the thread, there are these lines:
sb.append(address.getLatitude()).append("\n");
sb.append(address.getLongitude()).append("\n");
result = sb.toString();
As you can see, you can get latitued and longitude from the address object here directly! There are many ways you can go about this. You can stick the lat and long values into the bundle if you wish. According to
Here is main activity:
import androidx.appcompat.app.AppCompatActivity;
import android.location.Address;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
Button addressButton;
TextView addressTV;
TextView latTV;
TextView longTV;
EditText editText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
addressTV = findViewById(R.id.addressTV);
latTV = findViewById(R.id.latTV);
longTV = findViewById(R.id.longTV);
addressButton = findViewById(R.id.addressButton);
editText = (EditText) findViewById(R.id.addressET);
addressButton.setOnClickListener(arg0 -> {
String address = editText.getText().toString();
GeocodingLocation locationAddress = new GeocodingLocation();
locationAddress.getAddressFromLocation(address,
getApplicationContext(), new GeocoderHandler());
});
}
private class GeocoderHandler extends Handler {
@Override
public void handleMessage(Message message) {
switch (message.what) {
case 1:
Bundle bundle = message.getData();
Address address = bundle.getParcelable("address");
latTV.setText(address.getLatitude() "");
longTV.setText(address.getLongitude() "");
break;
case 2:
addressTV.setText("unable to get address");
}
}
}
}
Notes: I simplified some things here for you, but its essentially the same. Important point however is that you can stick Parcable
objects directly into the bundle, and since Address
objects are Parcable
, you can put the Address
object directly into the bundle!
Here is the geo coding location class:
import android.content.Context;
import android.location.Address;
import android.location.Geocoder;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
public class GeocodingLocation {
private static final String TAG = "GeocodingLocation";
public static void getAddressFromLocation(final String locationAddress,
final Context context, final Handler handler) {
Thread thread = new Thread() {
@Override
public void run() {
Geocoder geocoder = new Geocoder(context, Locale.getDefault());
Message message = Message.obtain();
message.setTarget(handler);
try {
List addressList = geocoder.getFromLocationName(locationAddress, 1);
if (addressList != null && addressList.size() > 0) {
Address address = (Address) addressList.get(0);
message.what = 1;
Bundle bundle = new Bundle();
bundle.putParcelable("address", address);
message.setData(bundle);
}
} catch (IOException e) {
Log.e(TAG, "IOException", e);
message.what = 2;
}
message.sendToTarget();
}
};
thread.start();
}
}
Note: here I simplified your code a little bit also. Personally (and I think most people will agree), I like to code in a way that uses least indentations, but is still interpretable. Instead of doing try catch finally
I just placed the correct pieces of code in try
and catch
separately, so there is no longer the need for finally
clause at all.
Before you had a message with address string, and in the catch clause you would put the string "unable to get address for location" into bundle with key "address":
Bundle bundle = new Bundle();
result = "Address: " locationAddress
"\n\nLatitude and Longitude :\n" result;
bundle.putString("address", result);
The result
string doesn't contain an address, but rather an error message, so its probably not a good idea to put it in bundle with "address" key (because its an error message). I did it slightly differently, I set message.what property to message.what = 2;
, and made that a case
in the switch
inside the main activity.
I hope this helps you further! :D