Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/372.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Android、谷歌地图API、JSON问题。获取空指针异常_Java_Android_Json_Google Maps - Fatal编程技术网

Java Android、谷歌地图API、JSON问题。获取空指针异常

Java Android、谷歌地图API、JSON问题。获取空指针异常,java,android,json,google-maps,Java,Android,Json,Google Maps,我正在开发一个小型的人事应用程序来帮助我学习Android开发和Java 让我先让大家知道谷歌地图部分正在应用程序中工作。当应用程序启动并获取手机的正确当前位置时,它正在加载 此外,我的JSON功能也能正常工作。数据是使用他们的API从www.wunderground.com中提取出来的,我的代码获取了我想要的内容,并创建了一个Arraylist,然后很好地填充它,并在应用程序中显示它 问题是,我正在尝试获取两段JSON数据,并创建一个google map Marker对象,并将其显示在地图上

我正在开发一个小型的人事应用程序来帮助我学习Android开发和Java

让我先让大家知道谷歌地图部分正在应用程序中工作。当应用程序启动并获取手机的正确当前位置时,它正在加载

此外,我的JSON功能也能正常工作。数据是使用他们的API从www.wunderground.com中提取出来的,我的代码获取了我想要的内容,并创建了一个Arraylist,然后很好地填充它,并在应用程序中显示它

问题是,我正在尝试获取两段JSON数据,并创建一个google map Marker对象,并将其显示在地图上

下面是我的代码:

此方法使用从JsonData.java获取的JSON数据创建Cyclone对象,我将在下面展示

Cyclone.java

