在我的应用程序中,我正在解析字符串,如" hospital"从onDrawerItemSelected()中的MainActivity到谷歌地图,谷歌地图在一个片段中定义,以显示附近的医院..
但是当我调用HomeFragment的这个名为showPlaces(int position)的方法来显示字符串命名的附近位置时,错误发生在:
' void com.google.android.gms.maps.GoogleMap.clear()'在空对象引用上
这是我的整个项目:
MainActivity的布局:
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"android:clickable="true"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Framelayout to display Fragments -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="@+id/container_toolbar">
<include
layout="@layout/toolbar"
android:id="@+id/toolbar"/>
</LinearLayout>
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="0dp"
android:id="@+id/container_body"
android:layout_weight="1"
/>
</LinearLayout>
<fragment
android:layout_width="@dimen/nav_drawer_width"
android:layout_height="match_parent"
android:id="@+id/fragment_navigation_drawer"
android:layout_gravity="start"
app:layout="@layout/fragment_navigation_drawer"
tools:layout="@layout/fragment_navigation_drawer"
android:name="mayur.projectwork3.FragmentDrawer"
/>
<!-- Listview to display slider menu -->
</android.support.v4.widget.DrawerLayout>
MainActivity.java
package mayur.projectwork3;
import android.support.v4.view.GravityCompat;
import android.support.v7.app.ActionBar;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends ActionBarActivity implements FragmentDrawer.FragmentDrawerListener {
private static String TAG = MainActivity.class.getSimpleName();
private Toolbar mToolbar;
private FragmentDrawer drawerFragment;
HomeFragment homeFragment = new HomeFragment();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayShowHomeEnabled(true);
drawerFragment = (FragmentDrawer)getSupportFragmentManager().findFragmentById(R.id.fragment_navigation_drawer);
drawerFragment.setUp(R.id.fragment_navigation_drawer, (DrawerLayout) findViewById(R.id.drawer_layout), mToolbar);
drawerFragment.setDrawerListener(this);
// display the first navigation drawer view on app launch
displayView(0);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onDrawerItemSelected(View view, int position)
{
homeFragment.showPlaces(position);
}
private void displayView(int position) {
Fragment fragment = null;
String title = getString(R.string.app_name);
switch (position) {
case 0:
fragment = new HomeFragment();
break;
default:
fragment = new HomeFragment();
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.container_body, fragment);
fragmentTransaction.commit();
// set the toolbar title
getSupportActionBar().setTitle(title);
}
}
}
Layout of HomeFragment:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="mayur.projectwork3.HomeFragment">
<com.google.android.gms.maps.MapView
android:id="@+id/map"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
HomeFragment.java:
package mayur.projectwork3;
import android.app.Activity;
import android.location.Location;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
public class HomeFragment extends Fragment
{
String[] mPlaceType=null;
String[] mPlaceTypeName=null;
GPSTracker gpsTracker;
double mLatitude=0;
double mLongitude=0;
HashMap<String, String> mMarkerPlaceLink = new HashMap<String, String>();
GoogleMap googleMap;
MapView mapView;
public HomeFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_map, container, false);
mapView = (MapView)rootView.findViewById(R.id.map);
mapView.onCreate(savedInstanceState);
setUpMap();
// Inflate the layout for this fragment
return rootView;
}
public void setUpMap()
{
gpsTracker = new GPSTracker(this.getActivity());
googleMap = mapView.getMap();
googleMap.getUiSettings().setMyLocationButtonEnabled(false);
googleMap.setMyLocationEnabled(true);
try {
MapsInitializer.initialize(this.getActivity());
} catch (Exception e) {
e.printStackTrace();
}
LatLng latLng = new LatLng(gpsTracker.getLatitude(),gpsTracker.getLongitude());
googleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
googleMap.animateCamera(CameraUpdateFactory.zoomTo(12));
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
}
@Override
public void onDetach() {
super.onDetach();
}
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 loading 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);
}
}
public void showPlaces(int position)
{
gpsTracker = new GPSTracker(this.getActivity());
if(isAdded())
mPlaceType = getResources().getStringArray(R.array.places_type);
String type = "hospital";
mLatitude =gpsTracker.getLatitude();
mLongitude =gpsTracker.getLongitude();
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=AIzaSyAED02xYclV3_jIri8Clz37DbZjeze-XSw");
// Creating a new non-ui thread task to download Google place json data
PlacesTask placesTask = new PlacesTask();
// Invokes the "doInBackground()" method of the class PlaceTask
placesTask.execute(sb.toString());
}
/** 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
googleMap.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
Marker m = googleMap.addMarker(markerOptions);
// Linking Marker id and place reference
mMarkerPlaceLink.put(m.getId(), hmPlace.get("reference"));
}
}
}
@Override
public void onResume() {
mapView.onResume();
super.onResume();
}
@Override
public void onDestroy() {
super.onDestroy();
mapView.onDestroy();
}
@Override
public void onLowMemory() {
super.onLowMemory();
mapView.onLowMemory();
}
}