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

Android服务不更新位置

南宫兴德
2023-03-14

我需要每1分钟和每5米位移更新一次熔合位置(我知道这是一个错误的做法,但为了测试和在日志中显示),并且我在按下按钮后立即启动服务,我在logcat中获得位置,但只有一次。根据服务级别,onLocationChanged应该每1分钟调用一次,但它不会再次调用,即使我的GPS几乎每分钟打开一次,然后在之后关闭,但Logcat中仍然没有位置更新。我需要服务类来保持更新位置,而不影响UI或主线程

这是只显示一次位置更新的logcat

09-16 03:13:37.125 10419-10419/com.example.com.pro_working1 D/===Location Service===: Service onConnected Calling
09-16 03:13:37.125 10419-10419/com.example.com.pro_working1 D/===Location Service===: Start Location Update is Calling
09-16 03:13:38.315 10419-10419/com.example.com.pro_working1 D/===Location Service===: Service OnLocationChanged Calling
09-16 03:13:38.315 10419-10419/com.example.com.pro_working1 D/===Location Service===: Here is Updated Locations: Latitude 28.5XXXXX Longitude 77.2XXXXX
09-16 03:13:38.315 10419-10419/com.example.com.pro_working1 D/===Location Service===: Sending Location Starting  Accuracy is: 37.5

这是我的服务课

public class Location_Service_background extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
    public static final String TAG = "===Location Service===";
    GoogleApiClient apiClient;
    Location mCurrentLocation;
    LocationRequest locationRequest;

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        GoogleApiSetup();
        RequestLocationUpdates();
        Log.d(TAG,"OnStartCommand Is Calling ");
        return START_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }



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

    }


    @Override
    public void onDestroy() {
        super.onDestroy();
        if (apiClient.isConnected()){
            Log.d(TAG,"Service On Destroy Calling and apiClient is Connected");
            StopLocationUpdates();
            apiClient.disconnect();
        }
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
    }

    @Override
    public void onConnected(@Nullable Bundle bundle) {
        Log.d(TAG,"Service onConnected Calling");
        if (mCurrentLocation != null) {
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                return;
            }
             mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(apiClient);

        }
        else {
            Log.d(TAG,"Start Location Update is Calling");
            StartLocationUpdate();
        }
    }

    @Override
    public void onConnectionSuspended(int i) {
        Log.d(TAG,"Service OnConnectionSuspended Calling");
        apiClient.connect();
    }

    @Override
    public void onLocationChanged(Location location) {
        Log.d(TAG,"Service OnLocationChanged Calling");
        mCurrentLocation=location;
        Log.d(TAG,"Here is Updated Locations: Latitude "+mCurrentLocation.getLatitude()+"Longitude "+mCurrentLocation.getLongitude());
        String Latitude= String.valueOf(mCurrentLocation.getLatitude());
        String Longitude=String.valueOf(mCurrentLocation.getLongitude());
        String Accuracy=String.valueOf(mCurrentLocation.getAccuracy());
        Log.d(TAG,"Sending Location Starting"+" "+" Accuracy is: "+mCurrentLocation.getAccuracy());


    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
        Log.d(TAG,"Connection Failed Called "+connectionResult);
    }



    private synchronized  void GoogleApiSetup() {
        apiClient = new GoogleApiClient.Builder(this)
                .addApi(LocationServices.API)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();
        apiClient.connect();
    }

    private void RequestLocationUpdates() {
        locationRequest = new LocationRequest();
        //1 Min = 60 seconds AND 1000 milliseconds in 1 second
        locationRequest.setInterval(60 * 1000);//5 Min 300 x 1000=300000
        locationRequest.setFastestInterval(60 * 1000);//2 Min
        locationRequest.setSmallestDisplacement(5);
        locationRequest.setMaxWaitTime(60*1000);
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    }

    private void StopLocationUpdates() {
        LocationServices.FusedLocationApi.removeLocationUpdates(apiClient, this);
    }

    private void StartLocationUpdate() {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

            return;
        }
        if (apiClient.isConnected()) {
            LocationServices.FusedLocationApi.requestLocationUpdates(apiClient, locationRequest, this);
        }
        else {
            Log.d(TAG,"GoogleApiClient is not connected yet.Please Try Again");
            apiClient.connect();
        }
    }


}