public class Cyclone {

// Category of the cyclone (e.g. -2, -1, 0, 1, 2, 3, 4, or 5)
private int category;

// Latitude & Longitude of Cyclone
private float latitude, longitude;

// Cyclone name
private String name;

// Cyclone heading (N, S, E, or W)
private String heading;

// Wind speed in Cyclone
private String windSpeedKnots;

// Url to website with Cyclone data
private String url;

/**
* CONSTRUCTOR
* Create a new Cyclone object.
*
* @param constCategory is the category of the cyclone (e.g. -2, -1, 0, 1, 2, 3, 4, or 5)
* @param constLatitude is the Latitude of the cyclone
* @param constLongitude is the Longitude of the cyclone
* @param constName is the name of the Cyclone
* @param constHeading is the direction the cyclone is moving
* @param constWindSpeedKnots is the speed of the wind the Cyclone is producing
* @param constUrl is the url of the website that is providing the data
*/
public Cyclone(int constCategory, float constLatitude, float constLongitude,String constName,
               String constHeading, String constWindSpeedKnots, String constUrl) {

    category = constCategory;
    latitude = constLatitude;
    longitude = constLongitude;
    name = constName;
    heading = constHeading;
    windSpeedKnots = constWindSpeedKnots;
    url = constUrl;
}

/**
 * Setting public getters for the private variables above for use of other classes
 */
// Get the storm category
public int getCategory() {
    return category;
}

// Get the cyclones Latitude
public float getLatitude() {
    return latitude;
}

//Get the cyclones Longitude
public float getLongitude() {
    return longitude;
}

// Get the cyclones name
public String getName() {
    return name;
}

// Get the cyclones heading
public String getHeading() {
    return heading;
}

// Get the cyclones wind speed
public String getWindSpeedKnots() {
    return windSpeedKnots;
}

// Get the Url
public String getUrl() {
    return url;
}
/**
 * Return a list of {@link Cyclone} objects that has been built up from
 * parsing a JSON response.
 */
public static ArrayList<Cyclone> extractFeatureFromJson(String cycloneJSON) {

    // Create an empty ArrayList to start adding Cyclones to
    ArrayList<Cyclone> cyclones = new ArrayList<>();

    // Try to parse the cycloneJSON response string. If there's a problem with the way the JSON
    // is formatted, a JSONException exception object will be thrown.
    // Catch the exception , and print the error message to the logs.

    try {

        JSONObject rootJsonObject = new JSONObject(cycloneJSON);

        // Create JSONArray associated with the key called "currenthurricane", which represents
        // a list of cyclones from JSON response.
        JSONArray currentHurricaneArray = rootJsonObject.getJSONArray("currenthurricane");

        /**
         * Loop through each section in the currentHurricaneArray array & create an
         * {@link Cyclone} object for each one
         *
         */
        for (int i = 0; i < currentHurricaneArray.length(); i++) {
            //Get cyclone JSONObject at position i in the array
            JSONObject cycloneProperties = currentHurricaneArray.getJSONObject(i);

            // Extract "stormInfo" object
            JSONObject stormInfo = cycloneProperties.optJSONObject("stormInfo");
            //Extract “stormName_Nice” & "requesturl" for Cyclone's name and url
            String name = stormInfo.optString("stormName_Nice");
            String url = stormInfo.optString("wuiurl");

            // Extract "Current" object
            JSONObject current = cycloneProperties.optJSONObject("Current");
            // Extract "SaffirSimpsonCategory" key
            int category = current.optInt("SaffirSimpsonCategory");

            //Extract "Lat" & "Lon" keys to get cyclone position
            float latitude = (float) current.optDouble("lat");
            float longitude = (float) current.optDouble("lon");

            //Extract "WindSpeed" object
            JSONObject windSpeed = current.optJSONObject("WindSpeed");
            //Extract wind speed in "Knots" Key
            int Kts = windSpeed.optInt("Kts");
            String knots = Kts + " Knots";

            //Extract "Movement" object
            JSONObject movement = current.optJSONObject("Movement");
            //Extract movement direction in "Text" key
            String direction = movement.optString("Text");

            Cyclone cyclone = new Cyclone(category, latitude, longitude, name, direction, knots, url);
            //Add new cyclone to list
            cyclones.add(cyclone);
        }
public class MainActivity extends AppCompatActivity implements
    LoaderManager.LoaderCallbacks<List<Cyclone>>,
    OnMapReadyCallback,
    GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener,
    LocationListener {

....

//Creating a Cyclone object, calling it from Cyclone.java
    Cyclone trackedCyclone = null;

    //getting the three bits of info I need/want (Name, lat, lon)
    String name = trackedCyclone.getName();
    float lat = trackedCyclone.getLatitude();
    float lon = trackedCyclone.getLongitude();

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

// Obtain the SupportMapFragment and get notified when the map is ready
    //Calling up the map fragment from cyclone_list.xml
    MapFragment mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.google_map);
    mapFragment.getMapAsync(this);

....

@Override
public void onMapReady(GoogleMap mapLocalInstance) {
    //Setting mapReady to true
    mapReady = true;

    //displaying cyclone map marker on the map
    LatLng cycloneMarker = new LatLng(lat, lon);
    googleMap.addMarker(new MarkerOptions().position(cycloneMarker).title(name));

    //Loading local instance map from Callback
    googleMap = mapLocalInstance;
    googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);

    //checks for permission using the Support library before enabling the My Location layer
    //Initialize Google Play Services
    if (android.os.Build.VERSION.SDK_INT >= M) {
        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_FINE_LOCATION)
                == PackageManager.PERMISSION_GRANTED) {
            buildGoogleApiClient();
            googleMap.setMyLocationEnabled(true);
        }
    } else {
        buildGoogleApiClient();
        googleMap.setMyLocationEnabled(true);
    }
}
}

此类从www.wunderground.com获取JSON数据。我从底部剪下了一堆代码。如果不返回任何内容,它主要只是处理异常。 JsonData.java

