尽管提到了地图库并使用了 google API,但错误膨胀 class com.google.android.maps.MapView

Error Inflating class com.google.android.maps.MapView though map library is mentioned and google API is used

我已经按照 this page 中的教程创建了一个 google 地图应用程序。除了 android 目标版本之外,代码与本页中的代码相同。我已将 Google APIs 版本 23 设置为目标。下面是我的清单。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.androidhive.googleplacesandmaps"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
    android:minSdkVersion="11" />

<application
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >

    <!--  Add Google Map Library -->
    <uses-library android:name="com.google.android.maps" />

    <activity
        android:name="com.places.googleplacesandmaps.MainActivity"
        android:label="@string/title_activity_main" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <!-- SinglePlaceActivity -->
    <activity android:name="com.places.googleplacesandmaps.SinglePlaceActivity" android:label="Place Details">
    </activity>

    <!-- PlacesMapActivity -->
    <activity android:name="com.places.googleplacesandmaps.PlacesMapActivity" android:label="Near Places Map View">
    </activity>
</application>

<!-- Internet Permissions -->
<uses-permission android:name="android.permission.INTERNET" />

<!-- Network State Permissions -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<!-- Access Location -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

<uses-feature android:glEsVersion="0x00020000" android:required="true"/>

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

我提到了解决同一问题的某些其他问题,但与那里提到的不同,我扩展了地图 activity 并且设置了 Google API 而不是 Android API。我还把地图库放在了清单中。我在这里做错了什么。请指教。请注意,我在我的模拟器中是 运行 这个,也是 Google API23。但是我没有做任何特殊配置。

下面是 logcat 输出。

01-02 19:44:13.430: E/AndroidRuntime(1209): FATAL EXCEPTION: main
01-02 19:44:13.430: E/AndroidRuntime(1209): Process: com.androidhive.googleplacesandmaps, PID: 1209
01-02 19:44:13.430: E/AndroidRuntime(1209): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.androidhive.googleplacesandmaps/com.places.googleplacesandmaps.MainActivity}: android.view.InflateException: Binary XML file line #25: Error inflating class com.google.android.maps.MapView
01-02 19:44:13.430: E/AndroidRuntime(1209):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
01-02 19:44:13.430: E/AndroidRuntime(1209):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
01-02 19:44:13.430: E/AndroidRuntime(1209):     at android.app.ActivityThread.access0(ActivityThread.java:135)
01-02 19:44:13.430: E/AndroidRuntime(1209):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
01-02 19:44:13.430: E/AndroidRuntime(1209):     at android.os.Handler.dispatchMessage(Handler.java:102)
01-02 19:44:13.430: E/AndroidRuntime(1209):     at android.os.Looper.loop(Looper.java:136)
01-02 19:44:13.430: E/AndroidRuntime(1209):     at android.app.ActivityThread.main(ActivityThread.java:5017)
01-02 19:44:13.430: E/AndroidRuntime(1209):     at java.lang.reflect.Method.invokeNative(Native Method)
01-02 19:44:13.430: E/AndroidRuntime(1209):     at java.lang.reflect.Method.invoke(Method.java:515)
01-02 19:44:13.430: E/AndroidRuntime(1209):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
01-02 19:44:13.430: E/AndroidRuntime(1209):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
01-02 19:44:13.430: E/AndroidRuntime(1209):     at dalvik.system.NativeStart.main(Native Method)
01-02 19:44:13.430: E/AndroidRuntime(1209): Caused by: android.view.InflateException: Binary XML file line #25: Error inflating class com.google.android.maps.MapView
01-02 19:44:13.430: E/AndroidRuntime(1209):     at android.view.LayoutInflater.createView(LayoutInflater.java:621)
01-02 19:44:13.430: E/AndroidRuntime(1209):     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:697)
01-02 19:44:13.430: E/AndroidRuntime(1209):     at android.view.LayoutInflater.rInflate(LayoutInflater.java:756)
01-02 19:44:13.430: E/AndroidRuntime(1209):     at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
01-02 19:44:13.430: E/AndroidRuntime(1209):     at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
01-02 19:44:13.430: E/AndroidRuntime(1209):     at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
01-02 19:44:13.430: E/AndroidRuntime(1209):     at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:290)
01-02 19:44:13.430: E/AndroidRuntime(1209):     at android.app.Activity.setContentView(Activity.java:1929)
01-02 19:44:13.430: E/AndroidRuntime(1209):     at com.places.googleplacesandmaps.MainActivity.onCreate(MainActivity.java:67)
01-02 19:44:13.430: E/AndroidRuntime(1209):     at android.app.Activity.performCreate(Activity.java:5231)
01-02 19:44:13.430: E/AndroidRuntime(1209):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
01-02 19:44:13.430: E/AndroidRuntime(1209):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
01-02 19:44:13.430: E/AndroidRuntime(1209):     ... 11 more
01-02 19:44:13.430: E/AndroidRuntime(1209): Caused by: java.lang.reflect.InvocationTargetException
01-02 19:44:13.430: E/AndroidRuntime(1209):     at java.lang.reflect.Constructor.constructNative(Native Method)
01-02 19:44:13.430: E/AndroidRuntime(1209):     at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
01-02 19:44:13.430: E/AndroidRuntime(1209):     at android.view.LayoutInflater.createView(LayoutInflater.java:595)
01-02 19:44:13.430: E/AndroidRuntime(1209):     ... 22 more
01-02 19:44:13.430: E/AndroidRuntime(1209): Caused by: java.lang.IllegalArgumentException: MapViews can only be created inside instances of MapActivity.
01-02 19:44:13.430: E/AndroidRuntime(1209):     at com.google.android.maps.MapView.<init>(MapView.java:291)
01-02 19:44:13.430: E/AndroidRuntime(1209):     at com.google.android.maps.MapView.<init>(MapView.java:264)
01-02 19:44:13.430: E/AndroidRuntime(1209):     at com.google.android.maps.MapView.<init>(MapView.java:247)
01-02 19:44:13.430: E/AndroidRuntime(1209):     ... 25 more

