当前位置: 首页 > 知识库问答 >
问题:

获取当前用户位置或最后已知位置

高才
2023-03-14

我意识到这个问题以前被问过很多次,但我现在问这个问题是因为答案很旧(与新的API相比)。

我以前使用过Location Manager,但我发现它非常不可靠。例如,在我的应用程序中,使用getLastKnownLocation和/或current location,它会立即将相机加载到用户的当前位置。但是,如果我在启动应用程序之前打开设备上的位置,它就不会把摄像头放在用户的当前位置,而是放在Nigera附近(我相信是默认视图)。

只有当我使用谷歌地图应用程序并用pin码指出我的位置,或者如果我等了一段时间,我的应用程序才会加载用户在视图中的位置(使用moveCamera)。

有时它会工作,有时不会。但我想使用Google Api客户端,或者更流畅的东西来检索用户的位置。

我想这样做:

1.)如果用户没有打开他们的位置,提示他们打开。

2.)打开位置后,以用户当前位置为中心启动地图相机/视图。

3.)最后,如果用户决定离开位置或从他们的位置移动,绝对不要做任何事情。

我在这里阅读了很多问题,但我找不到任何可以帮助我使用Google Api Client或其他任何东西配置此功能的东西。我已经尝试了位置管理器的几乎所有功能,但我仍然无法让它顺利工作。出于沮丧,我删除了我所有的位置管理器代码。

如果你想看看我写下或尝试了什么,我的大部分信息来源都来自这个问题(以及相关的):

在Android上获取用户当前位置的最简单、最健壮的方法是什么?

感谢您抽出时间阅读本文。

共有2个答案

汪胡非
2023-03-14

位置管理器对我来说工作完美,但对于API级别23,您需要做一些变通方法。要获得API级别23的权限,您需要在主线程中编写权限逻辑。

这是我在代码中使用的一个示例。

   /*Checking for permission if API level is more than 23 or 23, if condition match function calls*/
    if (Build.VERSION.SDK_INT >= 23) {
        requestMultiplePermissions();
    }

    /*Background Thread for splash screen with 2 seconds*/
    final Thread splashScreenThread = new Thread() {

        public void run() {

            try {
                Thread.sleep(2000);

            } catch (InterruptedException exception) {
                exception.printStackTrace();
            } finally {
                Intent homeScreen = new Intent(SplashScreen.this, MainActivity.class);
                startActivity(homeScreen);
                finish();

            }
        }
    };

    splashScreenThread.start();


}

/*Standar Permission chcking code for API level 23 or more*/
private void requestMultiplePermissions() {
    String locationPermission = Manifest.permission.ACCESS_FINE_LOCATION;
    int hasLocPermission = checkSelfPermission(locationPermission);
    List<String> permissions = new ArrayList<String>();
    if (hasLocPermission != PackageManager.PERMISSION_GRANTED) {
        permissions.add(locationPermission);
    }

    if (!permissions.isEmpty()) {
        String[] params = permissions.toArray(new String[permissions.size()]);
        requestPermissions(params, 1);
    } else {
        // We already have permission, so handle as normal

    }

}

/*This is function is used when permissions is granted by user, here we are firing a Intent after getting permission
* */
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
                                       int[] grantResults) {
    Toast.makeText(SplashScreen.this, " " + grantResults, Toast.LENGTH_SHORT).show();
    switch (requestCode) {
        case 1:
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Handle permission granted firing the Intent
                Intent intent = new Intent(SplashScreen.this, MainActivity.class);
                startActivity(intent);
                finish();

            } else {
                // Handle permission denied, giving Alertbox to user with some text
                new AlertDialog.Builder(this)
                        .setMessage("The app cannot continue without permissions")
                        .setCancelable(false)
                        .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {
                                SplashScreen.this.finish();
                            }
                        })
                        .show();


            }
            break;
        default:
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
    //

键入上面的代码在你的主活动或任何你想要的地方,我宁愿在应用程序启动时请求许可。

傅新
2023-03-14

以下服务优雅地为我提供准确的位置和位置服务的状态。此服务在我登录应用程序之前使用,因为应用程序需要启用位置服务。

基于此服务输入,您可以

  1. 提示用户打开位置
  2. 收到位置后,可以启动地图
  3. 如果位置断开,请注意其余逻辑