public class Cyclone {

// Category of the cyclone (e.g. -2, -1, 0, 1, 2, 3, 4, or 5)
private int category;

// Latitude & Longitude of Cyclone
private float latitude, longitude;

// Cyclone name
private String name;

// Cyclone heading (N, S, E, or W)
private String heading;

// Wind speed in Cyclone
private String windSpeedKnots;

// Url to website with Cyclone data
private String url;

/**
* CONSTRUCTOR
* Create a new Cyclone object.
*
* @param constCategory is the category of the cyclone (e.g. -2, -1, 0, 1, 2, 3, 4, or 5)
* @param constLatitude is the Latitude of the cyclone
* @param constLongitude is the Longitude of the cyclone
* @param constName is the name of the Cyclone
* @param constHeading is the direction the cyclone is moving
* @param constWindSpeedKnots is the speed of the wind the Cyclone is producing
* @param constUrl is the url of the website that is providing the data
*/
public Cyclone(int constCategory, float constLatitude, float constLongitude,String constName,
               String constHeading, String constWindSpeedKnots, String constUrl) {

    category = constCategory;
    latitude = constLatitude;
    longitude = constLongitude;
    name = constName;
    heading = constHeading;
    windSpeedKnots = constWindSpeedKnots;
    url = constUrl;
}

/**
 * Setting public getters for the private variables above for use of other classes
 */
// Get the storm category
public int getCategory() {
    return category;
}

// Get the cyclones Latitude
public float getLatitude() {
    return latitude;
}

//Get the cyclones Longitude
public float getLongitude() {
    return longitude;
}

// Get the cyclones name
public String getName() {
    return name;
}

// Get the cyclones heading
public String getHeading() {
    return heading;
}

// Get the cyclones wind speed
public String getWindSpeedKnots() {
    return windSpeedKnots;
}

// Get the Url
public String getUrl() {
    return url;
}
/**
 * Return a list of {@link Cyclone} objects that has been built up from
 * parsing a JSON response.
 */
public static ArrayList<Cyclone> extractFeatureFromJson(String cycloneJSON) {

    // Create an empty ArrayList to start adding Cyclones to
    ArrayList<Cyclone> cyclones = new ArrayList<>();

    // Try to parse the cycloneJSON response string. If there's a problem with the way the JSON
    // is formatted, a JSONException exception object will be thrown.
    // Catch the exception , and print the error message to the logs.

    try {

        JSONObject rootJsonObject = new JSONObject(cycloneJSON);

        // Create JSONArray associated with the key called "currenthurricane", which represents
        // a list of cyclones from JSON response.
        JSONArray currentHurricaneArray = rootJsonObject.getJSONArray("currenthurricane");

        /**
         * Loop through each section in the currentHurricaneArray array & create an
         * {@link Cyclone} object for each one
         *
         */
        for (int i = 0; i < currentHurricaneArray.length(); i++) {
            //Get cyclone JSONObject at position i in the array
            JSONObject cycloneProperties = currentHurricaneArray.getJSONObject(i);

            // Extract "stormInfo" object
            JSONObject stormInfo = cycloneProperties.optJSONObject("stormInfo");
            //Extract “stormName_Nice” & "requesturl" for Cyclone's name and url
            String name = stormInfo.optString("stormName_Nice");
            String url = stormInfo.optString("wuiurl");

            // Extract "Current" object
            JSONObject current = cycloneProperties.optJSONObject("Current");
            // Extract "SaffirSimpsonCategory" key
            int category = current.optInt("SaffirSimpsonCategory");

            //Extract "Lat" & "Lon" keys to get cyclone position
            float latitude = (float) current.optDouble("lat");
            float longitude = (float) current.optDouble("lon");

            //Extract "WindSpeed" object
            JSONObject windSpeed = current.optJSONObject("WindSpeed");
            //Extract wind speed in "Knots" Key
            int Kts = windSpeed.optInt("Kts");
            String knots = Kts + " Knots";

            //Extract "Movement" object
            JSONObject movement = current.optJSONObject("Movement");
            //Extract movement direction in "Text" key
            String direction = movement.optString("Text");

            Cyclone cyclone = new Cyclone(category, latitude, longitude, name, direction, knots, url);
            //Add new cyclone to list
            cyclones.add(cyclone);
        }
public class MainActivity extends AppCompatActivity implements
    LoaderManager.LoaderCallbacks<List<Cyclone>>,
    OnMapReadyCallback,
    GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener,
    LocationListener {

....

//Creating a Cyclone object, calling it from Cyclone.java
    Cyclone trackedCyclone = null;

    //getting the three bits of info I need/want (Name, lat, lon)
    String name = trackedCyclone.getName();
    float lat = trackedCyclone.getLatitude();
    float lon = trackedCyclone.getLongitude();

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

// Obtain the SupportMapFragment and get notified when the map is ready
    //Calling up the map fragment from cyclone_list.xml
    MapFragment mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.google_map);
    mapFragment.getMapAsync(this);

....

@Override
public void onMapReady(GoogleMap mapLocalInstance) {
    //Setting mapReady to true
    mapReady = true;

    //displaying cyclone map marker on the map
    LatLng cycloneMarker = new LatLng(lat, lon);
    googleMap.addMarker(new MarkerOptions().position(cycloneMarker).title(name));

    //Loading local instance map from Callback
    googleMap = mapLocalInstance;
    googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);

    //checks for permission using the Support library before enabling the My Location layer
    //Initialize Google Play Services
    if (android.os.Build.VERSION.SDK_INT >= M) {
        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_FINE_LOCATION)
                == PackageManager.PERMISSION_GRANTED) {
            buildGoogleApiClient();
            googleMap.setMyLocationEnabled(true);
        }
    } else {
        buildGoogleApiClient();
        googleMap.setMyLocationEnabled(true);
    }
}
/**
*返回从中建立的{@link Cyclone}对象列表
*解析JSON响应。
*/
公共静态ArrayList extractFeatureFromJson(字符串cycloneJSON){
//创建一个空的ArrayList以开始向其添加旋风分离器
ArrayList旋风分离器=新ArrayList();
//尝试解析cycloneJSON响应字符串。如果JSON响应的方式有问题
//如果已格式化,将抛出JSONException异常对象。
//捕获异常,并将错误消息打印到日志中。
试一试{
JSONObject rootJsonObject=新的JSONObject(cycloneJSON);
//创建与名为“currenthurricane”的键关联的JSONArray,该键表示
//JSON响应中的气旋列表。
JSONArray currentHurricaneArray=rootJsonObject.getJSONArray(“currenthurricane”);
/**
*循环浏览currentHurricaneArray中的每个部分并创建一个
*{@link Cyclone}对象
*
*/
对于(int i=0;i
我将在这里展示相关的部分

MainActivity.java

public class Cyclone {

// Category of the cyclone (e.g. -2, -1, 0, 1, 2, 3, 4, or 5)
private int category;

// Latitude & Longitude of Cyclone
private float latitude, longitude;

// Cyclone name
private String name;

// Cyclone heading (N, S, E, or W)
private String heading;

// Wind speed in Cyclone
private String windSpeedKnots;

// Url to website with Cyclone data
private String url;

/**
* CONSTRUCTOR
* Create a new Cyclone object.
*
* @param constCategory is the category of the cyclone (e.g. -2, -1, 0, 1, 2, 3, 4, or 5)
* @param constLatitude is the Latitude of the cyclone
* @param constLongitude is the Longitude of the cyclone
* @param constName is the name of the Cyclone
* @param constHeading is the direction the cyclone is moving
* @param constWindSpeedKnots is the speed of the wind the Cyclone is producing
* @param constUrl is the url of the website that is providing the data
*/
public Cyclone(int constCategory, float constLatitude, float constLongitude,String constName,
               String constHeading, String constWindSpeedKnots, String constUrl) {

    category = constCategory;
    latitude = constLatitude;
    longitude = constLongitude;
    name = constName;
    heading = constHeading;
    windSpeedKnots = constWindSpeedKnots;
    url = constUrl;
}

/**
 * Setting public getters for the private variables above for use of other classes
 */
// Get the storm category
public int getCategory() {
    return category;
}

// Get the cyclones Latitude
public float getLatitude() {
    return latitude;
}

//Get the cyclones Longitude
public float getLongitude() {
    return longitude;
}

// Get the cyclones name
public String getName() {
    return name;
}

// Get the cyclones heading
public String getHeading() {
    return heading;
}

// Get the cyclones wind speed
public String getWindSpeedKnots() {
    return windSpeedKnots;
}

// Get the Url
public String getUrl() {
    return url;
}
/**
 * Return a list of {@link Cyclone} objects that has been built up from
 * parsing a JSON response.
 */
public static ArrayList<Cyclone> extractFeatureFromJson(String cycloneJSON) {

    // Create an empty ArrayList to start adding Cyclones to
    ArrayList<Cyclone> cyclones = new ArrayList<>();

    // Try to parse the cycloneJSON response string. If there's a problem with the way the JSON
    // is formatted, a JSONException exception object will be thrown.
    // Catch the exception , and print the error message to the logs.

    try {

        JSONObject rootJsonObject = new JSONObject(cycloneJSON);

        // Create JSONArray associated with the key called "currenthurricane", which represents
        // a list of cyclones from JSON response.
        JSONArray currentHurricaneArray = rootJsonObject.getJSONArray("currenthurricane");

        /**
         * Loop through each section in the currentHurricaneArray array & create an
         * {@link Cyclone} object for each one
         *
         */
        for (int i = 0; i < currentHurricaneArray.length(); i++) {
            //Get cyclone JSONObject at position i in the array
            JSONObject cycloneProperties = currentHurricaneArray.getJSONObject(i);

            // Extract "stormInfo" object
            JSONObject stormInfo = cycloneProperties.optJSONObject("stormInfo");
            //Extract “stormName_Nice” & "requesturl" for Cyclone's name and url
            String name = stormInfo.optString("stormName_Nice");
            String url = stormInfo.optString("wuiurl");

            // Extract "Current" object
            JSONObject current = cycloneProperties.optJSONObject("Current");
            // Extract "SaffirSimpsonCategory" key
            int category = current.optInt("SaffirSimpsonCategory");

            //Extract "Lat" & "Lon" keys to get cyclone position
            float latitude = (float) current.optDouble("lat");
            float longitude = (float) current.optDouble("lon");

            //Extract "WindSpeed" object
            JSONObject windSpeed = current.optJSONObject("WindSpeed");
            //Extract wind speed in "Knots" Key
            int Kts = windSpeed.optInt("Kts");
            String knots = Kts + " Knots";

            //Extract "Movement" object
            JSONObject movement = current.optJSONObject("Movement");
            //Extract movement direction in "Text" key
            String direction = movement.optString("Text");

            Cyclone cyclone = new Cyclone(category, latitude, longitude, name, direction, knots, url);
            //Add new cyclone to list
            cyclones.add(cyclone);
        }
public class MainActivity extends AppCompatActivity implements
    LoaderManager.LoaderCallbacks<List<Cyclone>>,
    OnMapReadyCallback,
    GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener,
    LocationListener {

....

//Creating a Cyclone object, calling it from Cyclone.java
    Cyclone trackedCyclone = null;

    //getting the three bits of info I need/want (Name, lat, lon)
    String name = trackedCyclone.getName();
    float lat = trackedCyclone.getLatitude();
    float lon = trackedCyclone.getLongitude();

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

// Obtain the SupportMapFragment and get notified when the map is ready
    //Calling up the map fragment from cyclone_list.xml
    MapFragment mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.google_map);
    mapFragment.getMapAsync(this);

....

@Override
public void onMapReady(GoogleMap mapLocalInstance) {
    //Setting mapReady to true
    mapReady = true;

    //displaying cyclone map marker on the map
    LatLng cycloneMarker = new LatLng(lat, lon);
    googleMap.addMarker(new MarkerOptions().position(cycloneMarker).title(name));

    //Loading local instance map from Callback
    googleMap = mapLocalInstance;
    googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);

    //checks for permission using the Support library before enabling the My Location layer
    //Initialize Google Play Services
    if (android.os.Build.VERSION.SDK_INT >= M) {
        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_FINE_LOCATION)
                == PackageManager.PERMISSION_GRANTED) {
            buildGoogleApiClient();
            googleMap.setMyLocationEnabled(true);
        }
    } else {
        buildGoogleApiClient();
        googleMap.setMyLocationEnabled(true);
    }
}
public类MainActivity扩展了AppCompatActivity实现
LoaderManager.LoaderCallbacks,
四月一日,
GoogleAppClient.ConnectionCallbacks,
GoogleAppClient.OnConnectionFailedListener,
位置侦听器{
....
//创建Cyclone对象,从Cyclone.java调用它
Cyclone trackedCyclone=null;
//获取我需要/想要的三位信息(姓名、纬度、经度)
字符串名称=trackedCyclone.getName();
float lat=trackedCyclone.getLatitude();
float lon=trackedconclone.getLongitude();
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.cyclone_列表);
....
//获取SupportMapFragment,并在地图准备就绪时获得通知
//从cyclone_list.xml调用映射片段
MapFragment MapFragment=(MapFragment)getFragmentManager();
getMapAsync(这个);
....
@凌驾
Mapready上的公共无效(谷歌地图本地化){
//将mapReady设置为true
mapredy=true;
//在地图上显示气旋地图标记
LatLng cycloneMarker=新的LatLng(lat,lon);
addMarker(新的MarkerOptions().position(cycloneMarker.title(name));
//从回调加载本地实例映射
googleMap=MapLocationInstance;
googleMap.setMapType(googleMap.MAP类型卫星);
//在启用“我的位置”层之前,使用支持库检查权限
//初始化Google Play服务
if(android.os.Build.VERSION.SDK_INT>=M){
如果(ContextCompat.checkSelfPermission)(此,
清单.权限.访问(位置)
==PackageManager.权限(已授予){
buildGoogleAppClient();
googleMap.setMyLocationEnabled(true);
}
}否则{
buildGoogleAppClient();
googleMap.setMyLocationEnabled(true);
}
}
当应用程序启动时,会出现以下情况:

04-17 16:11:29.546 7028-7028/com.palarran.cycloops E/AndroidRuntime:致命异常:main