安卓 gRPC 失败异常

5

使用Geocoder从latlong获取位置时,出现此错误。

错误信息

由于java.io.IOException导致grpc失败 at android.location.Geocoder.getFromLocation(Geocoder.java:136) at com.example.myApp.test.Fragments.DashboardFragment$sendLocationData$1.onSuccess(DashboardFragment.kt:676) at com.example.myApp.test.Fragments.DashboardFragment$sendLocationData$1.onSuccess(DashboardFragment.kt:81) at com.google.android.gms.tasks.zzj.run(Unknown Source) at android.os.Handler.handleCallback(Handler.java:751) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6776) at java.lang.reflect.Method.invoke(Method.java) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1496) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386)

代码

    punch_button?.setOnClickListener {
    createLocationRequest()
}


protected fun createLocationRequest() {
    mLocationRequest = LocationRequest()
    mLocationRequest?.interval = 10
    mLocationRequest?.fastestInterval = 50
    mLocationRequest?.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
    val builder = LocationSettingsRequest.Builder()
            .addLocationRequest(mLocationRequest!!)

    mLocationCallback = object : LocationCallback() {
        override fun onLocationResult(p0: LocationResult?) {
            super.onLocationResult(p0)
            mCurrentLocation = p0?.lastLocation
        }

    }

    val client = LocationServices.getSettingsClient(context)
    val task = client.checkLocationSettings(builder.build())



    task.addOnSuccessListener(OnSuccessListener<LocationSettingsResponse> {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            askForPermission();
        }
    })  }



    private fun askForPermission() {
    if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.ACCESS_FINE_LOCATION)) {
            requestPermissions(arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), 123);
        } else {
            requestPermissions(arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), 123);
        }
    } else {
        sendLocationData()
    }
}


    @SuppressLint("MissingPermission")
fun sendLocationData() {
try{
    Log.e("lat", mCurrentLocation?.latitude.toString())
    //mCurrentLocation?.latitude !=null && mCurrentLocation?.latitude !=null
    mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, null)

    mFusedLocationClient.lastLocation.addOnSuccessListener({ location ->
        if (location != null) {
            val address: List<Address> = geocoder?.getFromLocation(location.latitude, location.longitude, 1)!!
        }
    })

}catch(e:Exception){
  Log.e("tag","error")
}
}

你是在模拟器上运行还是在实体设备上运行的? - Sz-Nika Janos
在物理设备上随机发生... - develope_AK
你检查过权限了吗?网络和位置权限都已经授权了吗?我看到你有一个askForPermission()方法,但是在onResult活动中检查请求并在每次调用之前询问权限是否被授予。对我来说,这也会导致相同的错误。 - Sz-Nika Janos
在函数sendLocationData()的第val address: List<Address> = geocoder?.getFromLocation(location.latitude, location.longitude, 1)!!行出现了错误。 - develope_AK
2个回答

3
这是一个已向Google报告但遗憾未解决的已知错误。该错误发生在真实设备和模拟器上。您可以在此处查看有关此问题的线程:

https://issuetracker.google.com/issues/64418751

https://issuetracker.google.com/issues/64247769

尝试解决这个错误的一个方法是尝试使用Geocoding API Web服务: https://github.com/googlemaps/google-maps-services-java 或者您可以尝试捕获异常并像这样处理异常:
try{
geocoder = new Geocoder(this, Locale.getDefault())
   // ... your code that throws the exception here
}catch(e: IOException){
   Log.e("Error", "grpc failed: " + e.message, e)
   // ... retry again your code that throws the exeception
}

2

当我使用geocoder.getFromLocation()方法获取地址列表时,遇到了这个问题,问题在于从纬度、经度获取地址列表需要时间,在某些慢速设备上需要更长的时间,并且有时会出现java-io-ioexception-grpc-failed错误。

我使用Rx Java解决了这个问题。

"最初的回答"

使用geocoder.getFromLocation()方法获取地址列表时遇到了问题,因为从纬度和经度获取地址列表需要时间,或者在一些慢速设备上需要更长的时间。有时会出现java-io-ioexception-grpc-failed异常。为了解决这个问题,我使用了Rx Java。

public class AsyncGeocoder {

private final Geocoder geocoder;

public AsyncGeocoder(Context context) {
    geocoder = new Geocoder(context);
}

public Disposable reverseGeocode(double lat, double lng, Callback callback) {
    return Observable.fromCallable(() -> {
        try {
            return geocoder.getFromLocation(lat, lng, 1);
        } catch (Exception e) {
            AppLogger.d("throwable,", new Gson().toJson(e));
            e.printStackTrace();
        }
        return false;
    }).subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(result -> {
                //Use result for something
                AppLogger.d("throwable,", new Gson().toJson(result));

                callback.success((Address) ((ArrayList) result).get(0));
            }, throwable -> AppLogger.d("throwable,", new Gson().toJson(throwable)));
}

public interface Callback {
    void success(Address address);

    void failure(Throwable e);
}
}

呼叫位置

mViewModel.getLocation(asyncGeocoder, getLat(), getLng(), this);

ViewModel方法

最初的回答
public void getLocation(AsyncGeocoder geocoder, Double lat, Double lng, AsyncGeocoder.Callback callback) {
        getCompositeDisposable().add(geocoder.reverseGeocode(lat, lng, callback));
    }

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