Sto cercando di incorporare la nuova API di Google Maps per Android v2 in un'applicazione che utilizza la libreria di supporto Android. Ho attraversato molte iterazioni per cercare di ottenere un posto dove lavorare e ora ho rinunciato e ho pensato di dover chiedere qui.Google Maps API Android v2 genera GooglePlayServicesNotAvailableException, obsoleto, SupportMapFragment.getMap() restituisce null
Sono passato alla console API, ho creato un progetto, ho abilitato l'API di Google Maps v2 per Android, creato un debug KEY come richiesto e incollato sul manifest. Nessun problema di autenticazione o qualcosa del genere. Abbastanza sicuro di aver fatto bene.
Nella cartella libs
del mio progetto ho inserito android-support-v4.jar
(tramite il progetto tasto destro del mouse-> Android-> Aggiungi libreria di supporto ...). In Eclipse ho fatto File-> Importa-> Android-> Codice Android esistente in Workspace e importato l'ultimo (rev 3) di android-sdk/google/google_play_services/libproject/google-play-services_lib. Poi ho aggiunto come una libreria di dipendenza al mio progetto (progetto-destra click-> Proprietà-> Android-> Aggiungi come dipendenza libreria sul fondo
Nel mio manifesto ho:.
<manifest xmlns:android="http://schemas.android.com/apk/res/android" ...>
<permission
android:name="myapp.permission.MAPS_RECEIVE"
android:protectionLevel="signature"/>
<All the uses-permission required like INTERNET, ACCESS_NETWORK_STATE, WRITE_EXTERNAL_STORAGE, FINE AND COARSE LOCATION, etc>
<uses-permission android:name="myapp.permission.MAPS_RECEIVE"/>
<uses-feature android:glEsVersion="0x00020000" android:required="true"/>
<application ...>
...
<uses-library android:name="com.google.android.maps" />
<meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="AI..."/>
</application>
Nel mio mainview.xml ho:
<fragment
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/map"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
class="com.google.android.gms.maps.SupportMapFragment" />
Ora in MainView.java ho:
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
public class MainView extends FragmentActivity ... {
private GoogleMap mMap;
@Override
protected void onResume() {
...
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.map);
SupportMapFragment mapFragment = (SupportMapFragment)fragment;
mMap = mapFragment.getMap();
//PROBLEM: mMap is null here even though mapFragment is not
}
}
Poi ho tho effettuato l 'acquisto probabilmente ho bisogno di inizializzare i frammenti così ho aggiunto nella mia onCreate
dopo aver impostato la visualizzazione del contenuto:
//Fragments
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.add(R.id.map, SupportMapFragment.newInstance());
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
transaction.commit();
Allora ho detto, forse non è SupportMapFragment
ma io in realtà dovrebbe fare riferimento al frammento reale, e nella mia onResume
I fatto:
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.map);
SupportMapFragment mapFragment = (SupportMapFragment)fragment;
//Fragments
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.add(R.id.map, mapFragment);
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
transaction.commit();
mMap = mapFragment.getMap();
mMap
è nuovamente nullo dopo questo.
Poi ho visto che c'è una classe MapsInitializer
, quindi ho pensato che forse dovrei chiamarla prima.
Così ho aggiunto il codice prima di ottenere il frammento di codice di cui sopra:
try {
MapsInitializer.initialize(this);
} catch (GooglePlayServicesNotAvailableException e) {
e.printStackTrace();
}
Con questa Logcat riportato l'avvertimento (linea 313 è il MapsInitializer.initialize(this)
):
com.google.android.gms.common.GooglePlayServicesNotAvailableException
at com.google.android.gms.internal.n.c(Unknown Source)
at com.google.android.gms.internal.n.a(Unknown Source)
at com.google.android.gms.maps.MapsInitializer.initialize(Unknown Source)
at myapp.activities.MainView.inflateSelectedViewAndSetData(MainView.java:313)
at myapp.activities.MainView.onClick(MainView.java:642)
at android.view.View.performClick(View.java:3153)
at android.view.View$PerformClick.run(View.java:12148)
at android.os.Handler.handleCallback(Handler.java:587)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:152)
at android.app.ActivityThread.main(ActivityThread.java:4615)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:491)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
at dalvik.system.NativeStart.main(Native Method)
Durante i miei tentativi Logcat segnalerebbe il seguente avviso:
Google Play services out of date. Requires 2010100 but found 1013
Questo potrebbe essere a/il colpevole ma non ho trovato soluzione.
A questo punto sono fuori di idee. Ho letto diverse discussioni here, here, here ma nessuno dei suggerimenti ha risolto il problema. Su quest'ultimo suggeriscono di non includere la dipendenza del progetto e di includere solo il file jar. Bene, non ha funzionato né usando google-play-services.jar
dalla cartella google-play-services_lib/libs
né esportando il mio barattolo da quel progetto.
A proposito, sto utilizzando un dispositivo reale (2.3.5 e un tablet con 3.2), non l'emulatore.
Qualsiasi aiuto apprezzato di tutto cuore. :)
UPDATE:
La soluzione è appresso con qubit.
Per quanto esportare la dipendenza biblioteca, un modo pulito per non avere a che fare con esso (che è un dolore quando si tratta di repository) è quello di utilizzare FatJar ed esportare il progetto google_play_services_lib
(che non ho creato una copia locale da perché quando si aggiorna non voglio reimportare) e includere il file jar di output fat nel tuo progetto come un altro file jar. NOTA: quando ho scelto i file jar da includere nel contenitore di grassi, ho dovuto escludere il file annotations.jar
poiché era già pre-incluso e causava errori di duplicazione. Ora tutto quello che devo fare è includere lo google_play_services_rev_3.jar
nella cartella libs
del mio progetto e sono a posto.
Poiché questa non è una risposta al tuo problema, la darò solo come commento: quando non vuoi fare più di localizzazione basata su GPS/WLAN, mostrando mappe, disegnando in mappe mostrate raccomandiamo di usare le classi ouf di http://sourceforge.net/projects/libwlocate/. IMHO sono molto più facili da gestire e forniscono supporto per diversi tipi di mappe. – Elmi
Questo "google_play_services_rev_3.jar" dovrebbe essere generico, lo stesso vale per qualsiasi progetto e configurazione, suppongo?Grazie per il suggerimento di FatJar, ho ottenuto il mio progetto lavorando in Jenkins CI con questa procedura. – JaakL
@JaakL Sì, è generico e puoi importarlo su qualsiasi progetto. :) – iliask