无法在应用程序中获取我的手机位置

huangapple go评论85阅读模式
英文:

Unable to get location of my phone in app

问题

以下是翻译好的代码部分:

public class MainActivity extends AppCompatActivity {

    LocationManager locMan;
    LocationListener locList;

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
    {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
        {
            if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION ) == PackageManager.PERMISSION_GRANTED)
            {
                locMan.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locList);
            }
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        locMan = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
        locList = new LocationListener()
        {
            @Override
            public void onLocationChanged(Location location)
            {
                Toast.makeText(getApplicationContext(), location.toString(), Toast.LENGTH_SHORT).show();
                // 这里我正在尝试显示我的位置信息。在 'getApplicationContext()' 的位置,我曾经尝试使用 'MainActivity',但它也不起作用。
            }

            @Override
            public void onStatusChanged(String s, int i, Bundle bundle)
            {

            }

            @Override
            public void onProviderEnabled(String s)
            {

            }

            @Override
            public void onProviderDisabled(String s)
            {

            }
        };
        if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION ) != PackageManager.PERMISSION_GRANTED)
        {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION},1);
        }
        else
        {
            locMan.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locList);
        }
    }
}

如果你对GPS有问题,可能需要检查权限是否正确设置和请求,以及是否允许了位置访问权限。

英文:

I am building app in Android Studio that will access user location. Below provided is the code I am using. I am using my phone itself as an emulator. I have granted ACCESS_FINE_LOCATION and ACCESS_INTERNET in the manifest XML file.

public class MainActivity extends AppCompatActivity {
LocationManager locMan;
LocationListener locList;
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
{
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
{
if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION ) == PackageManager.PERMISSION_GRANTED)
{
locMan.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locList);
}
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
locMan = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
locList = new LocationListener()
{
@Override
public void onLocationChanged(Location location)
{
Toast.makeText(getApplicationContext(), location.toString(), Toast.LENGTH_SHORT).show();
// Here I am trying to make toast of my location. In place of 'getApplicationContext()' , I had passed 'MainActivity' but it also don't work.
}
@Override
public void onStatusChanged(String s, int i, Bundle bundle)
{
}
@Override
public void onProviderEnabled(String s)
{
}
@Override
public void onProviderDisabled(String s)
{
}
};
if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION ) != PackageManager.PERMISSION_GRANTED)
{
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION},1);
}
else
{
locMan.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locList);
}
}
}

What can be done ? Is there any issue with my GPS ?

答案1

得分: 0

根据您使用的 Android 版本您可能还需要使用 ACCESS_COARSE_LOCATION 权限尝试将其添加到清单文件中并在您的活动中请求该权限

我曾经编写过一个可以持续跟踪设备位置的工作类

private static LocationManager locationManager=null;
private static LocationListener locationListener=null;

public static void startTrackingLocation(final Context context, final LocationChangedListener listener) {
    startTrackingLocation(context, listener, 0.5, 1);
}

/**
 * 位置会定期请求,如果位置之间的距离 > distance,则会调用抽象 listener.onLocationChanged(Location l) 方法
 * @param context   从中获取位置的上下文
 * @param listener  监听位置变化
 * @param minutes   位置请求之间的时间间隔
 * @param distance  触发 onLocationChanged(Location l) 的最小距离
 */
public static void startTrackingLocation(@NotNull final Context context, @NotNull final LocationChangedListener listener, final double minutes, final int distance) {
    initLocationManager(context);
    locationListener = new LocationListener() {
        @Override
        public void onLocationChanged(Location location) {
            listener.onLocationChanged(location);
        }
        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) { }
        @Override
        public void onProviderEnabled(String provider) { }
        @Override
        public void onProviderDisabled(String provider) { }
    };

    try {
        locationManager.requestLocationUpdates(
                LocationManager.NETWORK_PROVIDER, (int)(minutes*60000), distance, locationListener);
    } catch (SecurityException ignored) { }
}

private static void initLocationManager(@NotNull final Context context) {
    if (null==locationManager) {
        locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
    }
}

@SuppressWarnings("unused")
public static void stopTrackingLocation() {
    if (null!=locationManager && null!=locationListener) {
        locationManager.removeUpdates(locationListener);
    }
}

public static Location getLocation(final Context context) {
    initLocationManager(context);
    Location locationGPS=null, locationNet=null;
    try {
        locationGPS = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
        locationNet = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
    } catch (SecurityException ignored) { }

    if (null != locationNet) {
        return locationNet;
    }
    return locationGPS;
}

