2014-09-18 68 views
0

我的android google地图应用程序崩溃了空指针异常,因为Support Fragment Map对象没有被创建。 请帮我诊断导致此问题。 显然,每个人都有不同的问题导致该如此重复问题:fm.getMap()在Android地图应用程序中返回null

这里是我的代码: -

package com.iiitk.zeda.flashcabs; 
import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.net.HttpURLConnection; 
import java.net.URL; 
import java.util.ArrayList; 
import java.util.HashMap; 
import java.util.List; 

import org.json.JSONObject; 

import android.graphics.Color; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.support.v4.app.FragmentActivity; 
import android.util.Log; 
import android.view.Menu; 
import android.widget.TextView; 
import android.widget.Toast; 

import com.google.android.gms.maps.GoogleMap; 
import com.google.android.gms.maps.GoogleMap.OnMapClickListener; 
import com.google.android.gms.maps.MapFragment; 
import com.google.android.gms.maps.SupportMapFragment; 
import com.google.android.gms.maps.model.BitmapDescriptorFactory; 
import com.google.android.gms.maps.model.LatLng; 
import com.google.android.gms.maps.model.MarkerOptions; 
import com.google.android.gms.maps.model.PolylineOptions; 
import com.iiitk.zeda.flashcabs.DirectionsJSONParser; 


public class Home extends FragmentActivity { 

GoogleMap map; 
ArrayList<LatLng> markerPoints; 
TextView tvDistanceDuration; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_home); 

    tvDistanceDuration = (TextView) findViewById(R.id.tv_distance_time); 

    // Initializing 
    markerPoints = new ArrayList<LatLng>(); 

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


    // MapFragment fm = (MapFragment) getFragmentManager().findFragmentById(R.id.map); 

while(fm==null) { 
    int a=10; 
} 

    map = fm.getMap(); 
    // Getting Map for the SupportMapFragment 
    //map = fm.getMap(); 

    // Enable MyLocation Button in the Map 
    map.setMyLocationEnabled(true); 

    // Setting onclick event listener for the map 
    map.setOnMapClickListener(new OnMapClickListener() { 

     @Override 
     public void onMapClick(LatLng point) { 

      // Already two locations     
      if(markerPoints.size()>1){ 
       markerPoints.clear(); 
       map.clear(); 
      } 

      // Adding new item to the ArrayList 
      markerPoints.add(point); 

      // Creating MarkerOptions 
      MarkerOptions options = new MarkerOptions(); 

      // Setting the position of the marker 
      options.position(point); 

      /** 
      * For the start location, the color of marker is GREEN and 
      * for the end location, the color of marker is RED. 
      */ 
      if(markerPoints.size()==1){ 
       options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN)); 
      }else if(markerPoints.size()==2){ 
       options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)); 
      } 


      // Add new marker to the Google Map Android API V2 
      map.addMarker(options); 

      // Checks, whether start and end locations are captured 
      if(markerPoints.size() >= 2){ 
       LatLng origin = markerPoints.get(0); 
       LatLng dest = markerPoints.get(1); 

       // Getting URL to the Google Directions API 
       String url = getDirectionsUrl(origin, dest); 

       DownloadTask downloadTask = new DownloadTask(); 

       // Start downloading json data from Google Directions API 
       downloadTask.execute(url); 
      } 

     } 
    }); 

} 

private String getDirectionsUrl(LatLng origin,LatLng dest){ 

    // Origin of route 
    String str_origin = "origin="+origin.latitude+","+origin.longitude; 

    // Destination of route 
    String str_dest = "destination="+dest.latitude+","+dest.longitude; 


    // Sensor enabled 
    String sensor = "sensor=false"; 

    // Building the parameters to the web service 
    String parameters = str_origin+"&"+str_dest+"&"+sensor; 

    // Output format 
    String output = "json"; 

    // Building the url to the web service 
    String url = "https://maps.googleapis.com/maps/api/directions/"+output+"?"+parameters; 


    return url; 
} 

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



// Fetches data from url passed 
private class DownloadTask extends AsyncTask<String, Void, String>{ 

