#android #android_studio #google_maps_api
Возникла необходимость интегрировать в проект карты google, накидал по руководству
google MapFragment, до этого с картами google дел не имел, проверил вчера на телефоне(Samsung
Galaxy S4) - фрагмент открывается и корректно отображает карту. GoogleMaps API на сайте
google активирован, ключ Api в манифесте прописан. Activity, в котором запускаются
фрагменты, наследуется от AppCompatActivity. При попытке перехода на фрагмент с картой
на встроенном в студию эмуляторе(Nexus 4 21 API(with GoogleAPIs) и Nexus 4 23 API(with
GoogleAPIs), приложение вылетает.
Вопрос: Что можно предпринять, чтобы фрагмент с картами корректно запускался и отображал
карты на эмуляторе?
Прилагаю стактрейс ошибки, полный код фрагмента, и частично лэйаут, манифест и Build.gradle.
Cтактрейс ошибки:
12-07 11:15:09.290 2318-2318/xx.xxx.xxx W/GooglePlayServicesUtil: Google Play services
out of date. Requires 8298000 but found 8185480
12-07 11:15:09.290 2318-2318/xx.xxx.xxx W/GooglePlayServicesUtil: Google Play services
out of date. Requires 8298000 but found 8185480
12-07 11:15:09.290 2318-2318/xx.xxx.xxx W/GooglePlayServicesUtil: Google Play services
out of date. Requires 8298000 but found 8185480
12-07 11:15:09.290 2318-2318/xx.xxx.xxx W/GooglePlayServicesUtil: Google Play services
out of date. Requires 8298000 but found 8185480
12-07 11:15:09.290 2318-2318/xx.xxx.xxx W/GooglePlayServicesUtil: Google Play services
out of date. Requires 8298000 but found 8185480
12-07 11:15:09.290 2318-2318/xx.xxx.xxx W/GooglePlayServicesUtil: Google Play services
out of date. Requires 8298000 but found 8185480
12-07 11:15:09.300 2318-2318/xx.xxx.xxx W/GooglePlayServicesUtil: Google Play services
out of date. Requires 8298000 but found 8185480
12-07 11:15:09.300 2318-2318/xx.xxx.xxx W/GooglePlayServicesUtil: Google Play services
out of date. Requires 8298000 but found 8185480
12-07 11:15:09.300 2318-2318/xx.xxx.xxx W/GooglePlayServicesUtil: Google Play services
out of date. Requires 8298000 but found 8185480
12-07 11:15:09.320 2318-2318/xx.xxx.xxx D/AndroidRuntime: Shutting down VM
12-07 11:15:09.320 2318-2318/xx.xxx.xxx E/ACRA: ACRA caught a NullPointerException
for xx.xxx.xxx
java.lang.NullPointerException:
Attempt to invoke virtual method 'void com.google.android.gms.maps.MapFragment.getMapAsync(com.google.android.gms.maps.OnMapReadyCallback)'
on a null object reference
at xx.xxx.xxx.courier.OrdersFragmentMap.onCreateView(OrdersFragmentMap.java:45)
at android.app.Fragment.performCreateView(Fragment.java:2220)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:973)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1148)
at android.app.BackStackRecord.run(BackStackRecord.java:793)
at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1535)
at android.app.FragmentManagerImpl$1.run(FragmentManager.java:482)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native
Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Код фрагмента с картами:
package xx.xxx.xxx.courier;
import android.os.Bundle;
import android.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import xx.xxx.xxx.R;
public class OrdersFragmentMap extends Fragment implements OnMapReadyCallback {
public static OrdersFragmentMap newInstance() { return new OrdersFragmentMap(); }
public OrdersFragmentMap() { }
@Override
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); }
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
savedInstanceState) {
View view = inflater.inflate(R.layout.courier_fragment_map, container, false);
MapFragment mapFragment = (MapFragment) getFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
return view;
}
@Override
public void onMapReady(GoogleMap googleMap) {
LatLng sydney = new LatLng(-33.867, 151.506);
googleMap.setMyLocationEnabled(true);
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney, 13));
googleMap.addMarker(new MarkerOptions().title("Sydney").snippet(
"The most populous city in Australia.").position(sydney));
}
@Override
public void onResume() {
super.onResume();
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public void onLowMemory() {
super.onLowMemory();
}
}
Лэйаут, содержащий MapFragment(фрагмент):
Манифест(фрагмент):
Build.gradle(фпагмент):
dependencies {
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.android.support:design:23.1.1'
compile 'com.android.support:support-v4:23.1.1'
compile 'com.nbsp:library:1.01'
compile 'info.hoang8f:android-segmented:1.0.6'
compile 'ch.acra:acra:4.7.0-RC.3'
compile 'com.google.android.gms:play-services-maps:8.3.0'
compile 'com.google.android.gms:play-services-ads:8.3.0'
compile 'com.google.android.gms:play-services-auth:8.3.0'
compile 'com.google.android.gms:play-services-gcm:8.3.0'
compile 'com.google.android.gms:play-services:8.3.0'
}
Ответы
Ответ 1
Решил проблему следующим образом. Во-первых изменил код класса фрагмента, чтобы приложение не вылетало на версиях API 21 и выше: public class OrdersFragmentMap extends Fragment implements OnMapReadyCallback, LoaderManager.LoaderCallbacks{ ArrayList freeOrders = new ArrayList<>(); ArrayList myOrders = new ArrayList<>(); private FragmentActivity myContext; public static OrdersFragmentMap newInstance() { return new OrdersFragmentMap(); } public OrdersFragmentMap() { } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.courier_fragment_map, container, false); FragmentManager fm = myContext.getSupportFragmentManager(); SupportMapFragment mapFragment = SupportMapFragment.newInstance(); fm.beginTransaction().replace(R.id.map, mapFragment).commit(); mapFragment.getMapAsync(this); return view; } @Override public void onMapReady(GoogleMap googleMap) { LatLng sydney = new LatLng(-33.867, 151.506); googleMap.setMyLocationEnabled(true); googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney, 13)); googleMap.addMarker(new MarkerOptions().title("Sydney").snippet( "The most populous city in Australia.").position(sydney)); } @Override public void onResume() { super.onResume(); } @Override public void onDestroy() { super.onDestroy(); } @Override public void onLowMemory() { super.onLowMemory(); } @Override public void onAttach(Activity activity) { myContext=(FragmentActivity) activity; super.onAttach(activity); Метод onAttach() является устаревшим и я использую его временно только для того, чтобы запустить android.support.v4.app.FragmentManager в AppCompatActivity. Во-вторых создал шаблон MapActivity, для этого в корне проекта щелкнуть правой клавишей мыши, выбрать new>Google>GoogleMapsActivity. Из трех созданных файлов оставил только res/values/google_maps_api.xml(debug), скопировал из него ссылку для генерации ключа, которая находится в комментарии, перешел по ней в браузере, создал ключ и все заработало. Самое странное, что до этого вводил тот же фингерпринт и имя пакета. Такие вот дела. А на Galaxy S4 API работал, видимо, в обход защиты Google, так как запросов в консоли разработчика во время работы приложения не было.
Комментариев нет:
Отправить комментарий