如何将多个标记添加到谷歌地图中存储在数组中的位置

时间:2013-08-01 20:28:06

标签: android google-maps android-asynctask google-maps-markers

我正在编写一个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)

1 个答案:

答案 0 :(得分:3)

在UI线程上不执行

doInBackground(),并且必须从UI线程完成对UI的所有更改。移动代码:

googlemap.addMarker(new MarkerOptions()    
.position(new LatLng(la, lo))   
.title("Hello world")); 

onPostExecute(),它将在UI线程上执行此函数。您还必须将每个标记的lalo加入onPostExecute()