    // Downloading data in non-ui thread 
    @Override 
    protected String doInBackground(String... url) { 

     // For storing data from web service 
     String data = ""; 

     try{ 
      // Fetching the data from web service 
      data = downloadUrl(url[0]); 
     }catch(Exception e){ 
      Log.d("Background Task",e.toString()); 
     } 
     return data; 
    } 

    // Executes in UI thread, after the execution of 
    // doInBackground() 
    @Override 
    protected void onPostExecute(String result) { 
     super.onPostExecute(result); 

     ParserTask parserTask = new ParserTask(); 

     // Invokes the thread for parsing the JSON data 
     parserTask.execute(result); 

    } 
} 

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

    // Parsing the data in non-ui thread   
    @Override 
    protected List<List<HashMap<String, String>>> doInBackground(String... jsonData) { 

     JSONObject jObject; 
     List<List<HashMap<String, String>>> routes = null; 

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

      // Starts parsing data 
      routes = parser.parse(jObject); 
     }catch(Exception e){ 
      e.printStackTrace(); 
     } 
     return routes; 
    } 

    // Executes in UI thread, after the parsing process 
    @Override 
    protected void onPostExecute(List<List<HashMap<String, String>>> result) { 
     ArrayList<LatLng> points = null; 
     PolylineOptions lineOptions = null; 
     MarkerOptions markerOptions = new MarkerOptions(); 
     String distance = ""; 
     String duration = ""; 



     if(result.size()<1){ 
      Toast.makeText(getBaseContext(), "No Points", Toast.LENGTH_SHORT).show(); 
      return; 
     } 


     // Traversing through all the routes 
     for(int i=0;i<result.size();i++){ 
      points = new ArrayList<LatLng>(); 
      lineOptions = new PolylineOptions(); 

      // Fetching i-th route 
      List<HashMap<String, String>> path = result.get(i); 

      // Fetching all the points in i-th route 
      for(int j=0;j<path.size();j++){ 
       HashMap<String,String> point = path.get(j); 

       if(j==0){ // Get distance from the list 
        distance = (String)point.get("distance"); 
        continue; 
       }else if(j==1){ // Get duration from the list 
        duration = (String)point.get("duration"); 
        continue; 
       } 

       double lat = Double.parseDouble(point.get("lat")); 
       double lng = Double.parseDouble(point.get("lng")); 
       LatLng position = new LatLng(lat, lng); 

       points.add(position); 
      } 

      // Adding all the points in the route to LineOptions 
      lineOptions.addAll(points); 
      lineOptions.width(2); 
      lineOptions.color(Color.RED); 

     } 

     tvDistanceDuration.setText("Distance:"+distance + ", Duration:"+duration); 

     // Drawing polyline in the Google Map for the i-th route 
     map.addPolyline(lineOptions); 
    } 
} 


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

}

+0

可能的复制[mapFragment.getMap()返回null(http://stackoverflow.com/questions/17771545/android-mapfragment-getmap-returns-null)。 – jww 2014-09-18 17:03:50

回答

0

findFragmentById(R.id.map);后把下面这段代码:

new Handler().postDelayed(new Runnable() { 
    @Override 
    public void run() { 
     map = fm.getMap(); 
     if(map == null) new Handler().postDelayed(this, 500); 
     else { 
      // Do setup the map 
     } 
    } 
}, 500); 

这将尝试每隔500ms获取Map实例,直到它不为空。

注意:SupportMapFragment fm应该是活动的最终变量或成员变量。

0

电话设置为getMap()将是无效的,直到片段已经通过onCreateView生命周期阶段了,所以你不能把它在onCreate(),你需要调用它onCreateView()

这里的部分文档的相关部分以及链接。

public final GoogleMap getMap() 

获取与此片段包装的视图相关的底层GoogleMap。 返回GoogleMap。如果片段的视图尚未准备好,则为空。如果片段lifecyle还没有通过onCreateView(LayoutInflater,ViewGroup,Bundle),就会发生这种情况。如果Google Play服务不可用,也会发生这种情况。如果之后Google Play服务可用并且片段已经通过onCreateView(LayoutInflater,ViewGroup,Bundle),再次调用此方法将初始化并返回GoogleMap。的

http://developer.android.com/reference/com/google/android/gms/maps/MapFragment.html#getMap()

相关问题