Страницы

Поиск по вопросам

пятница, 24 января 2020 г.

Приложение вылетает с NullPointerException при переходе на MapFragment на эмуляторе

#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, так как запросов в консоли разработчика во время работы приложения не было.

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

Отправить комментарий