在 CommonsWare 的回答之后:

public class MainActivity extends FragmentActivity implements LocationListener {

GoogleMap mGoogleMap;
Spinner mSprPlaceType;

String[] mPlaceType = null;
String[] mPlaceTypeName = null;

double mLatitude = 0;
double mLongitude = 0;

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Array of place types
    mPlaceType = getResources().getStringArray(R.array.place_type);

    // Array of place type names
    mPlaceTypeName = getResources().getStringArray(R.array.place_type_name);

    // Creating an array adapter with an array of Place types
    // to populate the spinner
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item,
            mPlaceTypeName);

    // Getting reference to the Spinner
    mSprPlaceType = (Spinner) findViewById(R.id.spr_place_type);

    // Setting adapter on Spinner to set place types
    mSprPlaceType.setAdapter(adapter);

    Button btnFind;

    // Getting reference to Find Button
    btnFind = (Button) findViewById(R.id.btn_find);

    // Getting Google Play availability status
    int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getBaseContext());

    if (status != ConnectionResult.SUCCESS) { // Google Play Services are
                                                // not available

        int requestCode = 10;
        Dialog dialog = GooglePlayServicesUtil.getErrorDialog(status, this, requestCode);
        dialog.show();

    } else { // Google Play Services are available

        // Getting reference to the SupportMapFragment
        SupportMapFragment fragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);

        // Getting Google Map
        mGoogleMap = fragment.getMap();

        // Enabling MyLocation in Google Map
        mGoogleMap.setMyLocationEnabled(true);

        // Getting LocationManager object from System Service
        // LOCATION_SERVICE
        LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);

        // Creating a criteria object to retrieve provider
        Criteria criteria = new Criteria();

        // Getting the name of the best provider
        String provider = locationManager.getBestProvider(criteria, true);

        // Getting Current Location From GPS
        Location location = locationManager.getLastKnownLocation(provider);

        if (location != null) {
            onLocationChanged(location);
        }

        locationManager.requestLocationUpdates(provider, 20000, 0, this);

        // Setting click event lister for the find button
        btnFind.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

                int selectedPosition = mSprPlaceType.getSelectedItemPosition();
                String type = mPlaceType[selectedPosition];

                StringBuilder sb = new StringBuilder(
                        "https://maps.googleapis.com/maps/api/place/nearbysearch/json?");
                sb.append("location=" + mLatitude + "," + mLongitude);
                sb.append("&radius=5000");
                sb.append("&types=" + type);
                sb.append("&sensor=true");
                sb.append("&key=AIzaSyC_HOr2br_lboJAt-J8eUzmJoVhRAyyK50");

                // Creating a new non-ui thread task to download json data
                PlacesTask placesTask = new PlacesTask();

                // Invokes the "doInBackground()" method of the class
                // PlaceTask
                placesTask.execute(sb.toString());

            }
        });

    }

}

/** A method to download json data from url */
private String downloadUrl(String strUrl) throws IOException {
    String data = "";
    InputStream iStream = null;
    HttpURLConnection urlConnection = null;
    try {
        URL url = new URL(strUrl);

        // Creating an http connection to communicate with url
        urlConnection = (HttpURLConnection) url.openConnection();

        // Connecting to url
        urlConnection.connect();

        // Reading data from url
        iStream = urlConnection.getInputStream();

        BufferedReader br = new BufferedReader(new InputStreamReader(iStream));

        StringBuffer sb = new StringBuffer();

        String line = "";
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }

        data = sb.toString();

        br.close();

    } catch (Exception e) {
        Log.d("Exception while downloading url", e.toString());
    } finally {
        iStream.close();
        urlConnection.disconnect();
    }

    return data;
}