共有3个答案

杜曜灿
2023-03-14

没有什么帮助谁知道它可以被使用

    int jarak = 10;
    int interval = 5;


    LocationRequest request = new LocationRequest();
    request.setInterval(interval*1000); //update lokasi 10 detik
    request.setFastestInterval(interval*1000); //dapat update dari aplikasi lain yg lebih cepat 10 detik
    //request.setSmallestDisplacement(1); //diupdate jika berpindah 1 meter
    request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);


    FusedLocationProviderClient client = LocationServices.getFusedLocationProviderClient(this);
    int permission = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);
    if(permission == PackageManager.PERMISSION_GRANTED) {



        client.requestLocationUpdates(request, new LocationCallback() {

            @Override
            public void onLocationResult(LocationResult locationResult) {
                List<Location> locationList = locationResult.getLocations();
                if (locationList.size() > 0) {
                    Location locationCurrent = locationList.get(locationList.size() - 1);


                    double latitude = locationCurrent.getLatitude();
                    double longitude = locationCurrent.getLongitude();

                    double lastlatitude = Double.parseDouble(prefs.getString("lastlatitude","0"));
                    double lastlongitude = Double.parseDouble(prefs.getString("lastlongitude","0"));

                    Location startPoint=new Location("LokasiA");
                    startPoint.setLatitude(latitude);
                    startPoint.setLongitude(longitude);

                    Location endPoint = new Location("LokasiB");
                    endPoint.setLatitude(lastlatitude);
                    endPoint.setLongitude(lastlongitude);

                    double distance = startPoint.distanceTo(endPoint);

                    Log.d(tag, "location update last " + endPoint);
                    if(distance > jarak) {
                        Log.d(tag, "location update new" + startPoint);
                        Log.d(tag, "location dest " + distance);

                        SharedPreferences.Editor editor = prefs.edit();
                        editor.putString("lastlatitude", String.valueOf(latitude));
                        editor.putString("lastlongitude", String.valueOf(longitude));
                        editor.apply();



                        Log.i("getLatitude:",String.valueOf(locationCurrent.getLatitude()) );
                        Log.i("getLongitude:",String.valueOf(locationCurrent.getLongitude()) );


                    }

                }


            }
        },null);
    }
姚阳德
2023-03-14

假设您实际上在预期的更新之间移动设备超过5米,我认为LocationRequest类可能存在问题,其中setSmallestDisplacement()方法无法正常工作。。。或者至少它没有按预期工作。(我在其他帖子上看到过这些问题)。

您总是可以通过删除setSmallestDisplace()来检查自己的距离,而不是执行以下操作:

onLocationChanged() {
    double distance = // [ calculate distance between current lat/long and previous lat/long ]
    if (distance > 5 meters) {
        // do your normal onLocationChanged() code here
    }
}

还有一种可能性是,由于某种原因,FusedLocationProvider无法访问您的GPS,而是使用wifi或手机发射塔。。。在这种情况下,5m的距离太小,无法指定。你的日志显示精度为37.5米,因此这似乎不够精确,无法测量5米。所以可能您的清单中没有设置好的访问权限?

也可能是运行时权限没有正确执行的问题吗?您可以暂时将目标SDK设置为22,以检查这一点。

花烨
2023-03-14

希望这有助于拯救某人我在这个问题上经历的挫折。我正在使用FusedLocationAPI来请求位置更新和GoogleApiClient。我也通过服务这样做。

由于setSmallestDisplacement()比其他参数具有绝对优先级,因此您不会在定时间隔内获得任何位置更新。所以即使你有

