In my app I have recently upgraded Google Maps from V1 to V2.
Now, with an HTC One S (Android 4.1.1) when I switch on GPS and enter in the map activity, the app recognizes that GPS is on but its icon doesn't appear and the app can't find my location.
On devices like Samsung Galaxy Y (Android 2.3) the map works without problems.
On others like Samsung Galaxy S2 (Android 4.1.2), HTC Wildfire (Android 2.3) the GPS icon doesn't appear but the apps finds my location.
Where I'm wrong?
Class:
public class CercaPuntoVendita extends FragmentActivity implements OnMarkerClickListener, LocationSource, LocationListener {
// Identificatore del messaggio della Map
private final static int MAP_MESSAGE_ID = 1;
// Identificatore della ProgressBar
private final static int PROGRESS_DIALOG_ID = 1;
// Riferimento alla Map
private GoogleMap map;
// Riferimento alle UiSettings
private UiSettings uis;
// Riferimento al GeoCoder
private Geocoder geocoder;
// Riferimento alla EditText
private EditText inputName;
// Livello di Zoom
private int nMetriDiametroCitta = 10000;
private int nMetriDiametroVia = 1500;
//Riferimento al MapController
public static MapController mapController;
//Otteniamo il riferimento al LocationManager
private LocationManager myLocationManager = null;
private OnLocationChangedListener myLocationListener = null;
private Criteria myCriteria;
private PuntiVendita overlays = null;
private Context ctx = this;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Mettiamo la View a tutto schermo
requestWindowFeature(Window.FEATURE_NO_TITLE);
// Visualizziamo la Map
setContentView(R.layout.cerca_punto_vendita);
// Gestione font
Button btnSearch = (Button) findViewById(R.id.searchButton);
Typeface tf = Typeface.createFromAsset(ctx.getAssets(), "fonts/CRAI_regular.ttf");
Utils.setFontMultiple(tf, btnSearch);
// Set up della map
setUpMapIfNeeded();
// Riferimento al campo di testo
inputName = (EditText)findViewById(R.id.addressName);
// Otteniamo il riferimento al geocoder
geocoder = new Geocoder(this,Locale.ITALY);
// Otteniamo il riferimento al location manager
myLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
// Verifichiamo se il GPS è abilitato altrimenti avvisiamo l'utente
if(!myLocationManager.isProviderEnabled("gps")) {
Utils.showWarningDialog(this, "GPS è attualmente disabilitato. E' possibile abilitarlo dal menu impostazioni.");
}
// muovo la mappa su Roma
map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(41.893, 12.482), calculateZoomLevel(nMetriDiametroCitta)));
}
@Override
public void onPause() {
super.onPause();
map.setLocationSource(null);
myLocationManager.removeUpdates(this);
}
@Override
protected void onResume() {
super.onResume();
setUpMapIfNeeded();
map.setMyLocationEnabled(true);
uis = map.getUiSettings();
uis.setMyLocationButtonEnabled(false);
myCriteria = new Criteria();
myCriteria.setAccuracy(Criteria.ACCURACY_COARSE);
myLocationManager = (LocationManager)getSystemService(LOCATION_SERVICE);
// Verifichiamo se il GPS è abilitato altrimenti avvisiamo l'utente
if(myLocationManager.isProviderEnabled("gps")) {
try {
Location loc = myLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(loc.getLatitude(), loc.getLongitude()), calculateZoomLevel(nMetriDiametroVia)));
} catch (NullPointerException e) {
}
//Register for location updates using a Criteria, and a callback on the specified looper thread.
myLocationManager.requestLocationUpdates(
0L, //minTime
0.0f, //minDistance
myCriteria, //criteria
this, //listener
null); //looper
//Replaces the location source of the my-location layer.
map.setLocationSource(this);
}
//myLocationManager.getProviders(true);
}
public static double getRound(double x, int digits){
double powerOfTen = Math.pow(10, digits);
return (Math.round(x * powerOfTen) / powerOfTen);
}
/**
* Permette di iniziare la ricerca
*
* @param button
* Riferimento al button
*/
public void searchPlace(View button) {
hideSoftInput();
Thread searchThread = new Thread("SearchThread") {
@Override
public void run() {
// Otteniamo il messaggio
Message message = mapHandler.obtainMessage();
// Utilizziamo il Geocoder per fare la ricerca
try {
List<Address> risultati = geocoder.getFromLocationName(inputName.getText().toString().trim(), 1);
// Se c'e' qualcosa lo notifichiamo
if (risultati != null && risultati.size() > 0) {
message.obj = risultati.get(0);
mapHandler.sendMessage(message);
} else {
runOnUiThread(new Runnable() {
public void run() {
Utils.msg(CercaPuntoVendita.this, "Nessun risultato trovato");
}
});
}
} catch (IOException e) {
// Non facciamo nulla ma arriva il messaggio vuoto
mapHandler.sendEmptyMessage(MAP_MESSAGE_ID);
} finally {
dismissDialog(PROGRESS_DIALOG_ID);
}
}
};
// Visualizziamo la progressDialog
showDialog(PROGRESS_DIALOG_ID);
// Facciamo partire il Thread
searchThread.start();
}
private final Handler mapHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
// Si ottengono le informazioni se presenti sulla posizione
if (msg != null && msg.obj != null) {
// Estraiamo le informazioni di posizione
try {
Address address = (Address)msg.obj;
Log.d("CercaPuntoVendita.this", "" + address.getLocality());
GeoPoint pointToGo = new GeoPoint((int)(address.getLatitude()*1000000),(int)(address.getLongitude()*1000000));
float dZoom = 0;
if (address.getLocality().equalsIgnoreCase(inputName.getText().toString().trim())) {
// se la locality è uguale alla stringa di ricerca, si tratta di una citta'
dZoom = calculateZoomLevel(nMetriDiametroCitta);
} else {
dZoom = calculateZoomLevel(nMetriDiametroVia);
}
map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(address.getLatitude(), address.getLongitude()), dZoom));
} catch (NullPointerException ex) {
Utils.msg(CercaPuntoVendita.this, "Nessun risultato trovato");
Log.w("Punti Vendita - Cerca", (ex.getMessage() == null)?"address = null":ex.getMessage());
}
} else {
Utils.msg(CercaPuntoVendita.this, "Nessun risultato trovato");
}
Log.i("GEOCODER", "" + msg);
if (msg != null) {
Log.i("GEOCODER", "" + msg.obj);
}
}
};
@Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case PROGRESS_DIALOG_ID:
ProgressDialog progressDialog = new ProgressDialog(this, ProgressDialog.STYLE_SPINNER);
progressDialog.setIndeterminate(true);
progressDialog.setTitle("Cerca Punti Vendita");
progressDialog.setMessage("Cercando...");
return progressDialog;
default:
return null;
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Menù di gestione modalità di visualizzazione che, per renderle checkable le inseriamo in un sottomenu
SubMenu mapSubMenu = menu.addSubMenu("Modalità Mappa");
mapSubMenu.setIcon(android.R.drawable.ic_menu_mapmode);
int firstItem = Menu.FIRST;
MenuItem trafficItem = mapSubMenu.add(1, firstItem, firstItem, "Traffic");
trafficItem.setCheckable(true);
trafficItem.setChecked(false);
MenuItem satelliteItem = mapSubMenu.add(1, firstItem + 1, firstItem + 1, "Satellite");
satelliteItem.setCheckable(true);
trafficItem.setChecked(false);
// Visualizziamo il menu
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Modifichiamo lo stato di quella selezionata
item.setChecked(!item.isChecked());
// Abilitiamo o meno l'opzione relativa
switch (item.getItemId()) {
case Menu.FIRST:
map.setTrafficEnabled(item.isChecked());
break;
case Menu.FIRST + 1:
if (item.isChecked())
map.setMapType(MAP_TYPE_SATELLITE);
else
map.setMapType(MAP_TYPE_NORMAL);
break;
}
return super.onOptionsItemSelected(item);
}
protected boolean isRouteDisplayed() {
return false;
}
private void hideSoftInput() {
InputMethodManager inputManager = (InputMethodManager) CercaPuntoVendita.this.getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(CercaPuntoVendita.this.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
public boolean onMarkerClick(Marker mrk) {
final ProgressDialog progressDialog = ProgressDialog.show(ctx, "", "Caricamento in corso.\nAttendere prego...");
final String sSnippet = mrk.getSnippet();
new Thread() {
@Override
public void run() {
try {
sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
Intent intent = new Intent(ctx, PuntoVenditaDett.class);
intent.putExtra("myPdvId", sSnippet);
ctx.startActivity(intent);
progressDialog.dismiss();
}
}.start();
return true;
}
private void setUpMap() {
// Gestiamo gli Overlay
Drawable starImg = getResources().getDrawable(R.drawable.logominicrai);
if (overlays == null)
overlays = new PuntiVendita(starImg, this);
map.setOnMarkerClickListener(this);
for (int i=0; i < overlays.size(); i++) {
LatLng llPunto = new LatLng(overlays.getItem(i).getPoint().getLatitudeE6()/1E6, overlays.getItem(i).getPoint().getLongitudeE6()/1E6);
map.addMarker(new MarkerOptions()
.position(llPunto)
//.title(name)
.snippet(overlays.getItem(i).getSnippet())
.icon(BitmapDescriptorFactory
.fromResource(R.drawable.logominicrai)));
}
}
private void setUpMapIfNeeded() {
// Do a null check to confirm that we have not already instantiated the map.
if (map == null) {
// Try to obtain the map from the SupportMapFragment.
map = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
// Check if we were successful in obtaining the map.
if (map != null) {
setUpMap();
}
}
}
public void onLocationChanged(Location location) {
if (myLocationListener != null) {
myLocationListener.onLocationChanged(location);
LatLng latlng = new LatLng(location.getLatitude(), location.getLongitude());
map.animateCamera(CameraUpdateFactory.newLatLng(latlng));
}
}
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
public void activate(OnLocationChangedListener listener) {
myLocationListener = listener;
}
public void deactivate() {
myLocationListener = null;
}
}
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.gmaps"
android:versionCode="2"
android:versionName="2" >
<uses-sdk android:minSdkVersion="9" />
<!-- Google Maps API V2 -->
<permission
android:name="com.example.gmaps.permission.MAPS_RECEIVE"
android:protectionLevel="signature" />
<uses-feature
android:glEsVersion="0x00020000"
android:required="true" />
<uses-permission android:name="com.example.gmaps.permission.MAPS_RECEIVE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:allowBackup="true"
android:icon="@drawable/icon"
android:label="@string/app_name" >
<activity
android:name="com.fedrasoft.craiinforma.App"
android:configChanges="orientation|keyboardHidden|keyboard"
android:screenOrientation="portrait"
android:launchMode="singleTask" >
<!-- android:alwaysRetainTaskState="true" -->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.fedrasoft.craiinforma.CercaPuntoVendita"
android:label="@string/title_activity_cerca_punto_vendita"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="CercaPuntoVendita" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<uses-library android:name="com.google.android.maps" />
<!-- Google Maps API V2 -->
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="my key" />
</application>
</manifest>