GoogleApiClient во фрагменте Android

#android #fragment

#Android #фрагмент

Вопрос:

Я пытаюсь изучить Android самостоятельно. И в моем приложении я хочу использовать фрагмент для отображения карты Google, и когда пользователь открывает мое приложение, я хочу получить текущее местоположение, используя GoogleApiClient мой фрагмент кода:

 public class HomeFragment extends Fragment implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {

    public interface comuticateParent {
        public void sendMess(String text);
    }

    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;


    public HomeFragment() {
        // Required empty public constructor
    }

    public static HomeFragment newInstance(String param1, String param2) {
        HomeFragment fragment = new HomeFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    comuticateParent callback;
    Button btn1;
    TextView textView;
    MapView mMapView;
    GoogleApiClient mGoogleApiClient;
    Location mLastLocation;
    LocationRequest mLocationRequest;
    private GoogleMap googleMap;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
        if (mGoogleApiClient == null) {
            mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this)
                    .addApi(LocationServices.API)
                    .build();
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View rootView = inflater.inflate(R.layout.fragment_home, container, false);
        mMapView = (MapView) rootView.findViewById(R.id.mapView);
        mMapView.onCreate(savedInstanceState);

        mMapView.onResume(); // needed to get the map to display immediately

        try {
            MapsInitializer.initialize(getActivity().getApplicationContext());
        } catch (Exception e) {
            e.printStackTrace();
        }
        mMapView.getMapAsync(new OnMapReadyCallback() {
            @Override
            public void onMapReady(GoogleMap mMap) {
                googleMap = mMap;
                googleMap.setMyLocationEnabled(true);

                mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
                Log.d("onCreateView", Boolean.toString(mGoogleApiClient.isConnected()));
                googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(mylocation, 13));
            }
        });
        return rootView;
    }

    @Override
    public void onStart() {
        mGoogleApiClient.connect();
        Log.d("ConnectonStart", "Connected ");
        Log.d("ONstart", Boolean.toString(mGoogleApiClient.isConnected()));
        super.onStart();
    }

    @Override
    public void onStop() {
        mGoogleApiClient.disconnect();
        super.onStop();
    }

    @Override
    public void onResume() {
        mGoogleApiClient.connect();
        super.onResume();
        mMapView.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        mMapView.onPause();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mMapView.onDestroy();
    }

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

    @Override
    public void onConnected(Bundle bundle) {
        Log.d("Connect", "Connected ");
        Log.d("onConnected", Boolean.toString(mGoogleApiClient.isConnected()));
    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        Log.d("Connect", "failed ");
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        Activity activity;
        if (context instanceof Activity) {
            activity = (Activity) context;
            callback = (comuticateParent) getActivity();
        }
    }

}
  

И здесь проблема:
-Метод входа в систему onCreateView появляется перед методом входа в систему onconnected, поэтому я не могу получить getLastLocation(), потому что GoogleApiClient еще не подключен.

У меня есть поиск в Google, но я не знаю, как это исправить. Пожалуйста, помогите мне! Извините за мой лучший английский.

Комментарии:

1. попробуйте подключить GoogleApiClient в методе onCreate() фрагмента.

2. Я переношу ‘mMapView.getMapAsync’ в OnConnected, и это сработало. В любом случае, большое спасибо.

Ответ №1:

Первая проблема с методом входа в систему onCreateView появляется перед методом входа в систему onconnected, потому что GoogleApiClient будет доступ к API Google, проверка конфигурации приложения, проверка отпечатка сертификата и т.д. Обработка занимает слишком много времени. Чтобы избежать блокировки потока пользовательского интерфейса, он будет выполняться в другом потоке и использовать асинхронный обратный вызов.

Вторая проблема Я не могу получить getLastLocation(), потому что GoogleApiClient еще не подключен, потому что FusedLocationApi будет поддерживать только фоновый режим, поэтому вам нужно получить GoogleMap в фоновом режиме.

Смотрите мой пример здесь:https://gist.github.com/quydm/a458d908c4da2496672f83372304f417

Ответ №2:

Вам придется подождать, пока GoogleApiClient подключится, прежде чем вы сможете запросить обновления местоположения. Для этого вам необходимо переместить этот блок кода (который в настоящее время находится в вашем onCreateView() методе):

 mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
Log.d("onCreateView", Boolean.toString(mGoogleApiClient.isConnected()));
googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(mylocation, 13));
  

к телу переопределенного метода onConnected() .
Вы не можете ввести этот код напрямую onCreateView() из-за той самой проблемы, которая у вас была. Соединение должно быть установлено первым перед отправкой любых запросов о местоположении. Соединение может устанавливаться быстро или занимать больше времени, чем обычно. Это зависит от многих вещей, находящихся вне вашего контроля.

По этой причине я бы предложил показывать какой-нибудь индикатор выполнения, чтобы указать, что службы определения местоположения подключаются, а затем удалять индикатор выполнения при onConnected() вызове. Конечно, это полностью зависит от вашего приложения. Если для пользователя критически важны службы определения местоположения, то это обязательно, если нет, то вам может не понадобиться добавлять его.