Issue
I have followed the tutorial in this page and created a google maps application. Code is the same as it is in this page apart from android target versions. I have set Google APIs version 23 as the target. Below is my manifest.
<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"/>
I referred to certain other questions addressing the same issue, but unlike mentioned there, I have extended the map activity and I have set the Google API instead of Android API. Also I have put the map library in the manifest. What am I doing wrong here. Please advice. Please note that I am running this in my emulator which is Google API23 as well. But I haven't done any special configurations though.
Below is the logcat output.
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.access$800(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
After CommonsWare's answer:
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>
Solution
You are attempting to use the original version of Google Maps support for Android (com.google.android.maps
). We refer to that now as Maps V1.
This will not work, as Maps V1 has been deprecated for over two years. You can no longer get API keys for it, so even if your code would be correct, it would not work. The crash is because the old MapView
had to be used inside of a MapActivity
, as the error indicates.
The current version of Google Maps support for Android — Maps V2 — has a very different API and does not involve classes in the com.google.android.maps
package.
Answered By - CommonsWare
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.