Android定位在模拟器中可用,但在手机上不可用

4
我用地理位置服务制作了一个简单的应用程序,它可以在文本视图中显示用户的当前位置,例如纬度、经度以及使用Geocoder获取的城市名称、国家名称和邮政编码等。
一切在模拟器中都能完美运行,但由于某种原因,无法在我的手机上检索位置。
模拟器运行的是Android 7.1,而我的手机运行的是Android 7.0,但这不应该是问题,因为我设计这个应用程序时考虑了6.0 marshmallow。
以下是代码:
“Mainactivity”
package com.example.slimshady.LocationInfoApp;

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.LocationListener;
import android.location.LocationManager;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

import java.util.List;
import java.util.Locale;

public class MainActivity extends AppCompatActivity {

    LocationManager locationManager;
    LocationListener locationListener;
    Geocoder geocoder;
    TextView latitude, longitude, city, postcode, country;


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

        latitude = (TextView)findViewById(R.id.latitude);
        longitude = (TextView) findViewById(R.id.longitude);
        city = (TextView)findViewById(R.id.city);
        postcode = (TextView)findViewById(R.id.postcode);
        country = (TextView)findViewById(R.id.country);


        locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
        locationListener = new LocationListener() {
            @Override
            public void onLocationChanged(Location location) {

                updateLocationInfo(location);

            }

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

            }

            @Override
            public void onProviderEnabled(String s) {

            }

            @Override
            public void onProviderDisabled(String s) {

            }
        };

        // asking permission starts here
        if (Build.VERSION.SDK_INT < 23){

            // api level lower than 23 so no need to ask for permission

            try {
                locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0,0, locationListener);

            }
            catch (SecurityException e){

                e.printStackTrace();
            }
        }
        else {

            // api level greater than or equal to 23 checking if has permission if not VVVV this condition
            // means go ask for permission

            if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED){

                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 0);
            }
            else{

                // means api level greater than or equal to 23 and already has permission
                // so no need to go out and ask for permission

                locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0,0, locationListener);

                // last known location because we went to this part means we have been here before
                Location lastKnownLocation =  locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                if (lastKnownLocation != null) {
                    updateLocationInfo(lastKnownLocation);
                }



            }

        }
        // asking permission ends here


    }

    public void updateLocationInfo(Location location) {

        geocoder = new Geocoder(getApplicationContext(), Locale.getDefault());

        try {

            List<Address> locationAddress = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(),1);
            if (locationAddress != null && locationAddress.size() > 0) {

                latitude.setText("Latitude: "+String.valueOf(locationAddress.get(0).getLatitude()));
                longitude.setText("Longitude: "+String.valueOf(locationAddress.get(0).getLongitude()));
                city.setText("City: "+String.valueOf(locationAddress.get(0).getLocality()));
                postcode.setText("Post Code: "+String.valueOf(locationAddress.get(0).getPostalCode()));
                country.setText("Country: "+String.valueOf(locationAddress.get(0).getCountryName()));

            }


        }
        catch (Exception e){

        }

    }

    @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){

            startListening();

        }
    }

    public void startListening(){

        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED){

            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0,0, locationListener);

        }

    }
}

代码简单而基础,一切应该都能正常工作,但出于某些原因却没有。我的意思是我的物理设备中的GPS接收器可以与谷歌地图配合使用,所以我知道它没有损坏。看,它在模拟器中运行良好。Image of it working in the emulator但是相同的代码在我的手机上不起作用,我已经添加了所有权限。
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET"/>

看到同样的应用在我的实际设备上无法运行,这是来自我的实际设备的截图。

Screenshot of it not working on mobile

如您所见,位置已开启,并在弹出窗口中授权。 最后但并非最不重要的是,展示GPS接收器在我的物理设备中正常工作且未受损。

我使用谷歌地图的截图 我使用谷歌地图的截图 我用红圈标出了GPS的开启状态和地图可以获取我的GPS位置


你可以尝试使用以下代码获取你的当前位置:- https://github.com/kdblue/GetMyCurrentLocation - iamkdblue
你在设备上尝试使用哪个版本?调试版还是发布版? - Cris
3个回答

1
如果您在物理设备上使用已发布的apk,则需要在Google API控制台的限制部分中添加发布apk的SHA1。我认为这会有所帮助。
如果没有,请通过在物理设备中调试应用程序来显示您的logcat错误。

不,我是使用Android Studio的adb来部署应用程序。 - Shantanu Bedajna

1

您的设备可以通过多种方式定位自身位置。这些经常被误认为是“GPS”,但实际上并不是。

  1. GPS(全球定位系统) 这是一种全球导航卫星系统(GNSS),依靠来自轨道卫星星座的信号来定位设备。GPS特指由美国国防部部署的卫星星座。其他选择包括GLONASS(俄罗斯)和Galileo(欧洲)。
  2. 网络 这使用WiFi或蓝牙信号来定位您的设备。设备扫描发射器ID,然后通过其互联网连接将这些ID发送到服务器以在数据库中查找。服务器会返回一个位置。

您的代码目前仅使用了 LocationManager.GPS_PROVIDER,该选项仅使用卫星来定位您的设备。Google Maps可能正在使用网络位置,即使关闭了GPS也可以正常工作。

我怀疑您需要执行以下操作之一:

  1. 添加 LocationManager.NETWORK_PROVIDER 或者
  2. 在您的设备上启用GPS。此选项在“设置”和“位置”下某处。

enter image description here


0

我解决了类似于你的问题,完全删除了位置管理器,并使所有位置基于FusedLocationProviderClient工作。此外,在三星S8上有一些奇怪的错误与LocationSettingsRequest相关,可以启动默认对话框以打开GPS,但在删除locationManager.requestLocationUpdates后,它与融合完美地配合。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接