Googlemap.moveCamera中的空指针异常

时间:2017-03-30 09:01:37

标签: android google-maps

我创建了一个Google Map应用程序来列出附近的酒店。我按照这个tutorial link

的完整教程进行了操作

现在我收到这样的错误

     E/AndroidRuntime: FATAL EXCEPTION: main
              Process: com.example.futuro.gplace, PID: 30974
              java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.futuro.gplace/com.example.futuro.gplace.MainActivity}: java.lang.NullPointerException
                  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2264)
                  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2313)
                  at android.app.ActivityThread.access$1100(ActivityThread.java:141)
                  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1238)
                  at android.os.Handler.dispatchMessage(Handler.java:102)
                  at android.os.Looper.loop(Looper.java:136)
                  at android.app.ActivityThread.main(ActivityThread.java:5336)
                  at java.lang.reflect.Method.invokeNative(Native Method)
                  at java.lang.reflect.Method.invoke(Method.java:515)
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:873)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:689)
                  at dalvik.system.NativeStart.main(Native Method)
               Caused by: java.lang.NullPointerException
                  at com.example.futuro.gplace.MainActivity.onLocationChanged(MainActivity.java:361)
                  at com.example.futuro.gplace.MainActivity.onCreate(MainActivity.java:123)
                  at android.app.Activity.performCreate(Activity.java:5302)
                  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1090)
                  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2228)
                  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2313) 
                  at android.app.ActivityThread.access$1100(ActivityThread.java:141) 
                  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1238) 
                  at android.os.Handler.dispatchMessage(Handler.java:102) 
                  at android.os.Looper.loop(Looper.java:136) 
                  at android.app.ActivityThread.main(ActivityThread.java:5336) 
                  at java.lang.reflect.Method.invokeNative(Native Method) 
                  at java.lang.reflect.Method.invoke(Method.java:515) 
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:873) 
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:689) 
                  at dalvik.system.NativeStart.main(Native Method) 

我的代码是

public class MainActivity extends FragmentActivity implements LocationListener, OnMapReadyCallback {

  GoogleMap mGoogleMap;
    Spinner mSprPlaceType;

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

    double mLatitude = 0;
    double mLongitude = 0;

    HashMap<String, String> mMarkerPlaceLink = new HashMap<String, String>();
    /**
     * ATTENTION: This was auto-generated to implement the App Indexing API.
     * See https://g.co/AppIndexing/AndroidStudio for more information.
     */
    private GoogleApiClient client;