@SuppressWarnings("unused")
private static double distance(final double lat1, final double lon1, final double lat2, final double lon2) {
    final double theta = lon1 - lon2;
    double dist = Math.sin(Math.toRadians(lat1)) * Math.sin(Math.toRadians(lat2))
            + Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) * Math.cos(Math.toRadians(theta));
    dist = Math.toDegrees(Math.acos(dist)) * 60 * 1850 ; // 1 degree is 111km 111/60=1.85
    return (dist);
}

LocationChangedListener 类是我编写的一个抽象类,用于捕捉位置变化事件。

这段代码非常简单:

public abstract void onLocationChanged(Location location);

在您的活动中:

LocationChangedListener listener = new LocationChangedListener() {
        @Override
        public void onLocationChanged(Location location) {
            MainActivity.this.onLocationChanged(location);
        }
    };

这在我的 Android 设备上完全可用,您可以试试。另外,函数 Location getLocation(final Context context) 可以不使用,因为它只会在给定时间返回设备的位置。

我在清单文件中使用了相同的权限。这对您也应该有效。

英文:

Depending on the android version you are using, you might need to use ACCESS_COARSE_LOCATION, too. Try adding it to your manifest and requesting the permisison in your activity.

I once wrote a working class to constantly track a devices location.

private static LocationManager locationManager=null;
private static LocationListener locationListener=null;
public static void startTrackingLocation(final Context context, final LocationChangedListener listener) {
startTrackingLocation(context, listener, 0.5, 1);
}
/**
* Location gets requested periodically, and a call on abstract listener.onLocationChanged(Location l)
* is performed if distance between locations is > distance
* @param context   context to gather the location from
* @param listener  listens to location changes
* @param minutes   interval between the location requests
* @param distance  minimal distance to trigger onLocationChanged(Location l)
*/
public static void startTrackingLocation(@NotNull final Context context, @NotNull final LocationChangedListener listener, final double minutes, final int distance) {
initLocationManager(context);
locationListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
listener.onLocationChanged(location);
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) { }
@Override
public void onProviderEnabled(String provider) { }
@Override
public void onProviderDisabled(String provider) { }
};
try {
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, (int)(minutes*60000), distance, locationListener);
} catch (SecurityException ignored) { }
}
private static void initLocationManager(@NotNull final Context context) {
if (null==locationManager) {
locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
}
}
@SuppressWarnings("unused")
public static void stopTrackingLocation() {
if (null!=locationManager && null!=locationListener) {
locationManager.removeUpdates(locationListener);
}
}
public static Location getLocation(final Context context) {
initLocationManager(context);
Location locationGPS=null, locationNet=null;
try {
locationGPS = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
locationNet = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
} catch (SecurityException ignored) { }
if (null != locationNet) {
return locationNet;
}
return locationGPS;
}
@SuppressWarnings("unused")
private static double distance(final double lat1, final double lon1, final double lat2, final double lon2) {
final double theta = lon1 - lon2;
double dist = Math.sin(Math.toRadians(lat1)) * Math.sin(Math.toRadians(lat2))
+ Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) * Math.cos(Math.toRadians(theta));
dist = Math.toDegrees(Math.acos(dist)) * 60 * 1850 ; // 1 degree is 111km 111/60=1.85
return (dist);
}

The LocationChangedListener class is an abstract class I wrote to catch the event where location was changed.

The code is very simple:

 public abstract void onLocationChanged(Location location);

In your activity:

LocationChangedListener listener = new LocationChangedListener() {
@Override
public void onLocationChanged(Location location) {
MainActivity.this.onLocationChanged(location);
}
};

This is fully working on my android device, you may give it a try. Besides, the function Location getLocation(final Context context) may be left out as it only gives you devices location at given time.

I used the same permissions in the manifest. This should also work for you.

答案2

得分: 0

我注意到的一件事是,你只有ACCESS_FINE_LOCATION权限,并且正在使用LocationManager.GPS_PROVIDER。这会指示应用程序仅使用GPS获取位置,而不是一种优化的方式,即GPS、移动网络和WiFi网络的组合。

而且我猜你正在编程的时候是在室内。GPS需要能够看到天空才能正常工作,所以可能无法从卫星获取信号。你可以尝试将设备放在窗户旁边,也许会起作用。

但如果你不必严格使用GPS,可以将其更改为使用每个可能的位置提供程序。

英文:

One thing I've notice is that you only have the ACCESS_FINE_LOCATION permission and also using LocationManager.GPS_PROVIDER. This instruct the app to only use the GPS to obtain position and not the optimized way, a combination of GPS, Mobile Network and WiFi Networks.

And I'm guessing as you are coding you are indoors. The GPS needs sky visibility to work, so maybe it can not get the signal from the Satellites. You could try putting it next to the window and might work.

But if you are not required to strictly use the GPS only, change it to use every posible provider.

huangapple
  • 本文由 发表于 2020年4月5日 20:58:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/61042967.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定