我创建了一个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...
是否存在任何问题
答案 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));
}