问题
I want to get my current location in the form of an address by GPS. I am using the android studio. It is saying that my application stops working. What is the error in it? Can someone help me to get out of this, please?
My Code in activity_main.xml file is
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
My code in MainActivity.java is
package com.example.showlatlong;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.TextView;
import java.util.List;
import java.util.Locale;
public class MainActivity extends AppCompatActivity {
Location gps_loc, network_loc, final_loc;
double longitude;
double latitude;
String userCountry, userAddress;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = findViewById(R.id.text_view);
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_NETWORK_STATE) != PackageManager.PERMISSION_GRANTED) {
return;
}
try {
gps_loc = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
network_loc = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
} catch (Exception e) {
e.printStackTrace();
}
if (gps_loc != null) {
final_loc = gps_loc;
latitude = final_loc.getLatitude();
longitude = final_loc.getLongitude();
}
else if (network_loc != null) {
final_loc = network_loc;
latitude = final_loc.getLatitude();
longitude = final_loc.getLongitude();
}
else {
latitude = 0.0;
longitude = 0.0;
}
ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_NETWORK_STATE}, 1);
try {
Geocoder geocoder = new Geocoder(this, Locale.getDefault());
List<Address> addresses = geocoder.getFromLocation(latitude, longitude, 1);
if (addresses != null && addresses.size() > 0) {
userCountry = addresses.get(0).getCountryName();
userAddress = addresses.get(0).getAddressLine(0);
tv.setText(userCountry + ", " + userAddress);
}
else {
userCountry = "Unknown";
tv.setText(userCountry);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
My code in manifest.xml is
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<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>
</application>
The entire code is this. It is opening the app and in less than a second, it is closing by throwing an error message that "app keeps stopping" on my android application. This is what I got in the logcat is
2019-09-11 12:58:45.344 15400-15400/com.example.showlatlong E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.showlatlong, PID: 15400
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.showlatlong/com.example.showlatlong.MainActivity}: android.view.InflateException: Binary XML file line #2: Binary XML file line #2: Error inflating class android.support.constraint.ConstraintLayout
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2723)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2784)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1523)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:163)
at android.app.ActivityThread.main(ActivityThread.java:6238)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:933)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
Caused by: android.view.InflateException: Binary XML file line #2: Binary XML file line #2: Error inflating class android.support.constraint.ConstraintLayout
Caused by: android.view.InflateException: Binary XML file line #2: Error inflating class android.support.constraint.ConstraintLayout
Caused by: java.lang.ClassNotFoundException: Didn't find class "android.support.constraint.ConstraintLayout" on path: DexPathList[[zip file "/data/app/com.example.showlatlong-1/base.apk", zip file "/data/app/com.example.showlatlong-1/split_lib_dependencies_apk.apk", zip file "/data/app/com.example.showlatlong-1/split_lib_slice_0_apk.apk", zip file "/data/app/com.example.showlatlong-1/split_lib_slice_1_apk.apk", zip file "/data/app/com.example.showlatlong-1/split_lib_slice_2_apk.apk", zip file "/data/app/com.example.showlatlong-1/split_lib_slice_3_apk.apk", zip file "/data/app/com.example.showlatlong-1/split_lib_slice_4_apk.apk", zip file "/data/app/com.example.showlatlong-1/split_lib_slice_5_apk.apk", zip file "/data/app/com.example.showlatlong-1/split_lib_slice_6_apk.apk", zip file "/data/app/com.example.showlatlong-1/split_lib_slice_7_apk.apk", zip file "/data/app/com.example.showlatlong-1/split_lib_slice_8_apk.apk", zip file "/data/app/com.example.showlatlong-1/split_lib_slice_9_apk.apk"],nativeLibraryDirectories=[/data/app/com.example.showlatlong-1/lib/arm64, /system/lib64, /vendor/lib64]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:380)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
at android.view.LayoutInflater.createView(LayoutInflater.java:613)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:812)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:752)
at android.view.LayoutInflater.inflate(LayoutInflater.java:499)
at android.view.LayoutInflater.inflate(LayoutInflater.java:430)
at android.view.LayoutInflater.inflate(LayoutInflater.java:377)
at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:555)
at androidx.appcompat.app.AppCompatActivity.setContentView(AppCompatActivity.java:161)
at com.example.showlatlong.MainActivity.onCreate(MainActivity.java:29)
at android.app.Activity.performCreate(Activity.java:6857)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2676)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2784)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1523)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:163)
at android.app.ActivityThread.main(ActivityThread.java:6238)
at java.lang.reflect.Method.invoke(Native Method)
at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.
java:933)
2019-09-11 12:58:45.344 15400-15400/com.example.showlatlong
E/AndroidRuntime:
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
回答1:
In your AndroidManifest.xml, you have to put this above or below the application tag.
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
Because you did not show your code what you have been doing, so I have no clue how to resolve your problems. But the below code is the code I use for my application to get the current country of users.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
MainActivity.java
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationManager;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
import java.util.List;
import java.util.Locale;
public class MainActivity extends AppCompatActivity {
Location gps_loc;
Location network_loc;
Location final_loc;
double longitude;
double latitude;
String userCountry, userAddress;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = findViewById(R.id.text_view);
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_NETWORK_STATE) != PackageManager.PERMISSION_GRANTED) {
return;
}
try {
gps_loc = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
network_loc = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
} catch (Exception e) {
e.printStackTrace();
}
if (gps_loc != null) {
final_loc = gps_loc;
latitude = final_loc.getLatitude();
longitude = final_loc.getLongitude();
}
else if (network_loc != null) {
final_loc = network_loc;
latitude = final_loc.getLatitude();
longitude = final_loc.getLongitude();
}
else {
latitude = 0.0;
longitude = 0.0;
}
ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_NETWORK_STATE}, 1);
try {
Geocoder geocoder = new Geocoder(this, Locale.getDefault());
List<Address> addresses = geocoder.getFromLocation(latitude, longitude, 1);
if (addresses != null && addresses.size() > 0) {
userCountry = addresses.get(0).getCountryName();
userAddress = addresses.get(0).getAddressLine(0);
tv.setText(userCountry + ", " + userAddress);
}
else {
userCountry = "Unknown";
tv.setText(userCountry);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
You will have to understand this code. One more thing, if you run your application on an emulator, it will keep showing "United States" or more specifically, Googleplex's location. Just run it on a real device to make it return your current location.
To return your current location other than just country itself, you can replace the
addresses.get(0).getCountryName()
with something like
addresses.get(0).getPostalCode()
or
addresses.get(0).getAdminArea()
and so on.
You can too concatenate the values as a string to show your current location in detail.
Please have a look at this
回答2:
You can use Google's Fused Location Profivider API library to get and access your current location (given that your GPS service is turned on)
Also don't forget to add this to your AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
For a more detailed tutorial you can refer at this Medium GPS Tutorial
Cheers
回答3:
Using the Geocoder class in the Android framework location APIs, you can convert an address to the corresponding geographic coordinates. This process is called geocoding. Alternatively, you can convert a geographic location to an address. The address lookup feature is also known as reverse geocoding.
Use getFromLocation() method to convert a geographic location to an address. The method returns an estimated street address corresponding to a given latitude and longitude.
public List<Address> getFromLocation (double latitude, double int maxResults)
This Returns an array of Addresses that are known to describe the area immediately surrounding the given latitude and longitude. The returned addresses will be localized for the locale provided to this class's constructor.
Take a look here as well: https://developer.android.com/training/location/display-address
回答4:
Try This! (Did it one year back)- Will update your location on all your move at certain interval.
Add dependencies in grade
implementation 'com.google.android.gms:play-services-location:16.0.0'
Add permissions in Manifest
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
In Your Activity
public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, LocationListener {
double longitude;
double latitude;
TextView tv;
Context context;
Location mLastLocation;
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
public static final int REQUEST_ID_MULTIPLE_PERMISSIONS = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = this;
tv = findViewById(R.id. text_view);
mGoogleApiClient = new GoogleApiClient.Builder(this).addApi(LocationServices.API).addConnectionCallbacks(this).addOnConnectionFailedListener(this).build();
initLocation();
}
@Override
public void onConnected(@Nullable Bundle bundle) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
checkLocationPermission();
}
mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(100000); // Update location every second
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED)
{
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (mLastLocation != null) {
latitude = mLastLocation.getLatitude();
longitude = mLastLocation.getLongitude();
setValue();
}
}
private void setValue() {
String strAddress = getAddressFromLocation(this, latitude, longitude);
tv.setText(strAddress);
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}
@Override
public void onLocationChanged(Location location) {
if(location!=null){
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
public boolean checkLocationPermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)
{
// Asking user if explanation is needed
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION))
{
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
//Prompt the user once explanation has been shown
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSIONS_REQUEST_LOCATION);
}
else
{
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSIONS_REQUEST_LOCATION);
}
return false;
}
else
{
return true;
}
}
@Override
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
@Override
protected void onResume() {
super.onResume();
mGoogleApiClient.connect();
initLocation();
}
@Override
protected void onPause() {
super.onPause();
mGoogleApiClient.disconnect();
}
@Override
protected void onDestroy() {
mGoogleApiClient.disconnect();
super.onDestroy();
}
private void initLocation() {
if(checkAndRequestPermissions(context)) {
Toast.makeText(context,"Permission Granded",Toast.LENGTH_SHORT).show();
}
}
public static boolean checkAndRequestPermissions(Context context) {
int locationPermission = ContextCompat.checkSelfPermission(context,
Manifest.permission.ACCESS_FINE_LOCATION);
List<String> listPermissionsNeeded = new ArrayList<>();
if (locationPermission != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.ACCESS_FINE_LOCATION);
}
if (!listPermissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions((Activity) context, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]),REQUEST_ID_MULTIPLE_PERMISSIONS);
return false;
}
return true;
}
public static String getAddressFromLocation(Context context, final double latitude, final double longitude) {
String straddress = "";
Geocoder geocoder = new Geocoder(context, Locale.getDefault());
try {
List<Address> addressList = geocoder.getFromLocation(
latitude, longitude, 1);
if (addressList != null && addressList.size() > 0) {
Address address = addressList.get(0);
StringBuilder sb = new StringBuilder();
if(address.getAddressLine(0) !=null && address.getAddressLine(0).length()>0 && !address.getAddressLine(0).contentEquals("null"))
{
sb.append(address.getAddressLine(0)).append("\n");
}else {
sb.append(address.getLocality()).append("\n");
sb.append(address.getPostalCode()).append("\n");
sb.append(address.getCountryName());
}
straddress = sb.toString();
//Log.e("leaddress","@"+straddress);
}
} catch (IOException e) {
//Log.e(TAG, "Unable connect to Geocoder", e);
}
return straddress;
}
}
来源:https://stackoverflow.com/questions/57863500/how-can-i-get-my-current-location-in-android-using-gps