I am new in Android developing, and took a hard one for first project. :D
So the back story :
I have MapActivity what gets MapMarkers from MySql DB (php -> Json)
Now I have a map where are some Marks and user location is known.
And what I want to do?
Simple.. when user gets near to marker (lets say 20m) then he will get
popup where he can submit that he is there..
Problem is that I have no idea how to do it..
My Code is bad, but it works :D.
For rights I have fast workaround (Lenovo tab is with bit old Android, but other way works on Android 7.1.. I hope someone can help me out here. :).
public class kaart extends FragmentActivity implements OnMapReadyCallback {
MapFragment mapFragment;
GoogleMap gMap;
MarkerOptions markerOptions = new MarkerOptions();
CameraPosition cameraPosition;
LatLng center, latLng;
String title;
String kirjeldus;
String vahend;
public static final String ID = "id"; //god to use for marker detection
public static final String TITLE = "nimi";
public static final String KIRJELDUS = "kirjeldus";
public static final String LAT = "lat";
public static final String LNG = "lng";
public static final String VAHEND = "vahend";
private String url = "https://lammerdis.ee/orient/";
String tag_json_obj = "json_obj_req";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.kaart);
mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.kaart);
mapFragment.getMapAsync(this);
}
#Override
public void onMapReady(GoogleMap googleMap) {
gMap = googleMap;
gMap.getUiSettings().setMapToolbarEnabled(false);
gMap.setMapType(GoogleMap.MAP_TYPE_HYBRID); //Võimalikud valikud MAP_TYPE_SATELLITE, MAP_TYPE_TERRAIN, MAP_TYPE_HYBRID, MAP_TYPE_NORMAL
gMap.getUiSettings().setZoomControlsEnabled(true);
gMap.getUiSettings().setCompassEnabled(true);
gMap.getUiSettings().setMyLocationButtonEnabled(true);
gMap.getUiSettings().setZoomGesturesEnabled(true);
// Kaardi alguse asukoha Zoomime Aida juurde
center = new LatLng(59.175597, 25.022103);
cameraPosition = new CameraPosition.Builder().target(center).zoom(10).build();
googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
getMarkers();
}
private void addMarker(LatLng latlng, final String title, final String kirjeldus, final String vahend) {
markerOptions.position(latlng);
markerOptions.title(title);
markerOptions.snippet(kirjeldus);
if (vahend.equalsIgnoreCase("auto")) {
markerOptions.icon(BitmapDescriptorFactory.fromResource(R.mipmap.auto));
} else {
markerOptions.icon(BitmapDescriptorFactory.fromResource(R.mipmap.jala)); }
gMap.addMarker(markerOptions);
}
// Korjame JSON-ist punktid kokku
private void getMarkers() {
StringRequest strReq = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.e("Response: ", response.toString());
try {
JSONObject jObj = new JSONObject(response);
String getObject = jObj.getString("punktid");
JSONArray jsonArray = new JSONArray(getObject);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
title = jsonObject.getString(TITLE);
kirjeldus = jsonObject.getString(KIRJELDUS);
vahend = jsonObject.getString(VAHEND);
latLng = new LatLng(Double.parseDouble(jsonObject.getString(LAT)), Double.parseDouble(jsonObject.getString(LNG)));
// Kuvame andmed kaardile
addMarker(latLng, title, kirjeldus, vahend);
}
} catch (JSONException e) {
// JSON error
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("Error: ", error.getMessage());
Toast.makeText(kaart.this, error.getMessage(), Toast.LENGTH_LONG).show();
}
});
AppController.getInstance().addToRequestQueue(strReq, tag_json_obj);
//kui punktid kaardil ja seadmes on lubatud asukohta otsida, siis kuvame kasutaja asukoha ka
//Kui on vanem android siis saame Manifestis kirjeldatud õigustega hakkama ja saaba sukoha kuvatud
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) ==
PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) ==
PackageManager.PERMISSION_GRANTED) {
gMap.setMyLocationEnabled(true); //Kuvab asukoha punktina kaardil
gMap.getUiSettings().setMyLocationButtonEnabled(true); // Kuvab asukoha nupu (viskab ilusti oma asukohale)
} else {
//Kui on android 6.0 või uuem siis tuleb õiguseid küsida rakenduse käivitamisel
ActivityCompat.requestPermissions(this, new String[] {
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION },
PackageManager.PERMISSION_GRANTED);
//Kui õigused on lubatud siis tuleb neid rakendada, kõige lihtsam on kasutajale pasundada, et rakenduse restardiks
final Toast tag = Toast.makeText(this, R.string.OIGUSE_INFO, Toast.LENGTH_LONG);
tag.show();
new CountDownTimer(50000, 1000)
{
public void onTick(long millisUntilFinished) {tag.show();}
public void onFinish() {tag.show();}
}.start();
}
}
}
You can set up GeoFences ( https://developer.android.com/training/location/geofencing.html ) with these you can create an area where when the user enters it or it you will get an intent in your intent service then it's just a matter of use that info wherever you like.
Related
I am currently creating an app for a university project. Within the app I use two php scripts - one to set data from variables within the app to a MySQL data base, and the other to retrieve data from the database and set the variables within the app. The first script that sends the data to mySQL is working fine with no issues, however the script to retrieve the data from mySQL to set variables within the app is only working when ran through my webserver. When run within my app (on Activity Start and create) the variables are all set to zero. Any help would be amazing, Ive been stuck for weeks!
<?php
require "conn.php";
$username = "test";
$stmt = $conn->prepare("SELECT gold, goldMulti, xp, xpMulti, xpMax, xpMaxMulti, dmg, dmgMulti, bossCount, bossHp, bossHpMulti, level, backgroundCount FROM users WHERE username = '$username'");
$stmt ->execute();
$stmt ->bind_result($gold, $goldMulti, $xp, $xpMulti, $xpMax, $xpMaxMulti, $dmg, $dmgMulti, $bossCount, $bossHp, $bossHpMulti, $level, $backgroundCount);
$varaibles = array();
$stmt ->fetch();
$temp = array();
$temp['gold'] = $gold;
$temp['goldMulti'] = $goldMulti;
$temp['xp'] = $xp;
$temp['xpMulti'] = $xpMulti;
$temp['xpMax'] = $xpMax;
$temp['xpMaxMulti'] = $xpMaxMulti;
$temp['dmg'] = $dmg;
$temp['dmgMulti'] = $dmgMulti;
$temp['bossCount'] = $bossCount;
$temp['bossHp'] = $bossHp;
$temp['bossHpMulti'] = $bossHpMulti;
$temp['level'] = $level;
$temp['backgroundCount'] = $backgroundCount;
array_push($variables,$temp);
echo json_encode($temp);
?>
public class MainActivity extends AppCompatActivity {
// int variables for logic and functions ------------------------------------------------------
public int gold;
public int goldAwarded;
public int goldMultiplier;
public int xp;
public int xpAwarded;
public int xpMultiplier;
public int dmg;
public int dmgMultiplier;
public int bossCount;
public int bossHP;
public int bossHPMultiplier;
public int bossHPBase;
public int level;
public int xpMax;
public int bossCountFunc;
public int backgroundCount;
public int xpMaxMulti;
public int baseDmg;
// Widget variables -----------------------------------------------------------------------------
private TextView bossNumberText;
private TextView levelText;
private TextView goldText;
private TextView bossHealthText;
private ImageButton tapButton;
private ImageView bossImage;
private ImageView playerImage;
private ImageView bossImage2;
private ImageView bossImage3;
private ImageButton shopButton;
public String LoggedInUser = LogIn.getUser();
// Audio players --------------------------------------------------------------------------------
MediaPlayer mps;
MediaPlayer mpb;
MediaPlayer mpc;
MediaPlayer mpl;
MediaPlayer mpp;
// Websever php file URL to retrieve Data from user ----------------------------------------------
private static final String URL = "http://jg1104.brighton.domains/AppPhp/variablesretrieval.php";
private void getData(){
StringRequest stringRequest = new StringRequest(Request.Method.GET, URL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try{
JSONArray array = new JSONArray(response);
for(int i = 0; i<array.length(); i++){
JSONObject object = array.getJSONObject(i);
gold = object.getInt("gold");
goldMultiplier = object.getInt("goldMulti");
xp = object.getInt("xp");
xpMultiplier = object.getInt("xpMulti");
xpMax = object.getInt("xpMax");
xpMaxMulti = object.getInt("xpMaxMulti");
dmg = object.getInt("dmg");
dmgMultiplier = object.getInt("dmgMulti");
bossCount = object.getInt("bossCount");
bossHP = object.getInt("bossHp");
bossHPMultiplier = object.getInt("bossHpMulti");
level = object.getInt("level");
backgroundCount = object.getInt("backgroundCount");
}
}catch (Exception e) {
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(MainActivity.this,error.toString(), Toast.LENGTH_SHORT).show();
}
protected Map<String, String> getParams() throws AuthFailureError {
HashMap<String, String> param = new HashMap<>();
param.put("LoggedInUser", LoggedInUser);
return param;
}
}
);
Volley.newRequestQueue(MainActivity.this).add(stringRequest);
}
// On create -------------------------------------------------------------------------------------
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bossNumberText = (TextView) findViewById(R.id.bossNumberText);
levelText = (TextView) findViewById(R.id.levelText);
goldText = (TextView) findViewById(R.id.goldText);
bossHealthText = (TextView) findViewById(R.id.bossHealthText);
tapButton = (ImageButton) findViewById(R.id.TapButton);
bossImage = (ImageView) findViewById(R.id.bossImage);
playerImage = (ImageView) findViewById(R.id.playerImage);
bossImage2 = (ImageView) findViewById(R.id.bossImage2);
bossImage3 = (ImageView) findViewById(R.id.bossImage3);
shopButton = (ImageButton) findViewById(R.id.shopButton);
mpb = MediaPlayer.create(this, R.raw.backgroundmusic);
mpc = MediaPlayer.create(this, R.raw.coin);
mpl = MediaPlayer.create(this, R.raw.levelup);
mpp = MediaPlayer.create(this, R.raw.pain);
mps = MediaPlayer.create(this, R.raw.shootingsound);
// retrieving data from database and setting TextViews -----------------------------------
getData();
// Set looping and start of background music ---------------------------------------------
mpb.setLooping(true);
mpb.start();
// Initialising variable values on create ------------------------------------------------
goldAwarded = 100;
xpAwarded = 100;
baseDmg = 1;
bossHPBase = 10;
bossCountFunc = 1;
shopButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
launchShop();
}
});
}
#Override
protected void onStart() {
// onclickListener for main button --------------------------------------------------------
super.onStart();
getData();
levelText.setText("Level: " + Integer.toString(level));
goldText.setText("Gold: " + Integer.toString(gold));
bossHealthText.setText("HP: " + Integer.toString(bossHP));
bossNumberText.setText("Boss: " + bossCount);
tapButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// shooting sound
mps.start();
// run method that looks to see if background needs to be changed
newBackground();
// handlers for enemy animations
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
bossImage.setImageDrawable(getResources().getDrawable(R.drawable.onezshot));
AnimationDrawable oneshotz = (AnimationDrawable) bossImage.getDrawable();
oneshotz.start();
}
}, 0);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
bossImage2.setImageDrawable(getResources().getDrawable(R.drawable.twozshot));
AnimationDrawable twozshot = (AnimationDrawable) bossImage2.getDrawable();
twozshot.start();
}
}, 0);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
bossImage3.setImageDrawable(getResources().getDrawable(R.drawable.threezshot));
AnimationDrawable threezshot = (AnimationDrawable) bossImage3.getDrawable();
threezshot.start();
}
}, 0);
// handler for shooting animation
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
playerImage.setImageDrawable(getResources().getDrawable(R.drawable.shooting));
AnimationDrawable shooting = (AnimationDrawable) playerImage.getDrawable();
shooting.start();
}
}, 0);
bossHP -= dmg;
bossHealthText.setText("HP: " + Integer.toString(bossHP));
// if boss dies
if (bossHP <= 1) {
mpp.start();
bossCount++;
bossCountFunc++;
backgroundCount++;
if (backgroundCount > 9) {
backgroundCount = 1;
}
if (bossCountFunc > 3) {
bossCountFunc = 1;
}
bossNumberText.setText("Boss: " + bossCount);
goldMultiplier++;
xpMultiplier++;
mpc.start();
gold += (goldAwarded * goldMultiplier);
goldText.setText("Gold: " + Integer.toString(gold));
xp += (xpAwarded * xpMultiplier);
bossHPMultiplier++;
// look for level up
if (xp >= xpMax) {
mpl.start();
level++;
dmgMultiplier++;
bossHPMultiplier *= 2;
dmg = (baseDmg * dmgMultiplier);
levelText.setText("lvl: " + Integer.toString(level));
xp = 0;
xpMax = xpMax * xpMaxMulti;
}
newBoss();
}
}
});
}
// Method to show or hide boss frames
public void newBoss(){
bossHP = bossHPBase * bossHPMultiplier;
if(bossCountFunc==1){
bossImage.setVisibility(View.VISIBLE);
bossImage2.setVisibility(View.INVISIBLE);
bossImage3.setVisibility(View.INVISIBLE);
}
if(bossCountFunc==2){
bossImage.setVisibility(View.INVISIBLE);
bossImage2.setVisibility(View.VISIBLE);
}
if(bossCountFunc==3){
bossImage2.setVisibility(View.INVISIBLE);
bossImage3.setVisibility(View.VISIBLE);
}
}
// method to check and change background
public void newBackground(){
ConstraintLayout layout = (ConstraintLayout) findViewById(R.id.constraintLayout);
if(backgroundCount<=3){
layout.setBackgroundResource(R.drawable.main);
}
if(backgroundCount>3 && backgroundCount<=6){
layout.setBackgroundResource(R.drawable.maintwo);
}
if(backgroundCount>6 && backgroundCount<=9){
layout.setBackgroundResource(R.drawable.mainthree);
}
}
public void launchShop(){
Intent intent = new Intent(this, Shop.class);
startActivity(intent);
}
private void setData(final String LoggedInUser, final int gold,final int goldMultiplier,final int xp,final int xpMultiplier
,final int xpMax,final int xpMaxMulti,final int dmg
,final int dmgMultiplier,final int bossCount,final int bossHP
,final int bossHPMultiplier,final int level,final int backgroundCount){
final ProgressDialog progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setCancelable(false);
progressDialog.setIndeterminate(false);
progressDialog.setTitle("Setting Data");
progressDialog.show();
String uRl = "http://jg1104.brighton.domains/AppPhp/setdata.php";
StringRequest request = new StringRequest(Request.Method.POST, uRl, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
if(response.equals("Data set")){
progressDialog.dismiss();
Toast.makeText(MainActivity.this, response, Toast.LENGTH_SHORT).show();
}
else{
progressDialog.dismiss();
Toast.makeText(MainActivity.this, response, Toast.LENGTH_SHORT).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
progressDialog.dismiss();
Toast.makeText(MainActivity.this, error.toString(), Toast.LENGTH_SHORT).show();
}
}){
#Override
protected Map<String, String> getParams() throws AuthFailureError {
HashMap<String, String> param = new HashMap<>();
param.put("LoggedInUser", LoggedInUser);
param.put("gold", Integer.toString(gold));
param.put("goldMulti", Integer.toString(goldMultiplier));
param.put("xp", Integer.toString(xp));
param.put("xpMulti", Integer.toString(xpMultiplier));
param.put("xpMax", Integer.toString(xpMax));
param.put("xpMaxMulti", Integer.toString(xpMaxMulti));
param.put("dmg", Integer.toString(dmg));
param.put("dmgMulti", Integer.toString(dmgMultiplier));
param.put("bossCount", Integer.toString(bossCount));
param.put("bossHp", Integer.toString(bossHP));
param.put("bossHpMulti", Integer.toString(bossHPMultiplier));
param.put("level", Integer.toString(level));
param.put("backgroundCount", Integer.toString(backgroundCount));
return param;
}
};
request.setRetryPolicy(new DefaultRetryPolicy(30000,DefaultRetryPolicy.DEFAULT_MAX_RETRIES,DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
MySingleton.getmInstance(MainActivity.this).addToRequestQueue(request);
}
#Override
protected void onStop() {
super.onStop();
setData(LoggedInUser,gold,goldMultiplier,xp,xpMultiplier,xpMax,xpMaxMulti,dmg,dmgMultiplier,bossCount,bossHP,bossHPMultiplier,level,backgroundCount);
}
}
Since the script is working when used in my webserver, I am sure it is something to do with my java coding.
This code is your problem:
try{
JSONArray array = new JSONArray(response);
for(int i = 0; i<array.length(); i++){
JSONObject object = array.getJSONObject(i);
gold = object.getInt("gold");
goldMultiplier = object.getInt("goldMulti");
xp = object.getInt("xp");
xpMultiplier = object.getInt("xpMulti");
xpMax = object.getInt("xpMax");
xpMaxMulti = object.getInt("xpMaxMulti");
dmg = object.getInt("dmg");
dmgMultiplier = object.getInt("dmgMulti");
bossCount = object.getInt("bossCount");
bossHP = object.getInt("bossHp");
bossHPMultiplier = object.getInt("bossHpMulti");
level = object.getInt("level");
backgroundCount = object.getInt("backgroundCount");
}
} catch (Exception e) {
}
You should not leave the catch block empty. It's likely throwing and swallowing an error.
Do this:
} catch (Exception e) {
Log.e("MyApp", "Error parsing!", e);
}
(Some reading on Logcat https://developer.android.com/studio/debug/am-logcat)
or get rid of the try catch all together and let your app crash (fail fast)!!
Your actual error (or first error I can see anyway) is that you are attempting to parse a JSONarray when your server side response is a JSONObject. This line of code:
JSONArray array = new JSONArray(response);
And this response:
{
"gold":600, "goldMulti":3,
"xp":0, "xpMulti":3, "xpMax":0, "xpMaxMulti":0,
"dmg":3,"dmgMulti":3,
"bossCount":3,
"bossHp":80,
"bossHpMulti":14,
"level":3,
"backgroundCount":3
}
(from here) http://jg1104.brighton.domains/AppPhp/variablesretrieval.php
You should parse it as a JsonObject or wrap your server side returned response in an Array [].
I'm fetching some of the locations from the server and need to point them as markers in the google map, so what i did was i created a model of the locations and used the volley library to fetch the details from the server and saved them in a variable and post it in the map. But I'm getting an error as java.lang.NumberFormatException: multiple points.
So need some assistance.
This is my model
public class LocationModel
private String pdLatitude;
private String pdLongitude;
public LocationModel(String pdLatitude, String pdLongitude){
this.pdLatitude = pdLatitude;
this.pdLongitude = pdLongitude; }
public String getPdLatitude() {
return pdLatitude;
}
public String getPdLongitude() {
return pdLongitude;
}
This is my Activity where i'm retreiving the information from the server
private void findRoute(){
StringRequest request = new StringRequest(Request.Method.GET,
Constant.Route_URL + "/" + driverschoolname + "/" + driverid,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
String pdlatitude = "";
String pdlongitude = "";
try{
JSONObject jsonObject = new JSONObject(response);
JSONArray array = jsonObject.getJSONArray("res");
for (int i=0; i<array.length(); i++){
JSONObject object = array.getJSONObject(i);
StudentsPickDropModel pickDropModel = new StudentsPickDropModel(
object.getString("pdloc_latitude"),
object.getString("pdloc_longitude")
);
pdlatitude += pickDropModel.getPdLatitude();
pdlongitude += pickDropModel.getPdLongitude();
Toast.makeText(StudentsPickDropActivity.this, pickDropModel.getPdName(), Toast.LENGTH_SHORT).show();
Intent intent = new Intent(Activity.this, GetRoute.class);
intent.putExtra("pd_latitude", pdlatitude);
intent.putExtra("pd_longitude", pdlongitude);
startActivity(intent);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(Activity.this, error.getMessage(), Toast.LENGTH_SHORT).show();
}
});
RequestQueue queue = Volley.newRequestQueue(this);
queue.add(request);
}
And this is how i'm posting my coordiantes in Google maps
Bundle bundle = getIntent().getExtras();
schoollat = bundle.getString("school_lat");
schoollng = bundle.getString("school_lng");
pdlat = bundle.getString("pd_latitude");
pdlng = bundle.getString("pd_longitude");
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
mFusedLocationClient.getLastLocation().addOnCompleteListener(new OnCompleteListener<Location>() {
#Override
public void onComplete(#NonNull Task<Location> task) {
Location location = task.getResult();
if (location == null){
requestNewLocationData();
} else {
currentLat = location.getLatitude();
currentLng = location.getLongitude();
System.out.println("Current Latitude: "+location.getLatitude());
System.out.println("Current Longitude: "+location.getLongitude());
}
}
});
Double clat = currentLat;
System.out.println("Current Latitude : "+clat);
Double schoollatitude = new Double(schoollat);
Double schoollongitude = new Double(schoollng);
System.out.println("School latitude : "+schoollatitude + ", School Longitude : "+schoollongitude);
Double pdlatitude = new Double(pdlat);
Double pdlongitude = new Double(pdlng);
getDirections = findViewById(R.id.getdirection);
getDirections.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new FetchURL(GetRoute.this).execute(getUrl(placeOne.getPosition(), placeTwo.getPosition(), "driving"), "driving");
}
});
MapFragment mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map_fragment);
mapFragment.getMapAsync(this);
places = new MarkerOptions().position(new LatLng(pdlatitude, pdlongitude)).title("Office");
And this is my JSON
"res": [
{
"pdloc_latitude": "12.3111356",
"pdloc_longitude": "76.6075989",
},
{
"pdloc_latitude": "88.568645787",
"pdloc_longitude": "75.54544454887",
}
Use Double.parseDouble() for better efficiency
The core method is parseDouble() which is specially designed to parse
a String containing floating point value into the Double object. Rest
of the methods e.g. valueOf() and constructor uses parseDouble()
internally.
and be sure that the pdlat value you are passing is a valid double number and not just plain characters
This( Double.parseDouble()) method will throw NullPointerException if the string you are passing is null and NumberFormatException if String is not containing a valid double value e.g. containing alphabetic characters.
Just debug Double pdlatitude = new Double(pdlat); line to be sure.
Your PDlat have 2 points. That is invalid for Double since Double have 1 point.
Your value:
12.311135688.568645787
What it should has 1 point like this:
12.311135688568645787
PS. You can catch an exception If the value parsing is fail, and what to do is up to what exception occurs.
I am trying to create an Android app that displays a Map that shows every university | school in the area/nearby. I've looked over SO and Google and have only found tutorials on how to add markers, add tiles, or show a specific lat/lng but is there a way to show specific markers based on specific parameters? For example, if I want to show every marker for all universities/schools how would I go about passing those parameters to the MapFragment? I haven't tried anything because I haven't found anything that even hints at how to do that except for a reference to the web app api which didn't help for the Android specific api.
Hope it helps its a travel guide app code
public class SearchPlaceType extends Activity
{
String[] itemTypeName ={
"airport",
"atm",
"bank",
"bus_station",
"gas_station",
"hospital",
"mosque",
"park",
"restaurant",
"university",
"food"
};
ListView listView;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.search_place_type);
listView = (ListView)findViewById(R.id.typeList);
listView.setAdapter(new PlaceTypeAdapter(SearchPlaceType.this, itemTypeName));
listView.setOnItemClickListener(new OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id)
{
Intent intent = new Intent(SearchPlaceType.this,NearByPlaces.class);
intent.putExtra("positionOfType", (int)position);
startActivity(intent);
}
});
}
}
Than class to tell the near by places
public class NearByPlaces extends Activity
{
ArrayList<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();
ListView listView;
int positionOfType = 0;
Context context;
MyLocation myLocation;
double current_location_lat, current_location_lng;
public static String latStr = "";
public static String longStr = "";
public static LatLng myLatLng = null;
public static LatLng destinationLatLng = null;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.near_by_places);
context = NearByPlaces.this;
Bundle extras = getIntent().getExtras();
if(extras!=null)
{
positionOfType = extras.getInt("positionOfType", positionOfType);
}
listView = (ListView)findViewById(R.id.nearbyList);
myLocation = new MyLocation(context);
if (myLocation.isLocationAvailable() && myLocation.getUserLocation() != null)
{
current_location_lat = myLocation.getUserLocation().latitude;
current_location_lng = myLocation.getUserLocation().longitude;
latStr = current_location_lat + "";
longStr = current_location_lng + "";
myLatLng = new LatLng(current_location_lat, current_location_lng);
//url = url_part1 + latStr + "," + longStr + url_part2;
Log.d("LATITUDE", String.valueOf(current_location_lat));
Log.d("LONGITUDE", String.valueOf(current_location_lng));
new PlaceTask(context, positionOfType, latStr, longStr, new onTaskDoneListener()
{
#Override
public void onTaskDone(JSONObject jsonObject)
{
if(jsonObject!=null)
{
try
{
JSONObject obj = jsonObject;//new JSONObject(jsonObject);
String status = obj.getString("status");
if(status.equals("OK"))
{
JSONArray arr = obj.getJSONArray("results");
for(int i = 0; i < arr.length(); i++)
{
double lat = arr.getJSONObject(i).getJSONObject("geometry").getJSONObject("location").getDouble("lat");
double lng = arr.getJSONObject(i).getJSONObject("geometry").getJSONObject("location").getDouble("lng");
String place_name = arr.getJSONObject(i).getString("name");
String vicinity = arr.getJSONObject(i).getString("vicinity");
HashMap<String, String> map = new HashMap<String,String>();
map.put("placeName", place_name);
map.put("vicinity", vicinity);
map.put("lat", String.valueOf(lat));
map.put("lng", String.valueOf(lng));
list.add(map);
}
NearByPlaceAdapter adapter = new NearByPlaceAdapter(context, list);
listView.setAdapter(adapter);
}
}
catch (JSONException e)
{
e.printStackTrace();
}
}
else
{
Toast.makeText(context, "Response is Null", Toast.LENGTH_LONG).show();
}
}
}).execute();
//showSearchDialog(map);
}
else
{
Toast.makeText(context, "Please Enable Location Services and GPS From your Device",
Toast.LENGTH_LONG).show();
}
listView.setOnItemClickListener(new OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id)
{
HashMap<String, String> map = list.get(position);
Intent intent = new Intent(context,DirectionActivity3.class);
destinationLatLng = new LatLng(Double.valueOf(map.get("lat")), Double.valueOf(map.get("lat")));
startActivity(intent);
}
});
}
}
Draw marker using this MapyPane class
public class MapyPane extends Activity implements OnMapReadyCallback
{
String[] itemTypeName ={
"airport",
"atm",
"bank",
"bus_station",
"gas_station",
"hospital",
"mosque",
"park",
"restaurant",
"university",
"food"
};
Marker myMarker;
GMapV2Direction md;
MyLocation myLocation;
GoogleMap googleMap;
double current_location_lat, current_location_lng;
public static String latStr = "";
public static String longStr = "";
Dialog searchDialog;
ImageView searchDialogIv;
ImageView searchIcon;
EditText searchText;
Context context;
Integer[] imageId = {
R.drawable.school_3,
R.drawable.atm_3,
R.drawable.school_3,
R.drawable.police_station_3,
R.drawable.cng_station_3,//5
R.drawable.hospital_3,
R.drawable.school_3,
R.drawable.hospital_3,//8
R.drawable.hotel_3,
R.drawable.cng_station_3,
R.drawable.hotel_3
};
int positionToFind = 0;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = MapyPane.this;
md = new GMapV2Direction();
MapFragment mapFragment = (MapFragment) getFragmentManager()
.findFragmentById(R.id.fragment_map);
mapFragment.getMapAsync(this);
googleMap = mapFragment.getMap();//my doctory..
Bundle extras = getIntent().getExtras();
if(extras!=null)
{
positionToFind = extras.getInt("positionToFind", positionToFind);
}
searchText = (EditText)findViewById(R.id.search_text);
searchDialogIv = (ImageView)findViewById(R.id.search_dialogIv);
searchDialogIv.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
if(googleMap==null)
{
Toast.makeText(context, "Unable to load Map", Toast.LENGTH_LONG).show();
}
else
{
showSearchDialog(googleMap);
}
}
});
searchIcon = (ImageView)findViewById(R.id.search_icon);
searchIcon.setVisibility(View.GONE);
searchText.setVisibility(View.GONE);
searchIcon.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
//if(sear)
new PlaceTask(context, searchText.getText().toString(), latStr, longStr, new onTaskDoneListener()
{
#Override
public void onTaskDone(JSONObject jsonObject)
{
//drawMarkersOnMap(jsonObject, googleMap,postponeEnterTransition());
}
}).execute();
}
});
}
/*public void drawPathBetween(LatLng sourcePosition,LatLng destPosition,GoogleMap mMap)
{
Document doc = md.getDocument(sourcePosition, destPosition,
GMapV2Direction.MODE_DRIVING);
ArrayList<LatLng> directionPoint = md.getDirection(doc);
PolylineOptions rectLine = new PolylineOptions().width(3).color(
Color.RED);
for (int i = 0; i < directionPoint.size(); i++)
{
rectLine.add(directionPoint.get(i));
}
Polyline polylin = mMap.addPolyline(rectLine);
}*/
#Override
public void onMapReady(GoogleMap map)
{
// check if map is created successfully or not
if (map == null)
{
Toast.makeText(getApplicationContext(),
"Sorry! unable to load maps", Toast.LENGTH_SHORT)
.show();
}
else
{
myLocation = new MyLocation(MapyPane.this, map);
if (myLocation.isLocationAvailable() && myLocation.getUserLocation() != null)
{
current_location_lat = myLocation.getUserLocation().latitude;
current_location_lng = myLocation.getUserLocation().longitude;
latStr = current_location_lat + "";
longStr = current_location_lng + "";
//url = url_part1 + latStr + "," + longStr + url_part2;
Log.d("LATITUDE", String.valueOf(current_location_lat));
Log.d("LONGITUDE", String.valueOf(current_location_lng));
// Showing Current Location
map.setMyLocationEnabled(true);
// Move the camera instantly to hamburg with a zoom of 15.
map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(current_location_lat, current_location_lng), 15));
// Zoom in, animating the camera.
map.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);
// Moving Camera to a Location with animation
/*CameraPosition cameraPosition = new CameraPosition.Builder().target(
new LatLng(current_location_lat, current_location_lng)).zoom(12).build();
//CameraPosition cameraPosition = new CameraPosition.Builder().target(
//new LatLng( -33.8650, 151.2094)).zoom(12).build();
map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));*/
MarkerOptions markerOptions = new MarkerOptions().title("YourLocation").position(new LatLng(current_location_lat, current_location_lng)).icon(BitmapDescriptorFactory
.fromResource(R.drawable.gas_station));//gas_station
myMarker = map.addMarker(markerOptions);
new PlaceTask(context, positionToFind, latStr, longStr, new onTaskDoneListener() {
#Override
public void onTaskDone(JSONObject jsonObject)
{
}
});
//showSearchDialog(map);
}
else
{
Toast.makeText(MapyPane.this, "Please Enable Location Services and GPS From your Device",
Toast.LENGTH_LONG).show();
}
}
/* LatLng sydney = new LatLng(-33.867, 151.206);
map.setMyLocationEnabled(true);
map.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney, 13));
map.addMarker(new MarkerOptions()
.title("Sydney")
.snippet("The most populous city in Australia.")
.position(sydney));*/
/*map.moveCamera(CameraUpdateFactory.newLatLngZoom(
new LatLng(41.889, -87.622), 16));
// You can customize the marker image using images bundled with
// your app, or dynamically generated bitmaps.
map.addMarker(new MarkerOptions()
.icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher))
.anchor(0.0f, 1.0f) // Anchors the marker on the bottom left
.position(new LatLng(41.889, -87.622)));*/
}
private void drawMarkersOnMap(JSONObject jsonObject,final GoogleMap googleMap,int posi)
{
if(jsonObject!=null)
{
googleMap.clear();
try
{
JSONObject obj = jsonObject;//new JSONObject(jsonObject);
String status = obj.getString("status");
if(status.equals("OK"))
{
JSONArray arr = obj.getJSONArray("results");
for(int i = 0; i < arr.length(); i++)
{
double lat = arr.getJSONObject(i).getJSONObject("geometry").getJSONObject("location").getDouble("lat");
double lng = arr.getJSONObject(i).getJSONObject("geometry").getJSONObject("location").getDouble("lng");
String food_name = arr.getJSONObject(i).getString("name");
String vicinity = arr.getJSONObject(i).getString("vicinity");
MarkerOptions marker = new MarkerOptions().position(new LatLng(lat, lng)).icon(BitmapDescriptorFactory
.fromResource( imageId[posi]));// R.drawable.ic_launcher));//gas_station
marker.title(food_name);
marker.snippet(vicinity);
final Marker testMarker = googleMap.addMarker(marker);
googleMap.setOnMarkerClickListener(new OnMarkerClickListener()
{
#Override
public boolean onMarkerClick(Marker markker)
{
if(markker.equals(testMarker))
{
//drawPathBetween(myMarker.getPosition(), markker.getPosition(), googleMap);
}
else
{
}
return false;
}
});
}
}
}
catch (JSONException e)
{
e.printStackTrace();
}
}
}
private void showSearchDialog(final GoogleMap map)
{
searchDialog = new Dialog(MapyPane.this);
searchDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
searchDialog.setContentView(R.layout.menu_item_custom_dialog);
searchDialog.setCanceledOnTouchOutside(false);
ListView list;
final String[] web = {
"airport",
"atm",
"bank",
"bus_station",
"gas_station", //department_store ya home_goods_store
"hospital", //health
"mosque",//7
"park",
"restaurant",//instead of hotels
"university",
"Food"
} ;
Integer[] imageId = {
R.drawable.school_3,
R.drawable.atm_3,
R.drawable.school_3,
R.drawable.police_station_3,
R.drawable.cng_station_3,//5
R.drawable.hospital_3,
R.drawable.school_3,
R.drawable.hospital_3,//8
R.drawable.hotel_3,
R.drawable.cng_station_3,
R.drawable.hotel_3
};
CustomList adapter = new
CustomList(MapyPane.this, web, imageId);
list = (ListView) searchDialog.findViewById(R.id.list_location);
list.setAdapter(adapter);
///list.setSelector(R.drawable.list_item_selector);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
final int position, long id) {
//Toast.makeText(MapyPane.this, "You Clicked at " +web[+ position], Toast.LENGTH_SHORT).show();
ConnectivityManager connManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mWifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if (mWifi.isConnected())
{
if(latStr.equals(""))
{
Toast.makeText(MapyPane.this, " please enable your gps location ", Toast.LENGTH_SHORT).show();
}
else
{
new PlaceTask(MapyPane.this, position, latStr, longStr, new onTaskDoneListener()
{
#Override
public void onTaskDone(JSONObject jsonObject)
{
drawMarkersOnMap(jsonObject, map,position);
}
}).execute();
searchDialog.dismiss();
}
}
else
{
Toast.makeText(MapyPane.this, "Internet is not available", Toast.LENGTH_SHORT).show();
}
}
});
searchDialog.show();
}
}
Then the solution for your problem is Android Places API....It allows you to show places nearby based on your choice...This would help you in getting started...https://developers.google.com/places/android-api/start
I solved the issue for "checking if location is enabled", but now I'm stuck. I want the app to show a toast if location is disabled, and once it's enabled by the user, I want the app to proceed as normal, like location was enabled at the first place. My code looks correct to me, I don't know where the problem is. Note that I don't have any issues with accessing the location, network and stuff. It's just that I always need to restart the app after enabling location, otherwise it won't proceed and keep giving me the warning toast. Thanks in advance.
Edit: So I just added an alert dialog method instead of Toast messages. Users can now go to settings and turn location and network on using that dialog. I'd like you to take a look at the Network check if-else statement inside getForecast() method. else contains the alert dialog that leads user to Settings-Data Roaming. And when user activated mobile data and returns to the app, everything's fine and app can get info. I did the same for location if-else statement, yet when user turns location on and returns to the app, no matter what I do (wait several minutes, refresh several times), I'm not getting the location info. I need to close and reopen the app every time. That's the exact issue I'm facing.
Code:
public class MainActivity extends AppCompatActivity {
public static final String TAG = MainActivity.class.getSimpleName();
public static final String DAILY_FORECAST = "DAILY_FORECAST";
private Forecast mForecast;
#Bind(R.id.timeLabel) TextView mTimeLabel;
#Bind(R.id.tempLabel) TextView mTempLabel;
#Bind(R.id.humidityValue) TextView mHumidityValue;
#Bind(R.id.precipValue) TextView mPrecipValue;
#Bind(R.id.summaryLabel) TextView mSummaryLabel;
#Bind(R.id.windSpeedValue) TextView mWindSpeedValue;
#Bind(R.id.relativeLayout) RelativeLayout mRelativeLayout;
#Bind(R.id.container) SwipeRefreshLayout mSwipeRefreshLayout;
#Bind(R.id.locationLabel) TextView mLocationLabel;
double latitude;
double longitude;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
final GPSTracker gpsTracker = new GPSTracker(this);
mSwipeRefreshLayout.setColorSchemeColors(Color.RED, Color.GREEN, Color.BLUE, Color.CYAN);
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
mSwipeRefreshLayout.setRefreshing(false);
}
}, 1500);
if (gpsTracker.getIsGPSTrackingEnabled()){
getForecast(gpsTracker);
updateDisplay(gpsTracker);
} else {
Toast.makeText(MainActivity.this, "Please enable location services.!!", Toast.LENGTH_LONG).show();
gpsTracker.showSettingsAlert();
}
}
});
getForecast(gpsTracker);
}
private void getForecast(final GPSTracker gpsTracker) {
latitude = gpsTracker.getLatitude();
longitude = gpsTracker.getLongitude();
String apiKey = "7d22cdb138cd70f2e9e8d2006cd0461c";
String forecastUrl = "https://api.forecast.io/forecast/" + apiKey
+ "/" + latitude + "," + longitude;
if (isNetworkAvailable()) {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(forecastUrl).build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
#Override
public void onFailure(Request request, IOException e) {
alertUserAboutError();
}
#Override
public void onResponse(Response response) throws IOException {
try {
String jsonData = response.body().string();
Log.v(TAG, jsonData);
if (response.isSuccessful()) {
mForecast = parseForecastDetails(jsonData);
runOnUiThread(new Runnable() {
#Override
public void run() {
if (gpsTracker.getIsGPSTrackingEnabled()) {
updateDisplay(gpsTracker);
} else {
Toast.makeText(MainActivity.this, "Please enable location services.", Toast.LENGTH_LONG).show();
}
}
});
} else {
alertUserAboutError();
}
} catch (IOException | JSONException e) {
Log.e(TAG, "Exception caught: ", e);
}
}
});
} else {
gpsTracker.showSettingsAlert2();
}
}
private void updateDisplay(GPSTracker gpsTracker) {
Currently currently = mForecast.getCurrently();
String area = gpsTracker.getSubLocality(this);
String city = gpsTracker.getAdminArea(this);
String country = gpsTracker.getCountryName(this);
mLocationLabel.setText(area + "\n" + city + ", " + country);
mTempLabel.setText(currently.getTemperature() + "");
mTimeLabel.setText(currently.getFormattedTime());
mHumidityValue.setText(currently.getHumidity() + "%");
mPrecipValue.setText(currently.getPrecipChance() + "%");
mSummaryLabel.setText(currently.getSummary());
mWindSpeedValue.setText(currently.getWindSpeed() + "");
Drawable drawable = getResources().getDrawable(currently.getBackgroundId());
mRelativeLayout.setBackground(drawable);
}
// irrelevant after this point. (I guess)
private Forecast parseForecastDetails(String jsonData) throws JSONException {
Forecast forecast = new Forecast();
forecast.setCurrently(getCurrentlyDetails(jsonData));
forecast.setHourlyForecast(getHourlyForecast(jsonData));
forecast.setDailyForecast(getDailyForecast(jsonData));
return forecast;
}
private Daily[] getDailyForecast(String jsonData) throws JSONException {
JSONObject forecast = new JSONObject(jsonData);
String timezone = forecast.getString("timezone");
JSONObject jsonDaily = forecast.getJSONObject("daily");
JSONArray data = jsonDaily.getJSONArray("data");
Daily[] days = new Daily[data.length()];
for (int i = 0; i < data.length(); i++) {
JSONObject daily = data.getJSONObject(i);
Daily day = new Daily();
day.setSummary(daily.getString("summary"));
day.setTempMax(daily.getDouble("temperatureMax"));
day.setTempMin(daily.getDouble("temperatureMin"));
day.setIcon(daily.getString("icon"));
day.setTime(daily.getLong("time"));
day.setTimezone(timezone);
days[i] = day;
}
return days;
}
private Hourly[] getHourlyForecast(String jsonData) throws JSONException{
JSONObject forecast = new JSONObject(jsonData);
String timezone = forecast.getString("timezone");
JSONObject jsonHourly = forecast.getJSONObject("hourly");
JSONArray data = jsonHourly.getJSONArray("data");
Hourly[] hours = new Hourly[data.length()];
for(int i=0; i < data.length(); i++) {
JSONObject hourly = data.getJSONObject(i);
Hourly hour = new Hourly();
hour.setSummary(hourly.getString("summary"));
hour.setTemp(hourly.getDouble("temperature"));
hour.setIcon(hourly.getString("icon"));
hour.setTime(hourly.getLong("time"));
hour.setTimezone(timezone);
hours[i] = hour;
}
return hours;
}
private Currently getCurrentlyDetails(String jsonData) throws JSONException {
JSONObject forecast = new JSONObject(jsonData);
String timezone = forecast.getString("timezone");
JSONObject currently = forecast.getJSONObject("currently");
Currently currentWeather = new Currently();
currentWeather.setHumidity(currently.getDouble("humidity"));
currentWeather.setTime(currently.getLong("time"));
currentWeather.setPrecipChance(currently.getDouble("precipProbability"));
currentWeather.setSummary(currently.getString("summary"));
currentWeather.setTemperature(currently.getDouble("temperature"));
currentWeather.setWindSpeed(currently.getDouble("windSpeed"));
currentWeather.setTimeZone(timezone);
currentWeather.setBackgroundId(currently.getString("icon"));
Log.d(TAG, currentWeather.getFormattedTime());
return currentWeather;
}
private boolean isNetworkAvailable() {
ConnectivityManager manager = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = manager.getActiveNetworkInfo();
boolean isAvailable = false;
if (networkInfo != null && networkInfo.isConnected()){
isAvailable = true;
}
return isAvailable;
}
private void alertUserAboutError() {
AlertDialogFragment dialog = new AlertDialogFragment();
dialog.show(getFragmentManager(), "error_dialog");
}
#OnClick (R.id.dailyButton)
public void startDailyActivity(View view){
Intent intent = new Intent(this, DailyForecastActivity.class);
intent.putExtra(DAILY_FORECAST, mForecast.getDailyForecast());
startActivity(intent);
}
}
I need some help to fix this problem. I have a PieChart which is drawn in my android App using some data from a MySQL db. I am using an AsyncTask class implementation which loads the data from the server making an HTTPPostRequest and parsing the JSON response that is returned. The chart comes out fine and is drawn on the screen. The problem comes out when I rotate the device's screen: the Chart behaves abnormally and draws slices again... I don't know why it is doing that, but I read that if you rotate the screen all the methods of the Activity are called again (the onCreate(), onStart() and onResume() methods). Maybe it's because of that??? But I am not sure... Here is how is look like:
Then when I rotate the device:
The data are duplicated! Why? What am I mistaking?
Here is all the code:
public class ComeHaInvestito extends Activity {
/**** PieChartBuilder ****/
/** Colors to be used for the pie slices. */
private static int[] COLORS = new int[] { Color.GREEN, Color.BLUE, Color.MAGENTA, Color.CYAN };
/** The main series that will include all the data. */
private CategorySeries mSeries = new CategorySeries("");
/** The main renderer for the main dataset. */
private DefaultRenderer mRenderer = new DefaultRenderer();
/** Edit text field for entering the slice value. */
//private EditText mValue;
/** The chart view that displays the data. */
private GraphicalView mChartView;
private int HowmanyTimes;
#Override
protected void onRestoreInstanceState(Bundle savedState) {
super.onRestoreInstanceState(savedState);
mSeries = (CategorySeries) savedState.getSerializable("current_series");
mRenderer = (DefaultRenderer) savedState.getSerializable("current_renderer");
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putSerializable("current_series", mSeries);
outState.putSerializable("current_renderer", mRenderer);
}
/**** ComeHaInvestito ****/
// String which will store the values of the user
String municipalityName;
String year;
String versedMoney;
// List<Item> ArrayList that will be used to store data from DB
List<Item> MasterAndDetailstatisticsInfoList;
private static final String TAG_COMUNE = "mun_name";
private static final String TAG_ANNO = "year";
private static final String TAG_VERSED_MONEY = "versed_money";
private static final String TAG_SUCCESS = "success";
// POST request information
private static final String URL_ANDROID_APP_LISTENER = "http://xxx.xxx.xxx.xxx/androidApp/AndroidListener.php";
private ProgressDialog pDialog;
// JSONParser instance
JSONParser jParser = new JSONParser();
// JSON data retrieving information
private static final String JSON_STATISTICS_INFOS_LABEL = "statistics_infos";
private static final String JSON_MASTER_LABEL = "master";
private static final String JSON_DETAIL_LABEL = "detail";
private static final String JSON_MASTER_DETAIL_NAME_LABEL = "name";
private static final String JSON_MASTER_DETAIL_VALUE_LABEL ="value";
// statistics info JSON Array which will contain the Master and Detail data that will come from the POST request
JSONArray statisticsInfo = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_come_ha_investito);
Log.d("OnCREATE", "CREO L'ACTIVITY");
// recovering data from previous actitity
Intent iMieiDati = getIntent();
this.municipalityName = iMieiDati.getStringExtra(TAG_COMUNE);
this.year = iMieiDati.getStringExtra(TAG_ANNO);
this.versedMoney = iMieiDati.getStringExtra(TAG_VERSED_MONEY);
// instantiating the needed data structure
MasterAndDetailstatisticsInfoList = new ArrayList<Item>();
mRenderer.setStartAngle(270);
mRenderer.setDisplayValues(true);
new LoadAllMunicipalitiesInvestmentStatisticsThread().execute();
//mRenderer.setZoomButtonsVisible(true);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.pie_chart_builder2, menu);
return true;
}
#Override
protected void onResume() {
super.onResume();
if (mChartView == null) {
LinearLayout layout = (LinearLayout) findViewById(R.id.chart);
mChartView = ChartFactory.getPieChartView(this, mSeries, mRenderer);
mRenderer.setClickEnabled(true);
mChartView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
SeriesSelection seriesSelection = mChartView.getCurrentSeriesAndPoint();
if (seriesSelection == null) {
Toast.makeText(ComeHaInvestito.this, "No chart element selected", Toast.LENGTH_SHORT).show();
}
else {
for (int i = 0; i < mSeries.getItemCount(); i++) {
mRenderer.getSeriesRendererAt(i).setHighlighted(i == seriesSelection.getPointIndex());
}
// mChartView.repaint();
Toast.makeText(
ComeHaInvestito.this,
"Chart data point index " + seriesSelection.getPointIndex() + " selected"
+ " point value=" + seriesSelection.getValue(), Toast.LENGTH_SHORT).show();
}
}
});
layout.addView(mChartView, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
}
else {
//mChartView.repaint();
}
}
private void initChart() {
int i=0;
double value=0;
for (Item item : MasterAndDetailstatisticsInfoList) {
if (i == 4) {
break;
}
Log.d("Ciclo ", "NUMERO " + i);
if (item.getViewType() == EntryType.MASTER.ordinal()) {
MasterWithValue master = (MasterWithValue) item;
Log.d("MASTER NAME", master.getMasterName());
Log.d("MASTER VALUE", master.getMasterValue());
try {
value = Double.parseDouble(master.getMasterValue());
}
catch (NumberFormatException e) {
// value is not a decimal
}
mSeries.add(master.getMasterName(), value);
SimpleSeriesRenderer renderer = new SimpleSeriesRenderer();
renderer.setColor(COLORS[i%4]);
i++;
mRenderer.addSeriesRenderer(renderer);
Log.d("mSeries", mSeries.toString());
}
}
}
/**** Background Thread ****/
public class LoadAllMunicipalitiesInvestmentStatisticsThread extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(ComeHaInvestito.this);
pDialog.setMessage("Caricamento...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected String doInBackground(String... args) {
Log.d("ilMioComune", "Caricamento Statistiche Investimenti");
// building the HTTP POST request
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair(TAG_COMUNE, municipalityName));
params.add(new BasicNameValuePair(TAG_ANNO, year));
params.add(new BasicNameValuePair(TAG_VERSED_MONEY, versedMoney));
Log.d("params", params.toString());
JSONObject json = jParser.makeHttpRequest(URL_ANDROID_APP_LISTENER, "POST", params);
Log.d("JSON POST statistics investments", json.toString());
try {
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
statisticsInfo = json.getJSONArray(JSON_STATISTICS_INFOS_LABEL);
// foreach Statistics Master Entry
for (int i = 0; i<statisticsInfo.length(); i++) {
JSONObject JSONstatisticsInfo = statisticsInfo.getJSONObject(i);
JSONObject JSONmasterEntry = JSONstatisticsInfo.getJSONObject(JSON_MASTER_LABEL);
String masterEntryName = JSONmasterEntry.getString(JSON_MASTER_DETAIL_NAME_LABEL);
String masterEntryValue = JSONmasterEntry.getString(JSON_MASTER_DETAIL_VALUE_LABEL);
MasterAndDetailstatisticsInfoList.add(new MasterWithValue(masterEntryName, masterEntryValue));
JSONArray JSONdetails = JSONmasterEntry.getJSONArray(JSON_DETAIL_LABEL);
for (int j = 0; j<JSONdetails.length(); j++) {
JSONObject JSONdetailEntry = JSONdetails.getJSONObject(j);
String detailEntryName = JSONdetailEntry.getString(JSON_MASTER_DETAIL_NAME_LABEL);
String detailEntryValue = JSONdetailEntry.getString(JSON_MASTER_DETAIL_VALUE_LABEL);
MasterAndDetailstatisticsInfoList.add(new Detail(detailEntryName, detailEntryValue));
}
}
}
else {
// no statistics infos associated to the selected municipality were found
}
}
catch (JSONException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String file_url) {
pDialog.dismiss();
runOnUiThread(new Runnable() {
#Override
public void run() {
String MasterAndDetails = MasterAndDetailstatisticsInfoList.toString();
Log.d("List", MasterAndDetails);
// Creating the pie chart using the data recovered from the DB
initChart();
}
});
}
}
}
Does anyone have any idea on how to resolve this problem?
Thanks for the attention! Hope fore some help!
You are correct in that onCreate(), onResume(), etc. get called whenever you rotate. Because of this, you are calling new LoadAllMunicipalitiesInvestmentStatisticsThread().execute(); twice essentially.
You should move your data initialization logic to one place, and either load that data from the savedInstanceState, or call the initialize logic if the savedInstanceState returns null.
For example:
change declaration to
private CategorySeries mSeries = null;
in onCreate()
if(savedInstanceState != null)
mSeries = (CategorySeries) savedInstanceState.getSerializable("current_series");
if(mSeries == null)
{
mSeries = new CategorySeries("");
new LoadAllMunicipalitiesInvestmentStatisticsThread().execute(); //this line can be substituted for a new init method, which would contain the thread.execute
}