• Add the following code to res/layout/activity_main.xml.
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <TextView android:layout_marginTop="20dp" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Get Current Location and City Name" android:textAlignment="center" android:layout_centerHorizontal="true" android:textSize="20sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/textView" android:layout_centerInParent="true" android:textSize="16sp" android:textStyle="bold"/> </RelativeLayout>
• Add the following dependency in Gradle
implementation 'com.google.android.gms:play-services-location:17.0.0'
• Add the following code to src/MainActivity.java
import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import android.Manifest; import android.content.Intent; import android.content.pm.PackageManager; import android.location.Geocoder; import android.location.Location; import android.os.Bundle; import android.os.Handler; import android.os.ResultReceiver; import android.util.Log; import android.widget.TextView; import android.widget.Toast; import com.google.android.gms.location.FusedLocationProviderClient; import com.google.android.gms.location.LocationCallback; import com.google.android.gms.location.LocationRequest; import com.google.android.gms.location.LocationResult; import com.google.android.gms.location.LocationServices; public class MainActivity extends AppCompatActivity { private FusedLocationProviderClient fusedLocationClient; private static final int LOCATION_PERMISSION_REQUEST_CODE = 2; private LocationAddressResultReceiver addressResultReceiver; private TextView currentAddTv; private Location currentLocation; private LocationCallback locationCallback; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); addressResultReceiver = new LocationAddressResultReceiver(new Handler()); currentAddTv = findViewById(R.id.textView); fusedLocationClient = LocationServices.getFusedLocationProviderClient(this); locationCallback = new LocationCallback() { @Override public void onLocationResult(LocationResult locationResult) { currentLocation = locationResult.getLocations().get(0); getAddress(); } }; startLocationUpdates(); } @SuppressWarnings("MissingPermission") private void startLocationUpdates() { if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION_PERMISSION_REQUEST_CODE); } else { LocationRequest locationRequest = new LocationRequest(); locationRequest.setInterval(2000); locationRequest.setFastestInterval(1000); locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, null); } } @SuppressWarnings("MissingPermission") private void getAddress() { if (!Geocoder.isPresent()) { Toast.makeText(MainActivity.this, "Can't find current address, ", Toast.LENGTH_SHORT).show(); return; } Intent intent = new Intent(this, GetAddressIntentService.class); intent.putExtra("add_receiver", addressResultReceiver); intent.putExtra("add_location", currentLocation); startService(intent); } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (requestCode == LOCATION_PERMISSION_REQUEST_CODE) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { startLocationUpdates(); } else { Toast.makeText(this, "Location permission not granted, " + "restart the app if you want the feature", Toast.LENGTH_SHORT).show(); } } } private class LocationAddressResultReceiver extends ResultReceiver { LocationAddressResultReceiver(Handler handler) { super(handler); } @Override protected void onReceiveResult(int resultCode, Bundle resultData) { if (resultCode == 0) { Log.d("Address", "Location null retrying"); getAddress(); } if (resultCode == 1) { Toast.makeText(MainActivity.this, "Address not found, ", Toast.LENGTH_SHORT).show(); } String currentAdd = resultData.getString("address_result"); showResults(currentAdd); } } private void showResults(String currentAdd) { currentAddTv.setText(currentAdd); } @Override protected void onResume() { super.onResume(); startLocationUpdates(); } @Override protected void onPause() { super.onPause(); fusedLocationClient.removeLocationUpdates(locationCallback); } }
• Create a new java class GetaddressIntentService.java and add the following code
package app.com.sample; import android.app.IntentService; import android.content.Intent; import android.location.Address; import android.location.Geocoder; import android.location.Location; import android.os.Bundle; import android.os.ResultReceiver; import android.util.Log; import java.util.List; import java.util.Locale; import java.util.Objects; import androidx.annotation.Nullable; public class GetAddressIntentService extends IntentService { private static final String IDENTIFIER = "GetAddressIntentService"; private ResultReceiver addressResultReceiver; public GetAddressIntentService() { super(IDENTIFIER); } @Override protected void onHandleIntent(@Nullable Intent intent) { String msg; addressResultReceiver = Objects.requireNonNull(intent).getParcelableExtra("add_receiver"); if (addressResultReceiver == null) { Log.e("GetAddressIntentService", "No receiver, not processing the request further"); return; } Location location = intent.getParcelableExtra("add_location"); if (location == null) { msg = "No location, can't go further without location"; sendResultsToReceiver(0, msg); return; } Geocoder geocoder = new Geocoder(this, Locale.getDefault()); List<Address> addresses = null; try { addresses = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1); } catch (Exception ioException) { Log.e("", "Error in getting address for the location"); } if (addresses == null || addresses.size() == 0) { msg = "No address found for the location"; sendResultsToReceiver(1, msg); } else { Address address = addresses.get(0); String addressDetails = address.getFeatureName() + "\n" + address.getThoroughfare() + "\n" + "Locality: " + address.getLocality() + "\n" + "County: " + address.getSubAdminArea() + "\n" + "State: " + address.getAdminArea() + "\n" + "Country: " + address.getCountryName() + "\n" + "Postal Code: " + address.getPostalCode() + "\n"; sendResultsToReceiver(2, addressDetails); } } private void sendResultsToReceiver(int resultCode, String message) { Bundle bundle = new Bundle(); bundle.putString("address_result", message); addressResultReceiver.send(resultCode, bundle); } }
• Add the following code to androidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="app.com.sample"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name=".GetAddressIntentService" /> </application> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> </manifest>
OutPut