/** A class, to download Google Places */
private class PlacesTask extends AsyncTask<String, Integer, String> {

    String data = null;

    // Invoked by execute() method of this object
    @Override
    protected String doInBackground(String... url) {
        try {
            data = downloadUrl(url[0]);
        } catch (Exception e) {
            Log.d("Background Task", e.toString());
        }
        return data;
    }

    // Executed after the complete execution of doInBackground() method
    @Override
    protected void onPostExecute(String result) {
        ParserTask parserTask = new ParserTask();

        // Start parsing the Google places in JSON format
        // Invokes the "doInBackground()" method of the class ParseTask
        parserTask.execute(result);
    }

}

/** A class to parse the Google Places in JSON format */
private class ParserTask extends AsyncTask<String, Integer, List<HashMap<String, String>>> {

    JSONObject jObject;

    // Invoked by execute() method of this object
    @Override
    protected List<HashMap<String, String>> doInBackground(String... jsonData) {

        List<HashMap<String, String>> places = null;
        PlaceJSONParser placeJsonParser = new PlaceJSONParser();

        try {
            jObject = new JSONObject(jsonData[0]);

            /** Getting the parsed data as a List construct */
            places = placeJsonParser.parse(jObject);

        } catch (Exception e) {
            Log.d("Exception", e.toString());
        }
        return places;
    }

    // Executed after the complete execution of doInBackground() method
    @Override
    protected void onPostExecute(List<HashMap<String, String>> list) {

        // Clears all the existing markers
        mGoogleMap.clear();

        for (int i = 0; i < list.size(); i++) {

            // Creating a marker
            MarkerOptions markerOptions = new MarkerOptions();

            // Getting a place from the places list
            HashMap<String, String> hmPlace = list.get(i);

            // Getting latitude of the place
            double lat = Double.parseDouble(hmPlace.get("lat"));

            // Getting longitude of the place
            double lng = Double.parseDouble(hmPlace.get("lng"));

            // Getting name
            String name = hmPlace.get("place_name");

            // Getting vicinity
            String vicinity = hmPlace.get("vicinity");

            LatLng latLng = new LatLng(lat, lng);

            // Setting the position for the marker
            markerOptions.position(latLng);

            // Setting the title for the marker.
            // This will be displayed on taping the marker
            markerOptions.title(name + " : " + vicinity);

            // Placing a marker on the touched position
            mGoogleMap.addMarker(markerOptions);
        }
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public void onLocationChanged(Location location) {
    mLatitude = location.getLatitude();
    mLongitude = location.getLongitude();
    LatLng latLng = new LatLng(mLatitude, mLongitude);

    mGoogleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
    mGoogleMap.animateCamera(CameraUpdateFactory.zoomTo(12));
}

@Override
public void onProviderDisabled(String provider) {
    // TODO Auto-generated method stub
}

@Override
public void onProviderEnabled(String provider) {
    // TODO Auto-generated method stub
}

@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
    // TODO Auto-generated method stub
}

activity_main.xml

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/ScrollView01"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.listviewtest.MainActivity" >

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_below="@+id/checkBox11"
        android:text="Save" >
    </Button>

    <CheckBox
        android:id="@+id/checkBox1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:text="Airport" />

    <CheckBox
        android:id="@+id/checkBox2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/checkBox1"
        android:text="ATM" />

    <CheckBox
        android:id="@+id/checkBox3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/checkBox2"
        android:text="Bank" />

    <CheckBox
        android:id="@+id/checkBox4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/checkBox3"
        android:text="Bus Station" />

    <CheckBox
        android:id="@+id/checkBox5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/checkBox4"
        android:text="Church" />

    <CheckBox
        android:id="@+id/checkBox6"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/checkBox5"
        android:text="Doctor" />

    <CheckBox
        android:id="@+id/checkBox7"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/checkBox6"
        android:text="Hospital" />

    <CheckBox
        android:id="@+id/checkBox8"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/checkBox7"
        android:text="Mosque" />

    <CheckBox
        android:id="@+id/checkBox9"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/checkBox8"
        android:text="Movie Theater" />

    <CheckBox
        android:id="@+id/checkBox10"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/checkBox9"
        android:text="Hindu Temple" />

    <CheckBox
        android:id="@+id/checkBox11"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/checkBox10"
        android:text="Restaurant" />
</RelativeLayout>

</ScrollView>

您正在尝试使用原始版本的 Google 地图支持 Android (com.google.android.maps)。我们现在将其称为 Maps V1。

这行不通,因为 Maps V1 已被弃用两年多了。你不能再为它获得 API 键,所以即使你的代码是正确的,它也不会工作。崩溃是因为必须在 MapActivity 内部使用旧的 MapView,如错误所示。

The current version of Google Maps support for Android — Maps V2 — 有一个非常不同的 API 并且不涉及 com.google.android.maps 包中的 类。