locationRequestTimeInterval = LocationRequest.create()
    .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
    .setInterval(1)    
    .setFastestInterval(1)    
    .setMaxWaitTime(1)    
    .setSmallestDisplacement(5);

这将永远不会被触发,直到smallstDisplace参数被满足。

解决方案是创建两个单独的LocationRequest...一个只关心距离,一个只关心时间,并使用您的单个GoogleApiClient创建2个Request estLocationUpdate命令,一个使用时间LocationRequest,另一个使用距离LocationRequest。

所以你的2 LocationRequest看起来像这样:

locationRequestDistanceInterval = LocationRequest.create()
            .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
            .setFastestInterval(0) // This MUST be set, otherwise no updates
            .setSmallestDisplacement(LOCATION_REQUEST_MIN_DISTNACE);

locationRequestTimeInterval = LocationRequest.create()
            .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
            .setInterval(PROVIDER_GPS_UPDATE_TIME_INTERVAL)
            .setFastestInterval(PROVIDER_GPS_UPDATE_TIME_INTERVAL);
  • 请注意,必须在距离请求上设置setFastestInterval()值,否则不会触发距离请求。它不一定是0,但必须设置此字段。

然后,在您的GoogleApiClients onConnect()中,您可以添加两个请求位置更新()调用。

LocationServices.FusedLocationApi.requestLocationUpdates(
    mLocationClient, 
    locationRequestDistanceInterval, 
    new LocationListener() {
        @Override
        public void onLocationChanged(Location location) {
            // Handle your Distance based updates
        }
    }
);

LocationServices.FusedLocationApi.requestLocationUpdates(
    mLocationClient, 
    locationRequestTimeInterval, 
    new LocationListener() {
        @Override
        public void onLocationChanged(Location location) {
            // Handle your Time based updates
        }
    }
);  

您可以使用相同或单独的LocationListeners来处理每个请求的响应。希望这有帮助。

 类似资料:
  • 我有一个后台服务,每12分钟更新一次位置。我们希望每5-6分钟测试一次位置更新,但在Android文档中我们发现: 为了降低功耗,Android8.0(API Level26)限制了后台应用程序检索用户当前位置的频率。应用程序每小时只能接收几次位置更新。 限制是每小时固定次数?

  • 我们试图在wifi禁用时测试应用程序的优先级高精度和位置更新。 如果用户在没有wifi网络可用的地方移动,也会出现同样的问题。 我认为正确的行为是使用其他手机传感器(如GPS)更新位置,如果手机不能更新位置与WiFi。 你能提供什么工作? 我们不想使用优先高精度,因为它会耗尽手机电池。我们的应用程序跟踪手机位置,它不应该取决于wifi设置和wifi网络可用性。

  • 我最近收到了一封电子邮件更新,AdMob将于2016年10月17日停止向此链接https://firebase . Google . com/docs/AdMob/Android-legacy-release-notes中列出的SDK版本提供广告,并且必须修改为此链接https://firebase . Google . com/docs/AdMob/release-notes # Android

  • 无法导入com.google.android.gms.location.LocationServices 但我无法解决。 我安装的Google play服务的版本(在我的Android SDK管理器中)是17。我知道最新版本是19,但我不能从SDK管理器更新版本,我找不到任何选项这样做。

  • Im使用位置服务的简化版本 GCM推送的更新版本 无法解析配置“:app:_debugcompile”的所有依赖项。找不到com.google.android.gms:play-services-location:6.5.87build.gra.在以下位置进行了搜索:https://repo1.maven.org/maven2/com/google/android/gms/play-service

  • 我正在制作一个定期采样数据的应用程序。由于某种原因,我无法获得GPS数据。以下是我得到的: 舱单: 我想重申,我没有问题与空位置,函数没有得到调用。 我在外面走了几分钟的时候测试了这个代码,所以卫星接收不是问题。GPS跟踪器图标一直都在。