如何从AsyncTask中检索的JSON添加Google Maps Markers

时间:2016-12-05 18:06:44

标签: android google-maps android-studio

我有问题。我将我的mysql数据库连接到我的应用程序,添加了必要的一切。所以现在我希望这些数据显示在地图上,但是这行不起作用。

MainActivity类

public class MainActivity extends AppCompatActivity
        implements NavigationView.OnNavigationItemSelectedListener {
    private MapFragment mapsFragment;
    static MainActivity can;

    private void initializeMapsFragment() {
        android.support.v4.app.FragmentTransaction mTransaction = getSupportFragmentManager().beginTransaction();
        mapsFragment = new MapFragment();
        SupportMapFragment supportMapFragment = mapsFragment;
        mTransaction.add(R.id.map, supportMapFragment);
        mTransaction.commit();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        initializeMapsFragment();
        Log.d("--***** MAP  ","::Loading Map");
        can = this;
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.setDrawerListener(toggle);
        toggle.syncState();


        NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);
        SigninAcitivity signin = new SigninAcitivity();
        signin.execute();
    }



    @Override
    public void onBackPressed() {
        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawer(GravityCompat.START);
        } else {
            super.onBackPressed();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @RequiresApi(api = Build.VERSION_CODES.HONEYCOMB)
    @SuppressWarnings("StatementWithEmptyBody")
    @Override
    public boolean onNavigationItemSelected(MenuItem item) {
        FragmentManager fm = getFragmentManager();
        android.support.v4.app.FragmentManager sFm = getSupportFragmentManager();

        int id = item.getItemId();


        if (id == R.id.nav_camera) {

            if (!mapsFragment.isAdded())
                sFm.beginTransaction().add(R.id.map, mapsFragment).commit();
            else
                sFm.beginTransaction().show(mapsFragment).commit();
        }

        else if (id == R.id.nav_share) {

        } else if (id == R.id.nav_send) {

        }

        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        drawer.closeDrawer(GravityCompat.START);
        return true;
    }

}

MapFragment类

public class MapFragment extends SupportMapFragment {

    public static GoogleMap mapView = null;

    private void initGoogleMap() {
        getMapAsync(new OnMapReadyCallback() {
            @Override
            public void onMapReady(GoogleMap googleMap) {
                mapView = googleMap;
                if(ActivityCompat.checkSelfPermission(MainActivity.can, android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(MainActivity.can, android.Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                    mapView.setMyLocationEnabled(true);
                }


                LatLng kaunas = new LatLng(54.898544, 23.903696);
                mapView.moveCamera(CameraUpdateFactory.newLatLngZoom(kaunas, (float) 10));
            }
        });

    }

    public static void addMarker(String pav, Double lat, Double lng){

        LatLng loc = new LatLng(lat, lng);
        mapView.addMarker(new MarkerOptions().position(loc).title(pav));


    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        initGoogleMap();
    }

}

和mysql连接类

class SigninAcitivity extends AsyncTask<String, Void, String> {

protected String doInBackground(String... urls) {


    try {
        Thread.sleep(10000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    if(MapFragment.mapView != null) {
        String result = "";
        //the year data to send
        ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
        InputStream is = null;
        //http post
        try {
            DefaultHttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost("http://hidden/connect.php");
            httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
            HttpResponse response = httpclient.execute(httppost);
            HttpEntity entity = response.getEntity();
            is = entity.getContent();
        } catch (Exception e) {
            Log.e("log_tag", "Error in http connection " + e.toString());
        }
        //convert response to string
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"), 8);
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
            is.close();

            result = sb.toString();
        } catch (Exception e) {
            Log.e("log_tag", "Error converting result " + e.toString());
        }

        //parse json data
        try {
            JSONArray jArray = new JSONArray(result);
            for (int i = 0; i < jArray.length(); i++) {
                JSONObject json_data = jArray.getJSONObject(i);
                Log.i("log_tag", "id: " + json_data.getInt("id") +
                        ", pavadinimas: " + json_data.getString("pavadinimas") +
                        ", lat: " + json_data.getDouble("lat") +
                        ", long: " + json_data.getDouble("long")
                );
                String pav = json_data.getString("pavadinimas");
                Double lat = json_data.getDouble("lat");
                Double lng = json_data.getDouble("long");
                MapFragment.addMarker(pav, lat, lng);
            }
        } catch (JSONException e) {
            Log.e("log_tag", "Error parsing data " + e.toString());
        }
    }
    return null;
}

除了SigninAcitivity类中的代码外,一切正常: MapFragment.addMarker(pav, lat, lng);

它给我带来了这个错误: Caused by: java.lang.IllegalStateException: Not on the main thread

1 个答案:

答案 0 :(得分:0)

不是尝试在后台线程上运行的doInBackground()中添加标记,而是填充自定义对象列表,并将其传递给在UI线程上运行的onPostExecute()

例如POJO类:

public class MyLocation {
    public String snippet;
    public double lat;
    public double lon;
    public MyLocation(String s, double la, double lo) {
        snippet = s;
        lat = la;
        lon = lo;
    }
}

然后修改doInBackground()方法,并添加onPostExecute()方法覆盖,您可以在UI线程上绘制标记:

//Modified generics parameters:
class SigninAcitivity extends AsyncTask<String, Void, List<MyLocation>> {

    //Modified return value type:
    @Override
    protected List<MyLocation> doInBackground(String... urls) {
        List<MyLocation> retList = new ArrayList<>();
        //......

        //parse json data
        String result = "";
        try {
            JSONArray jArray = new JSONArray(result);
            for (int i = 0; i < jArray.length(); i++) {
                JSONObject json_data = jArray.getJSONObject(i);
                Log.i("log_tag", "id: " + json_data.getInt("id") +
                        ", pavadinimas: " + json_data.getString("pavadinimas") +
                        ", lat: " + json_data.getDouble("lat") +
                        ", long: " + json_data.getDouble("long")
                );
                String pav = json_data.getString("pavadinimas");
                Double lat = json_data.getDouble("lat");
                Double lng = json_data.getDouble("long");
                //MapFragment.addMarker(pav, lat, lng);
                retList.add(new MyLocation(pav, lat, lng));
            }
        } catch (JSONException e) {
            Log.e("log_tag", "Error parsing data " + e.toString());
        }
        return retList;
    }

    //Added:
    @Override
    protected void onPostExecute(List<MyLocation> locationList) {
        //Go through the list and add each Marker:
        for (MyLocation loc : locationList) {
            MapFragment.addMarker(loc.snippet, loc.lat, loc.lon);
        }
    }
}