位置更新要记住的要点是

  • 指定接收更新的最小距离更改setSmallestDisplacement(即使我们在一个位置停留很长时间而不移动,API也会返回数据)
  • 设置FastTestInterval以接收位置更新
  • 根据您的要求设置优先级参数setPriority
    public class AppLocationService extends Service implements GoogleApiClient.ConnectionCallbacks,
            GoogleApiClient.OnConnectionFailedListener,
            LocationListener{

        private LocationRequest locationRequest;
        private GoogleApiClient googleApiClient;
        private Context appContext;
        private boolean currentlyProcessingLocation = false;
        private int mInterval=0;
        private final int CONNTIMEOUT=50000;
        private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters

    @Override
    public void onCreate() {
        super.onCreate();

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        appContext=getBaseContext();
        Toast.makeText(getBaseContext(), "Location Service Started", Toast.LENGTH_SHORT)
                .show();
        if(intent != null){
            mInterval = intent.getIntExtra(Constants.REFRESHTIMETAG, 5);
            mIMEI = intent.getStringExtra(Constants.IMEITAG);
            Log.v(Constants.BLL_LOG, "AppLocationService onStartCommand , mInterval=" + mInterval + " | mIMEI=" + mIMEI);
        }
        if (!currentlyProcessingLocation) {
            currentlyProcessingLocation = true;
            startTracking();
        }

        return START_STICKY;
    }

    private void startTracking() {
        Log.v(Constants.BLL_LOG, "startTracking");
        if (GooglePlayServicesUtil.isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS) {
            Log.v(Constants.BLL_LOG, "ConnectionResult SUCCESS");
            googleApiClient = new GoogleApiClient.Builder(this)
                    .addApi(LocationServices.API)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this)
                    .build();

            if (!googleApiClient.isConnected() || !googleApiClient.isConnecting()) {
                googleApiClient.connect();
                Log.v(Constants.BLL_LOG, "googleApiClient.connect()");
            }else{
                Log.v(Constants.BLL_LOG, "NOT connected googleApiClient.connect()");
                //
                //INTIMATE UI WITH EITHER HANDLER OR RUNONUI THREAD
                //
            }
        } else {
            Log.v(Constants.BLL_LOG, "unable to connect to google play services.");
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    public AppLocationService() {
    }

    @Override
    public void onConnected(Bundle bundle) {
        Log.v(Constants.BLL_LOG, "onConnected");
        locationRequest = LocationRequest.create();
        locationRequest.setInterval(mInterval * 1000); // milliseconds
        locationRequest.setFastestInterval(mInterval * 1000);
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        locationRequest.setSmallestDisplacement(MIN_DISTANCE_CHANGE_FOR_UPDATES);//distance change
        int permissionCheck = ContextCompat.checkSelfPermission(appContext, Manifest.permission.ACCESS_COARSE_LOCATION);
        if (permissionCheck!= PackageManager.PERMISSION_DENIED)
        {    LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);}

        Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(appContext, "Location Service got connected", Toast.LENGTH_SHORT)
                        .show();
            }
        });
    }

    @Override
    public void onConnectionSuspended(int i) {
        Log.v(Constants.BLL_LOG, "onConnectionSuspended");
        //INTIMATE UI ABOUT DISCONNECTION STATUS
    }

    @Override
    public void onLocationChanged(Location location) {
        Log.v(Constants.BLL_LOG, "onLocationChanged position: " + location.getLatitude() + ", " + location.getLongitude() + " accuracy: " + location.getAccuracy());
        //if (location.getAccuracy() < 500.0f) 
        Log.v(Constants.BLL_LOG, "onLocationChanged position: location.getAccuracy()= "+location.getAccuracy());

        //DO YOUR BUSINESS LOGIC, FOR ME THE SAME WAS TO SEND TO SERVER
        sendLocationDataToWebsite(location);        

    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        Log.v(Constants.BLL_LOG, "onConnectionFailed");
        Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(appContext, "Location Service got disconnected temporarily", Toast.LENGTH_SHORT)
                        .show();
            }
        });
    }

    /**
     * Send details to server
     * @param location
     */
    void sendLocationDataToWebsite(Location location){


    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (googleApiClient != null && googleApiClient.isConnected()) {
            googleApiClient.disconnect();
        }
        this.unregisterReceiver(this.batteryInfoReceiver);
    }
}

注意:此服务仍需在更新版本中进行测试

 类似资料:
  • 问题内容: 嗨,我写了一个应用程序,获取当前的纬度和经度并将其转换为相应的地址。我可以获取纬度和经度,但是如何使用json将其转换为相应的地址。我是json的新手。我尝试了一些示例代码,但没有得到地址 这是我的代码 请帮助我 提前致谢 问题答案: 要改回可读格式,您也可以使用Geocoder,但有时由于Google Play服务问题而无法正常工作。我将这个json地理编码用作第二种选择,以防万一。

  • 问题内容: 我在这个项目中使用该类。在我的地图上,您可以看到许多标记。我有许多已知的位置,但是在我的代码中,例如,我仅显示两个位置。 我不明白如何使用方向API和JSON。如何显示从当前位置(更改)到已知位置(恒定)的路线,距离和行进时间? 问题答案: 看一下本教程: 使用Google Map Android API V2中的Google Directions在两个位置之间绘制行车路线 它显示了如

  • 问题内容: 我要获取的是我的最后一个已知位置,但是距最近一次更新位置已有多久了。我如何得知自上次更新位置以来已有多长时间了? 问题答案: 前后API 17的最佳选择: Pre 17不太准确,但是应该足以测试某个位置是否很旧。 我应该认为,这可以: 这种逻辑的通常用例是当应用程序刚刚启动时,我们需要知道是在等待新位置时还是 必须 等待一个新位置还是可以使用最新的位置。

  • 问题内容: 我在使用android定位系统的NETWORK提供程序获取当前位置坐标时遇到麻烦。 已经阅读了很多教程,并为我的项目实现了4到5个现有的类,所有这些类都给了我最后的坐标,而不是当前的坐标。 我很确定这个问题是我遗漏的根本问题,但是我无法理解到底是什么。 我现在正在使用的代码: 这是我的主要活动 这是我用于跟踪的课程: 这是我的AndroidManifest.xml 实际上,GPS定位工

  • 问题内容: 我正在尝试通过GPS功能获取用户的当前位置, 编写了一个实现的简单类 通过一个简单的动作,我正在访问这些经度和纬度值 但是它总是返回0.0作为结果。无法找出问题所在。 问题答案: 您必须在onCreate()返回之后才能触发您的位置更新回调。如果您将经纬度变量初始化为虚拟值,则可能会看到您正在打印这些值。 在onLocationChanged中添加一些日志记录,以便可以看到它已被触发,