В настоящее время я работаю над приложением, которое использует карты Google и продолжает получать ту же ошибку при поиске местоположения. Я запрашиваю у пользователя разрешения в mapsActivity и использую FAB для ввода нового действия, в котором пользователь может искать местоположение. Я подозреваю, что ошибка может быть с разрешениями, хотя я в недоумении. Я приведу код ниже. Как ни странно, код работает очень хорошо и дает мне адрес при первом запуске приложения, но не работает после закрытия приложения.
package online.ridr.android;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.FragmentActivity;
import android.Manifest;
import android.app.Dialog;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.animation.OvershootInterpolator;
import android.widget.Toast;
import android.location.Address;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener, View.OnClickListener{
private FloatingActionButton fabMain, fabOne, fabTwo, fabThree;
private Float translationY = 100f;
private Boolean isMenuOpen = false;
private OvershootInterpolator interpolator = new OvershootInterpolator();
private GoogleMap mMap;
private GoogleApiClient googleApiClient;
private LocationRequest locationRequest;
private Location lastLocation;
private Marker currentUserLocationMarker;
private static final int Request_User_Location_Code = 99;
private static final String TAG = "MapsActivity";
private static final int ERROR_DIALOG_REQUEST = 9001;
private static final float DEFAULT_ZOOM = 15f;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
checkUserLocationPermission();
isServicesOk();
}
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
initFabMenu();
}
public boolean isServicesOk(){
Log.d(TAG, "isServicesOk: checking google services version");
int available = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(MapsActivity.this);
if(available == ConnectionResult.SUCCESS){
//everything is fine and the user can make map requests
Log.d(TAG, "isServicesOk: Google Play Services is working");
return true;
}
else if(GoogleApiAvailability.getInstance().isUserResolvableError(available)){
//an error occured but we can resolve it
Log.d(TAG, "isServiceOk: an error occured but we can fix it");
Dialog dialog = GoogleApiAvailability.getInstance().getErrorDialog(MapsActivity.this, available, ERROR_DIALOG_REQUEST);
dialog.show();
}
else{
Toast.makeText(this, "You cannot make map requests", Toast.LENGTH_SHORT).show();
}
return false;
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED){
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
mMap.getUiSettings().setMyLocationButtonEnabled(false); // This removes the button that re-centers device location
}
public boolean checkUserLocationPermission(){
if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED){
if(ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)){
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, Request_User_Location_Code);
}
else{
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, Request_User_Location_Code);
}
return false;
}
else{
return true;
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode){
case Request_User_Location_Code:
if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED){
if(googleApiClient == null){
buildGoogleApiClient(); //Creates new client
}
mMap.setMyLocationEnabled(true);
}
}
else{
Toast.makeText(this, "Access Denied...", Toast.LENGTH_SHORT).show();
}
return;
}
}
protected synchronized void buildGoogleApiClient(){
googleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
googleApiClient.connect();
}
@Override
public void onLocationChanged(Location location) {
lastLocation = location;
if(currentUserLocationMarker != null){
currentUserLocationMarker.remove();
}
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title("Current Location");
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ORANGE));
moveCamera(new LatLng(location.getLatitude(), location.getLongitude()), DEFAULT_ZOOM);
if(googleApiClient != null){
LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, this);
}
}
public void moveCamera(LatLng latLng, Float zoom){
Log.d(TAG, "moveCamera: moving the camera to: lat: " + latLng.latitude + ", lng: " + latLng.longitude);
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, zoom));
}
@Override
public void onConnected(@Nullable Bundle bundle) {
locationRequest = new LocationRequest();
locationRequest.setInterval(1100);
locationRequest.setFastestInterval(1100);
locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
}
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}
private void initFabMenu(){
fabMain = findViewById(R.id.fabMain);
fabOne = findViewById(R.id.fabOne);
fabTwo = findViewById(R.id.fabTwo);
fabThree = findViewById(R.id.fabThree);
fabOne.setAlpha(0f);
fabTwo.setAlpha(0f);
fabThree.setAlpha(0f);
fabOne.setTranslationY(translationY);
fabTwo.setTranslationY(translationY);
fabThree.setTranslationY(translationY);
fabMain.setOnClickListener(this);
fabOne.setOnClickListener(this);
fabTwo.setOnClickListener(this);
fabThree.setOnClickListener(this);
}
private void openMenu(){
isMenuOpen = !isMenuOpen;
fabMain.animate().setInterpolator(interpolator).rotation(45f).setDuration(300).start(); //Rotates the main button open
fabOne.animate().translationY(0f).alpha(1f).setInterpolator(interpolator).setDuration(300).start(); //Moves the sub buttons up
fabTwo.animate().translationY(0f).alpha(1f).setInterpolator(interpolator).setDuration(300).start();
fabThree.animate().translationY(0f).alpha(1f).setInterpolator(interpolator).setDuration(300).start();
}
private void closeMenu(){
isMenuOpen = !isMenuOpen;
fabMain.animate().setInterpolator(interpolator).rotation(0f).setDuration(300).start(); //Rotates the main button closed
fabOne.animate().translationY(translationY).alpha(0f).setInterpolator(interpolator).setDuration(300).start();
fabTwo.animate().translationY(translationY).alpha(0f).setInterpolator(interpolator).setDuration(300).start();
fabThree.animate().translationY(translationY).alpha(0f).setInterpolator(interpolator).setDuration(300).start();
}
private void handleFabOne(){
}
private void handleFabTwo(){
}
private void handleFabThree(){
}
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.fabMain:
if(isMenuOpen){
closeMenu();
}
else{
openMenu();
}
break;
case R.id.fabOne:
handleFabOne();
if(isMenuOpen){
closeMenu();
}
else{
openMenu();
}
break;
case R.id.fabTwo:
handleFabTwo();
if(isMenuOpen){
closeMenu();
}
else{
openMenu();
}
break;
case R.id.fabThree:
handleFabThree();
openDestinationActivity();
if(isMenuOpen){
closeMenu();
}
else{
openMenu();
}
break;
}
}
public void openDestinationActivity(){
Intent intent = new Intent(this, DestinationSearchActivity.class);
startActivity(intent);
}
}
Это mapsActivity, которое также является mainActivity. Я также предоставлю код для другого класса. Спасибо за помощь.
package online.ridr.android;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Geocoder;
import android.nfc.Tag;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.maps.model.LatLng;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class DestinationSearchActivity extends AppCompatActivity {
private EditText mSearchText;
private static final String TAG = "DestinationSearch";
private LatLng location;
private static final int Request_User_Location_Code = 99;
private double destLat;
private double destLong;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_destination_search);
mSearchText = (EditText) findViewById(R.id.input_search);
init();
}
private void init(){
Log.d(TAG, "init: initializing");
mSearchText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView textView, int actionId, KeyEvent keyEvent) {
if(actionId == EditorInfo.IME_ACTION_SEARCH
|| actionId == EditorInfo.IME_ACTION_DONE
|| keyEvent.getAction() == keyEvent.ACTION_DOWN
|| keyEvent.getAction() == keyEvent.KEYCODE_ENTER){
//execute method for searching
geoLocate();
}
return false;
}
});
}
private void geoLocate(){
Log.d(TAG, "geolocate: geolocating");
String searchString = mSearchText.getText().toString();
Geocoder geocoder = new Geocoder(DestinationSearchActivity.this);
List<Address> list = new ArrayList<>();
try {
list = geocoder.getFromLocationName(searchString, 1);
}catch (IOException e){
Log.e(TAG, "geoLocate: IOException " + e.getMessage());
}
if(list.size() > 0){
Address address = list.get(0);
//Toast.makeText(this, address.toString(), Toast.LENGTH_SHORT).show();
Log.d(TAG, "geoLocate: found a location: " + address.toString());
}
}
}
Обновление: я получил больше трассировки стека, но все еще застрял.
2020-02-24 14:12:41.051 7483-7483/online.ridr.android D/DestinationSearch: geolocate: geolocating
2020-02-24 14:12:46.057 7483-7483/online.ridr.android W/System.err: java.io.IOException: grpc failed
2020-02-24 14:12:46.066 7483-7483/online.ridr.android W/System.err: at android.location.Geocoder.getFromLocationName(Geocoder.java:178)
2020-02-24 14:12:46.066 7483-7483/online.ridr.android W/System.err: at online.ridr.android.DestinationSearchActivity.geoLocate(DestinationSearchActivity.java:72)
2020-02-24 14:12:46.066 7483-7483/online.ridr.android W/System.err: at online.ridr.android.DestinationSearchActivity.access$000(DestinationSearchActivity.java:29)
2020-02-24 14:12:46.066 7483-7483/online.ridr.android W/System.err: at online.ridr.android.DestinationSearchActivity$1.onEditorAction(DestinationSearchActivity.java:58)
2020-02-24 14:12:46.066 7483-7483/online.ridr.android W/System.err: at android.widget.TextView.doKeyDown(TextView.java:8318)
2020-02-24 14:12:46.066 7483-7483/online.ridr.android W/System.err: at android.widget.TextView.onKeyDown(TextView.java:8187)
2020-02-24 14:12:46.066 7483-7483/online.ridr.android W/System.err: at android.view.KeyEvent.dispatch(KeyEvent.java:2801)
2020-02-24 14:12:46.066 7483-7483/online.ridr.android W/System.err: at android.view.View.dispatchKeyEvent(View.java:13352)
2020-02-24 14:12:46.066 7483-7483/online.ridr.android W/System.err: at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1922)
2020-02-24 14:12:46.066 7483-7483/online.ridr.android I/chatty: uid=10134(online.ridr.android) identical 5 lines
2020-02-24 14:12:46.067 7483-7483/online.ridr.android W/System.err: at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1922)
2020-02-24 14:12:46.067 7483-7483/online.ridr.android W/System.err: at com.android.internal.policy.DecorView.superDispatchKeyEvent(DecorView.java:453)
2020-02-24 14:12:46.067 7483-7483/online.ridr.android W/System.err: at com.android.internal.policy.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1839)
2020-02-24 14:12:46.067 7483-7483/online.ridr.android W/System.err: at android.app.Activity.dispatchKeyEvent(Activity.java:3953)
2020-02-24 14:12:46.067 7483-7483/online.ridr.android W/System.err: at androidx.core.app.ComponentActivity.superDispatchKeyEvent(ComponentActivity.java:115)
2020-02-24 14:12:46.067 7483-7483/online.ridr.android W/System.err: at androidx.core.view.KeyEventDispatcher.dispatchKeyEvent(KeyEventDispatcher.java:84)
2020-02-24 14:12:46.067 7483-7483/online.ridr.android W/System.err: at androidx.core.app.ComponentActivity.dispatchKeyEvent(ComponentActivity.java:133)
2020-02-24 14:12:46.067 7483-7483/online.ridr.android W/System.err: at androidx.appcompat.app.AppCompatActivity.dispatchKeyEvent(AppCompatActivity.java:558)
2020-02-24 14:12:46.067 7483-7483/online.ridr.android W/System.err: at androidx.appcompat.view.WindowCallbackWrapper.dispatchKeyEvent(WindowCallbackWrapper.java:59)
2020-02-24 14:12:46.067 7483-7483/online.ridr.android W/System.err: at androidx.appcompat.app.AppCompatDelegateImpl$AppCompatWindowCallback.dispatchKeyEvent(AppCompatDelegateImpl.java:2764)
2020-02-24 14:12:46.067 7483-7483/online.ridr.android W/System.err: at com.android.internal.policy.DecorView.dispatchKeyEvent(DecorView.java:367)
2020-02-24 14:12:46.067 7483-7483/online.ridr.android W/System.err: at android.view.ViewRootImpl$ViewPostImeInputStage.processKeyEvent(ViewRootImpl.java:5413)
2020-02-24 14:12:46.067 7483-7483/online.ridr.android W/System.err: at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:5281)
2020-02-24 14:12:46.067 7483-7483/online.ridr.android W/System.err: at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4788)
2020-02-24 14:12:46.067 7483-7483/online.ridr.android W/System.err: at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4841)
2020-02-24 14:12:46.067 7483-7483/online.ridr.android W/System.err: at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4807)
2020-02-24 14:12:46.067 7483-7483/online.ridr.android W/System.err: at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4947)
2020-02-24 14:12:46.067 7483-7483/online.ridr.android W/System.err: at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4815)
2020-02-24 14:12:46.067 7483-7483/online.ridr.android W/System.err: at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:5004)
2020-02-24 14:12:46.068 7483-7483/online.ridr.android W/System.err: at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4788)
2020-02-24 14:12:46.068 7483-7483/online.ridr.android W/System.err: at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4841)
2020-02-24 14:12:46.068 7483-7483/online.ridr.android W/System.err: at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4807)
2020-02-24 14:12:46.068 7483-7483/online.ridr.android W/System.err: at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4815)
2020-02-24 14:12:46.068 7483-7483/online.ridr.android W/System.err: at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4788)
2020-02-24 14:12:46.068 7483-7483/online.ridr.android W/System.err: at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4841)
2020-02-24 14:12:46.068 7483-7483/online.ridr.android W/System.err: at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4807)
2020-02-24 14:12:46.068 7483-7483/online.ridr.android W/System.err: at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4980)
2020-02-24 14:12:46.068 7483-7483/online.ridr.android W/System.err: at android.view.ViewRootImpl$ImeInputStage.onFinishedInputEvent(ViewRootImpl.java:5141)
2020-02-24 14:12:46.068 7483-7483/online.ridr.android W/System.err: at android.view.inputmethod.InputMethodManager$PendingEvent.run(InputMethodManager.java:3064)
2020-02-24 14:12:46.068 7483-7483/online.ridr.android W/System.err: at android.view.inputmethod.InputMethodManager.invokeFinishedInputEventCallback(InputMethodManager.java:2607)
2020-02-24 14:12:46.068 7483-7483/online.ridr.android W/System.err: at android.view.inputmethod.InputMethodManager.finishedInputEvent(InputMethodManager.java:2598)
2020-02-24 14:12:46.068 7483-7483/online.ridr.android W/System.err: at android.view.inputmethod.InputMethodManager$ImeInputEventSender.onInputEventFinished(InputMethodManager.java:3041)
2020-02-24 14:12:46.068 7483-7483/online.ridr.android W/System.err: at android.view.InputEventSender.dispatchInputEventFinished(InputEventSender.java:143)
2020-02-24 14:12:46.068 7483-7483/online.ridr.android W/System.err: at android.os.MessageQueue.nativePollOnce(Native Method)
2020-02-24 14:12:46.069 7483-7483/online.ridr.android W/System.err: at android.os.MessageQueue.next(MessageQueue.java:336)
2020-02-24 14:12:46.069 7483-7483/online.ridr.android W/System.err: at android.os.Looper.loop(Looper.java:174)
2020-02-24 14:12:46.069 7483-7483/online.ridr.android W/System.err: at android.app.ActivityThread.main(ActivityThread.java:7356)
2020-02-24 14:12:46.069 7483-7483/online.ridr.android W/System.err: at java.lang.reflect.Method.invoke(Native Method)
2020-02-24 14:12:46.069 7483-7483/online.ridr.android W/System.err: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
2020-02-24 14:12:46.070 7483-7483/online.ridr.android W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
2020-02-24 14:12:46.070 7483-7483/online.ridr.android E/DestinationSearch: geoLocate: IOException grpc failed