我正在编写一个Android应用程序,它将多个用户的位置存储到远程数据库,然后任何用户都可以获取这些位置并将它们放在谷歌地图上。
我可以成功存储位置。我可以成功地将所有位置作为数组。我无法在地图上绘制它们:应用程序总是崩溃。
这是我的代码,添加标记位于“Do In Background”部分的“attemptLoad”类中:
package com.paul.locations;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.paul.locations.JSONParser;
import com.paul.locations.R;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class Location extends Activity implements OnClickListener {
private GoogleMap googlemap;
private String lat="", lon="", current = "", lati, loni;
private Button bLoad, bStore;
private Float la, lo;
// Progress Dialog
private ProgressDialog pDialog;
// JSON parser class
JSONParser jsonParser = new JSONParser();
//php add a comment script
//localhost :
//testing on your device
//put your local ip instead, on windows, run CMD > ipconfig
//or in mac's terminal type ifconfig and look for the ip under en0 or en1
private static final String LOAD_INFO_URL = "http://192.168.1.14/locations/load_infos.php";
private static final String UPDATE_INFO_URL = "http://192.168.1.14/locations/update_info.php";
//testing on Emulator:
//private static final String POST_COMMENT_URL = "http://10.0.2.2:1234/webservice/addcomment.php";
//testing from a real server:
//private static final String POST_COMMENT_URL = "http://www.mybringback.com/webservice/addcomment.php";
//ids
private static final String TAG_SUCCESS = "success";
private static final String TAG_MESSAGE = "message";
private static final String TAG_LON = "lon";
private static final String TAG_LAT = "lat";
private static final String TAG_USERNAME = "username";
private static final String TAG_POSTS = "posts";
private static final String TAG_TIME = "time";
private static final String TAG_ID = "id";
// products JSONArray
JSONArray products = null;
ArrayList<HashMap<String, String>> productsList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.map);
setUpMap();
// Hashmap for ListView
productsList = new ArrayList<HashMap<String, String>>();
bLoad = (Button)findViewById(R.id.bLoad);
bLoad.setOnClickListener(this);
bStore = (Button)findViewById(R.id.bStore);
bStore.setOnClickListener(this);
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.bLoad:
new AttemptLoad().execute();
break;
case R.id.bStore:
LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
android.location.Location location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
lon = Double.toString(location.getLongitude());
lat = Double.toString(location.getLatitude());
System.out.println(lon + ", " + lat);
Calendar c = Calendar.getInstance();
SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");
current = df.format(c.getTime());
System.out.println(current);
new AttemptStore().execute();
break;
default:
break;
}
}
class AttemptLoad extends AsyncTask<String, String, String> {
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(Location.this);
pDialog.setMessage("Attempting to load locations...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
@Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
// Instantiate the arraylist to contain all the JSON data.
// we are going to use a bunch of key-value pairs, referring
// to the json element name, and the content, for example,
// message it the tag, and "I'm awesome" as the content.
// Building Parameters
List<NameValuePair> params1 = new ArrayList<NameValuePair>();
// getting JSON string from URL
JSONObject json = jsonParser.makeHttpRequest(LOAD_INFO_URL, "GET", params1);
// Check your log cat for JSON reponse
Log.d("All Products: ", json.toString());
// when parsing JSON stuff, we should probably
// try to catch any exceptions:
try {
// Checking for SUCCESS TAG
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// products found
// Getting Array of Products
products = json.getJSONArray(TAG_POSTS);
// looping through All Products
for (int i = 0; i < products.length(); i++) {
JSONObject c = products.getJSONObject(i);
// Storing each json item in variable
loni = c.getString(TAG_LON);
String username = c.getString(TAG_USERNAME);
lati = c.getString(TAG_LAT);
String time = c.getString(TAG_TIME);
String id = c.getString(TAG_ID);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(TAG_LON, loni);
map.put(TAG_LAT, lati);
map.put(TAG_USERNAME, username);
map.put(TAG_TIME, time);
map.put(TAG_ID, id);
// adding HashList to ArrayList
productsList.add(map);
la = Float.valueOf(lati);
lo = Float.valueOf(loni);
System.out.println(la);
System.out.println(lo);
//this is where i try to put all the markers on the map and where the app crashes
googlemap.addMarker(new MarkerOptions()
.position(new LatLng(la, lo))
.title("Hello world"));
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String file_url) {
// dismiss the dialog once product deleted
pDialog.dismiss();
if (file_url != null){
Toast.makeText(Location.this, file_url, Toast.LENGTH_LONG).show();
}
}
}
class AttemptStore extends AsyncTask<String, String, String> {
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(Location.this);
pDialog.setMessage("Attempting to store your location...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
@Override
protected String doInBackground(String... args) {
// TODO Auto-generated method stub
String success;
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(Location.this);
String post_username = sp.getString("username", "anon");
try {
// Building Parameters
List<NameValuePair> params1 = new ArrayList<NameValuePair>();
params1.add(new BasicNameValuePair("username", post_username));
params1.add(new BasicNameValuePair("lat", lat));
params1.add(new BasicNameValuePair("lon", lon));
params1.add(new BasicNameValuePair("time", current));
Log.d("request!", "starting");
//Posting user data to script
JSONObject json = jsonParser.makeHttpRequest(
UPDATE_INFO_URL, "POST", params1);
// full json response
Log.d("Store location attempt", json.toString());
// json success element
success = json.getString(TAG_SUCCESS);
if(success.equals("SUCCESS")) {
Log.d("Location Stored!", json.toString());
finish();
return json.getString(TAG_MESSAGE);
}else{
Log.d("Storing Location Failure!", json.getString(TAG_MESSAGE));
return json.getString(TAG_MESSAGE);
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String file_url) {
// dismiss the dialog once product deleted
pDialog.dismiss();
if (file_url != null){
Toast.makeText(Location.this, file_url, Toast.LENGTH_LONG).show();
}
}
}
private void setUpMap() {
if(googlemap == null){
googlemap = ((MapFragment)getFragmentManager().findFragmentById(R.id.map)).getMap();
if(googlemap != null){
//code to initialize the map
googlemap.setMyLocationEnabled(true);
}
}
}
}
我不确定会发生什么事情;任何帮助将不胜感激!这是我得到的logcat:
I/System.out(19285): -117.21224441, 32.75089894
I/System.out(19285): 13:18:33
D/request!(19285): starting
I/Adreno200-EGLSUB(19285): <ConfigWindowMatch:2087>: Format RGBA_8888.
D/Store location attempt(19285): {"message":"Post Successfully Added!","success":1}
D/Storing Location Failure!(19285): Post Successfully Added!
I/Adreno200-EGLSUB(19285): <ConfigWindowMatch:2087>: Format RGBA_8888.
D/All Products:(19285): {"posts":[{"id":"1","time":"13:18:33","lon":"-117.21224441","username":"paul","lat":"32.75089894"},{"id":"2","time":"01:00:30","lon":"13","lat":"13.01"},{"id":"3","time":"12:00:59","lon":"12.51","username":"ed","lat":"12.52"},{"id":"4","time":"14:00:00","lon":"20","username":"eric","lat":"20"},{03:03","lon":"17.01","username":"sumner","lat":"16.01"}],"success":1}
I/System.out(19285): 32.7509
I/System.out(19285): -117.21224
W/dalvikvm(19285): threadid=28: thread exiting with uncaught exception (group=0x41077438)
E/AndroidRuntime(19285): FATAL EXCEPTION: AsyncTask #3
E/AndroidRuntime(19285): java.lang.RuntimeException: An error occured while executing doInBackground()
E/AndroidRuntime(19285): at android.os.AsyncTask$3.done(AsyncTask.java:299)
E/AndroidRuntime(19285): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
E/AndroidRuntime(19285): at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
E/AndroidRuntime(19285): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
E/AndroidRuntime(19285): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
E/AndroidRuntime(19285): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
E/AndroidRuntime(19285): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
E/AndroidRuntime(19285): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
E/AndroidRuntime(19285): at java.lang.Thread.run(Thread.java:856)
E/AndroidRuntime(19285): Caused by: java.lang.IllegalStateException: Not on the main thread
E/AndroidRuntime(19285): at maps.as.i.b(Unknown Source)
E/AndroidRuntime(19285): at maps.am.g.b(Unknown Source)
E/AndroidRuntime(19285): at maps.ah.an.a(Unknown Source)
E/AndroidRuntime(19285): at bgc.onTransact(SourceFile:167)
E/AndroidRuntime(19285): at android.os.Binder.transact(Binder.java:326)
E/AndroidRuntime(19285): at com.google.android.gms.maps.internal.IGoogleMapDelegate$a$a.addMarker(Unknown Source)
E/AndroidRuntime(19285): at com.google.android.gms.maps.GoogleMap.addMarker(Unknown Source)
E/AndroidRuntime(19285): at com.paul.locations.Location$AttemptLoad.doInBackground(Location.java:194)
E/AndroidRuntime(19285): at com.paul.locations.Location$AttemptLoad.doInBackground(Location.java:1)
E/AndroidRuntime(19285): at android.os.AsyncTask$2.call(AsyncTask.java:287)
E/AndroidRuntime(19285): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
E/AndroidRuntime(19285): ... 5 more
I/Choreographer(19285): Skipped 474 frames! The application may be doing too much work on its main thread.
W/SurfaceView(19285): CHECK surface infomation creating=false formatChanged=false sizeChanged=false visible=false visibleChanged=true surfaceChanged=true e redrawNeeded=false left=false top=false
E/WindowManager(19285): Activity com.paul.locations.Location has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@4243bb10 that was e
E/WindowManager(19285): android.view.WindowLeaked: Activity com.paul.locations.Location has leaked window com.android.internal.policy.impl.w@4243bb10 that was originally added here
E/WindowManager(19285): at android.view.ViewRootImpl.<init>(ViewRootImpl.java:408)
E/WindowManager(19285): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:311)
E/WindowManager(19285): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:224)
E/WindowManager(19285): at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:149)
E/WindowManager(19285): at android.view.Window$LocalWindowManager.addView(Window.java:552)
E/WindowManager(19285): at android.app.Dialog.show(Dialog.java:277)
E/WindowManager(19285): at com.paul.locations.Location$AttemptLoad.onPreExecute(Location.java:131)
E/WindowManager(19285): at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:586)
E/WindowManager(19285): at android.os.AsyncTask.execute(AsyncTask.java:534)
E/WindowManager(19285): at com.paul.locations.Location.onClick(Location.java:102)
E/WindowManager(19285): at android.view.View.performClick(View.java:4203)
E/WindowManager(19285): at android.view.View$PerformClick.run(View.java:17189)
E/WindowManager(19285): at android.os.Handler.handleCallback(Handler.java:615)
E/WindowManager(19285): at android.os.Handler.dispatchMessage(Handler.java:92)
E/WindowManager(19285): at android.os.Looper.loop(Looper.java:137)
E/WindowManager(19285): at android.app.ActivityThread.main(ActivityThread.java:4950)
E/WindowManager(19285): at java.lang.reflect.Method.invokeNative(Native Method)
E/WindowManager(19285): at java.lang.reflect.Method.invoke(Method.java:511)
E/WindowManager(19285): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1004)
E/WindowManager(19285): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:771)
E/WindowManager(19285): at dalvik.system.NativeStart.main(Native Method)
答案 0 :(得分:3)
doInBackground()
,并且必须从UI线程完成对UI的所有更改。移动代码:
googlemap.addMarker(new MarkerOptions()
.position(new LatLng(la, lo))
.title("Hello world"));
到onPostExecute()
,它将在UI线程上执行此函数。您还必须将每个标记的la
和lo
加入onPostExecute()