    @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
            fragment.getMapAsync(this);
            if (ActivityCompat.checkSelfPermission(this,android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this,android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)                 // 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);

            mGoogleMap.setOnInfoWindowClickListener(new OnInfoWindowClickListener() {

                @Override
                public void onInfoWindowClick(Marker arg0) {
                    Intent intent = new Intent(getBaseContext(), PlaceDetailsActivity.class);
                    String reference = mMarkerPlaceLink.get(arg0.getId());
                    intent.putExtra("reference", reference);

                    // Starting the Place Details Activity
                    startActivity(intent);
                }
            });

            // 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("AIzaSyAjd_-MyhsY0-Bbdb_wrYv507oG7D__ZGg");

                    // 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());
                }
            });
        }
        // ATTENTION: This was auto-generated to implement the App Indexing API.
        // See https://g.co/AppIndexing/AndroidStudio for more information.
        client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();
    }

    /**
     * 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("Exceptionl", e.toString());
        } finally {
            iStream.close();
            urlConnection.disconnect();
        }
        return data;
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mGoogleMap = googleMap;

    }

    /**
     * ATTENTION: This was auto-generated to implement the App Indexing API.
     * See https://g.co/AppIndexing/AndroidStudio for more information.
     */
    public Action getIndexApiAction() {
        Thing object = new Thing.Builder()
                .setName("Main Page") // TODO: Define a title for the content shown.
                // TODO: Make sure this auto-generated URL is correct.
                .setUrl(Uri.parse("http://[ENTER-YOUR-URL-HERE]"))
                .build();
        return new Action.Builder(Action.TYPE_VIEW)
                .setObject(object)
                .setActionStatus(Action.STATUS_TYPE_COMPLETED)
                .build();
    }

    @Override
    public void onStart() {
        super.onStart();

        // ATTENTION: This was auto-generated to implement the App Indexing API.
        // See https://g.co/AppIndexing/AndroidStudio for more information.
        client.connect();
        AppIndex.AppIndexApi.start(client, getIndexApiAction());
    }

    @Override
    public void onStop() {
        super.onStop();

        // ATTENTION: This was auto-generated to implement the App Indexing API.
        // See https://g.co/AppIndexing/AndroidStudio for more information.
        AppIndex.AppIndexApi.end(client, getIndexApiAction());
        client.disconnect();
    }

    /**
     * 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
                Marker m = mGoogleMap.addMarker(markerOptions);

                // Linking Marker id and place reference
                mMarkerPlaceLink.put(m.getId(), hmPlace.get("reference"));
            }
        }
    }



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

        mGoogleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));  /// error is shown in this line
        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
    }

}

我是这个论坛和android的新手。

这是什么意思?我帮忙解决了所有错误。现在我可以打开地图,地图显示我当前的位置(不是用标记)。当我点击发现nothig发生时,这是我的运行窗口显示

    W/DynamiteModule: Local module descriptor class for com.google.android.gms.googlecertificates not found.
I/ActivityThread: com.example.futuro.gplace query other app provider, pkg:com.google.android.gms uid:10010, send to pg
I/DynamiteModule: Considering local module com.google.android.gms.googlecertificates:0 and remote module com.google.android.gms.googlecertificates:2
I/DynamiteModule: Selected remote version of com.google.android.gms.googlecertificates, version >= 2
D/dalvikvm: DexOpt: couldn't find static field Landroid/os/Build;.SUPPORTED_64_BIT_ABIS
W/dalvikvm: VFY: unable to resolve static field 29 (SUPPORTED_64_BIT_ABIS) in Landroid/os/Build;
D/dalvikvm: VFY: replacing opcode 0x62 at 0x0012
D/dalvikvm: DexOpt: couldn't find static field Landroid/os/Build;.SUPPORTED_32_BIT_ABIS
W/dalvikvm: VFY: unable to resolve static field 28 (SUPPORTED_32_BIT_ABIS) in Landroid/os/Build;
D/dalvikvm: VFY: replacing opcode 0x62 at 0x0021
D/dalvikvm: DexOpt: couldn't find static field Landroid/os/Build;.SUPPORTED_64_BIT_ABIS
W/dalvikvm: VFY: unable to resolve static field 29 (SUPPORTED_64_BIT_ABIS) in Landroid/os/Build;
D/dalvikvm: VFY: replacing opcode 0x62 at 0x0008
D/dalvikvm: DexOpt: couldn't find static field Landroid/os/Build;.SUPPORTED_64_BIT_ABIS
I/dalvikvm: DexOpt: unable to optimize static field ref 0x001d at 0x17 in Lv;.a
D/dalvikvm: DexOpt: couldn't find static field Landroid/os/Build;.SUPPORTED_32_BIT_ABIS
I/dalvikvm: DexOpt: unable to optimize static field ref 0x001c at 0x26 in Lv;.a
D/dalvikvm: DexOpt: couldn't find static field Landroid/os/Build;.SUPPORTED_64_BIT_ABIS
I/dalvikvm: DexOpt: unable to optimize static field ref 0x001d at 0x0d in Lv;.b
I/dalvikvm: Could not find method b.createCredentialProtectedStorageContext, referenced from method c.createCredentialProtectedStorageContext
W/dalvikvm: VFY: unable to resolve virtual method 181: Lb;.createCredentialProtectedStorageContext ()Landroid/content/Context;
D/dalvikvm: VFY: replacing opcode 0x6f at 0x0002
I/dalvikvm: Could not find method b.createDeviceProtectedStorageContext, referenced from method c.createDeviceProtectedStorageContext
W/dalvikvm: VFY: unable to resolve virtual method 182: Lb;.createDeviceProtectedStorageContext ()Landroid/content/Context;
D/dalvikvm: VFY: replacing opcode 0x6f at 0x0002
I/ActivityThread: com.example.futuro.gplace query other app provider, pkg:com.google.android.gsf uid:10010, send to pg
V/AudioManager: playSoundEffect   effectType: 0
V/AudioManager: querySoundEffectsEnabled...
V/AudioManager: playSoundEffect   effectType: 0
V/AudioManager: querySoundEffectsEnabled...
V/AudioManager: playSoundEffect   effectType: 0
V/AudioManager: querySoundEffectsEnabled...
V/AudioManager: playSoundEffect   effectType: 0
V/AudioManager: querySoundEffectsEnabled...
V/AudioManager: playSoundEffect   effectType: 0
V/AudioManager: querySoundEffectsEnabled...
V/AudioManager: playSoundEffect   effectType: 0
V/AudioManager: querySoundEffectsEnabled...
V/AudioManager: playSoundEffect   effectType: 0
V/AudioManager: querySoundEffectsEnabled...
D/dalvikvm: GC_FOR_ALLOC freed 7235K, 59% free 8106K/19316K, paused 77ms, total 78ms

我的Gradle文件

    apply plugin: 'com.android.application'

    android {
     compileSdkVersion 25
         buildToolsVersion "25.0.2"
               defaultConfig {
                  applicationId "com.example.futuro.gplace"
               minSdkVersion 15
                targetSdkVersion 25
                 versionCode 1
                  versionName "1.0"
                    multiDexEnabled true
                  testInstrumentationRunner                                                "                        "android.support.test.runner.AndroidJUnitRunner"
                                }


                  buildTypes {
                         release {
                           minifyEnabled false
                                                                                                                                                         proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

               dependencies {
                     compile fileTree(include: ['*.jar'], dir: 'libs')
                            androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
    exclude group: 'com.android.support', module: 'support-annotations'
})
              compile 'com.android.support:appcompat-v7:25.2.0'
                  testCompile 'junit:junit:4.12'

                compile 'com.google.android.gms:play-services-maps:10.2.1'
             compile 'com.google.android.gms:play-services-location:10.2.1'
          compile 'com.google.android.gms:play-services-places:10.2.1'
          compile 'com.google.firebase:firebase-appindexing:10.2.0'

           //  compile 'com.google.android.gms:play-services-appindexing:10.2.1'

           compile 'com.android.support:multidex:1.0.1'
                 }
             android {
                   aaptOptions.cruncherEnabled = false
                   aaptOptions.useNewCruncher = false

                 }

每当我点击查找按钮 就像这样

   Manager: playSoundEffect   effectType: 0
   V/AudioManager: querySoundEffectsEnabled...

link to show my api enabled.

是否存在任何问题

1 个答案:

答案 0 :(得分:0)

Google地图已在该方法中初始化 public void onMapReady(GoogleMap googleMap)

但是onLocationChanged(位置位置)是来自LocationListener的回调方法,可能在地图准备好并初始化之前调用它。

所以我想,在移动相机之前进行空检查将解决问题

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

        if(mGoogleMap != null){
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));  /// error is shown in this line
        mGoogleMap.animateCamera(CameraUpdateFactory.zoomTo(12));

    }