0

在我的应用程序中,我最近将 Google 地图从 V1 升级到了 V2。现在,使用 HTC One S (Android 4.1.1),当我打开 GPS 并进入地图活动时,应用程序会识别出 GPS 已打开,但它的图标没有出现,并且应用程序无法找到我的位置。
在三星 Galaxy Y (Android 2.3) 等设备上,地图可以正常运行。
在三星 Galaxy S2 (Android 4.1.2)、HTC Wildfire (Android 2.3) 等其他设备上,GPS 图标不会出现,但应用程序会找到我的位置。
我哪里错了?

班级:

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;
    }
}

显现:

<?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>
4

2 回答 2

2

按照@Nevermore 的建议,我解决了实现 OnMyLocationChangeListener 而不是 LocationSource 和 LocationListener 的问题。
我以这种方式更改了代码:

public class CercaPuntoVendita extends FragmentActivity implements OnMarkerClickListener, OnMyLocationChangeListener {
    //...
    public void onMyLocationChange(Location location) {
        mMap.animateCamera(
            CameraUpdateFactory.newLatLng(
                new LatLng(location.getLatitude(), location.getLongitude())));
    }
}
于 2013-04-26T15:50:06.873 回答
1

我发现这个问题取决于指令:

map.setLocationSource(this);

如果我不使用它,GPS 工作正常,但它不能“跟随”我的位置。我必须以一种始终可以设置位置源的方式放置此指令,即使我在运行中打开 GPS 时也是如此……

于 2013-04-24T06:50:18.090 回答