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);
}
}
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 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.
I have an activity in which I have used Recycle View to show all items as a list. On same activity I have given functionality to add new item. Everything is working fine. Items are adding in my database and its showing in list. I have added pagination on Recycle View it is also working fine. What I want that when user add new item at the same time when new data added to database but it is not updating in list. When user press back and again come on activity after that it is showing in list. I want to add add new item at same time without scroll the list or without go back.
TimelineActivity.java
public class TimelineActivity extends AppCompatActivity implements RecyclerView.OnScrollChangeListener {
private static final String TAG = MainActivity.class.getSimpleName();
private RecyclerView listView;
private RecyclerView.LayoutManager layoutManager;
private RecyclerView.Adapter adapter;
private TimeLineListAdapter listAdapter;
private List<TimeLineItem> timeLineItems;
private int requestCount = 1;
private ProgressDialog pDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_timeline);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
listView = (RecyclerView) findViewById(R.id.list);
listView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
listView.setLayoutManager(layoutManager);
btnPost = (Button) findViewById(R.id.btnPost);
//Adding an scroll change listener to recyclerview
listView.setOnScrollChangeListener(this);
// Progress dialog
pDialog = new ProgressDialog(this);
pDialog.setCancelable(false);
cd = new ConnectionDetector(this);
isInternetPresent = cd.isConnectingToInternet();
db = new SQLiteHandler(this);
// session manager
session = new SessionManager(this);
/*pref = getApplicationContext().getSharedPreferences("MayahudiPref", 0);
editor = pref.edit();*/
buttonClickEvent();
// Fetching user details from sqlite
HashMap<String, String> user = db.getUserDetails();
id = user.get("id");
token = user.get("token");
getData();
timeLineItems = new ArrayList<>();
adapter = new TimeLineListAdapter(timeLineItems, this);
listView.setAdapter(adapter);
Timer autoRefresh;
autoRefresh=new Timer();
autoRefresh.schedule(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
public void run() {
getTimeLineData(token, "1");
}
});
}
}, 0, 2000);
}
public void getTimeLineData(final String token, final String page) {
String tag_string_req = "req_register";
// making fresh volley request and getting json
StringRequest strReq = new StringRequest(Request.Method.POST, AppConfig.timeline, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
VolleyLog.d(TAG, "Response: " + response.toString());
if (response != null) {
try {
JSONObject jObj = new JSONObject(response);
boolean error = jObj.getBoolean("status");
String message = jObj.getString("message");
if (error) {
totalPages = jObj.getInt("totalPages");
pageCount = jObj.getInt("page");
int limit = jObj.getInt("limit");
parseJsonFeed(response);
}
} catch (Exception e) {
}
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
}
}) {
#Override
protected Map<String, String> getParams() {
// Posting params to register url
Map<String, String> params = new HashMap<String, String>();
params.put("my_token", token);
params.put("page", page);
params.put("limit", "5");
return params;
}
};
// Adding request to request queue
AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
}
private void parseJsonFeed(String response) {
try {
JSONObject jsonObj = new JSONObject(response);
JSONArray feedArray = jsonObj.getJSONArray("data");
for (int i = 0; i < feedArray.length(); i++) {
JSONObject feedObj = (JSONObject) feedArray.get(i);
TimeLineItem item = new TimeLineItem();
item.setId(feedObj.getInt("id"));
item.setName(feedObj.getString("name"));
item.setLname(feedObj.getString("lname"));
// Image might be null sometimes
String image = feedObj.isNull("image") ? null : feedObj
.getString("image");
if (image.equals("")) {
item.setImge(image);
} else {
item.setImge(AppConfig.storyPic + image);
}
item.setStatus(feedObj.getString("story_text"));
item.setProfilePic(AppConfig.profilePic + feedObj.getString("profile_pic"));
item.setTimeStamp(feedObj.getString("time_stamp"));
item.setIsLike(feedObj.getInt("is_like"));
item.setTotalLikes(feedObj.getString("total_likes"));
item.setTotalComment(feedObj.getString("total_comments"));
/*// url might be null sometimes
String feedUrl = feedObj.isNull("url") ? null : feedObj
.getString("url");
item.setUrl(feedUrl);*/
timeLineItems.add(item);
}
// notify data changes to list adapater
adapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
//This method will get data from the web API
private void getData() {
//Adding the method to the queue by calling the method getDataFromServer
getTimeLineData(token, String.valueOf(requestCount));
//Incrementing the request counter
requestCount++;
}
//This method would check that the recyclerview scroll has reached the bottom or not
private boolean isLastItemDisplaying(RecyclerView recyclerView) {
if (recyclerView.getAdapter().getItemCount() != 0) {
int lastVisibleItemPosition = ((LinearLayoutManager) recyclerView.getLayoutManager()).findLastCompletelyVisibleItemPosition();
if (lastVisibleItemPosition != RecyclerView.NO_POSITION && lastVisibleItemPosition == recyclerView.getAdapter().getItemCount() - 1)
return true;
}
return false;
}
#Override
public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
//Ifscrolled at last then
if (isLastItemDisplaying(listView)) {
//Calling the method getdata again
getData();
}
}
public void buttonClickEvent() {
btnPost.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (isInternetPresent) {
String text = txtStatusBox.getText().toString().trim();
if (!text.isEmpty()) {
if (thumbnail != null) {
String image = getStringImage(thumbnail);
JSONObject student2 = new JSONObject();
try {
student2.put("size", "1000");
student2.put("type", "image/jpeg");
student2.put("data", image);
} catch (JSONException e) {
e.printStackTrace();
}
addStory(text, token, String.valueOf(student2));
} else {
addStory(text, token, "");
}
} else {
Toast.makeText(TimelineActivity.this, "Please add some text or image.", Toast.LENGTH_SHORT).show();
}
} else {
final SweetAlertDialog alert = new SweetAlertDialog(TimelineActivity.this, SweetAlertDialog.WARNING_TYPE);
alert.setTitleText("No Internet");
alert.setContentText("No connectivity. Please check your internet.");
alert.show();
}
}
});
btnCancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
txtStatusBox.setText("");
imgImageUpload.setImageBitmap(null);
imgImageUpload.setBackgroundResource(R.drawable.image);
Toast.makeText(TimelineActivity.this, message, Toast.LENGTH_SHORT).show();
slidingUpPanelLayout.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED);
}
});
imgImageUpload.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
selectImage();
}
});
/*fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
myDialogFragment.show(getFragmentManager(), "MyDialogFragment");
//Toast.makeText(TimelineActivity.this, "Floating Button", Toast.LENGTH_SHORT).show();
}
});*/
}
private void addStory(final String story_text, final String token, final String image) {
// Tag used to cancel the request
String tag_string_req = "req_register";
pDialog.setMessage("Please wait ...");
showDialog();
StringRequest strReq = new StringRequest(Request.Method.POST, AppConfig.addStory, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
hideDialog();
try {
JSONObject jObj = new JSONObject(response);
boolean error = jObj.getBoolean("status");
message = jObj.getString("message");
if (error) {
txtStatusBox.setText("");
imgImageUpload.setImageBitmap(null);
imgImageUpload.setBackgroundResource(R.drawable.image);
Toast.makeText(TimelineActivity.this, message, Toast.LENGTH_SHORT).show();
slidingUpPanelLayout.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED);
} else {
// Error occurred in registration. Get the error
// message
String errorMsg = jObj.getString("message");
Toast.makeText(TimelineActivity.this, errorMsg, Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(TimelineActivity.this, "Oops something went wrong...", Toast.LENGTH_LONG).show();
hideDialog();
}
}) {
#Override
protected Map<String
, String> getParams() {
// Posting params to register url
Map<String, String> params = new HashMap<String, String>();
params.put("my_token", token);
params.put("story_text", story_text);
params.put("image", image);
return params;
}
};
// Adding request to request queue
AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
}
private void showDialog() {
if (!pDialog.isShowing())
pDialog.show();
}
private void hideDialog() {
if (pDialog.isShowing())
pDialog.dismiss();
}
}
TimeLineListAdapter.java
public class TimeLineListAdapter extends RecyclerView.Adapter<TimeLineListAdapter.ViewHolder> {
private List<TimeLineItem> timeLineItems;
String message, storyId, token;
private Context context;
ImageLoader imageLoader = AppController.getInstance().getImageLoader();
public TimeLineListAdapter(List<TimeLineItem> timeLineItems, Context context) {
super();
this.context = context;
this.timeLineItems = timeLineItems;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.timeline_item, parent, false);
ViewHolder viewHolder = new ViewHolder(v);
return viewHolder;
}
#Override
public void onBindViewHolder(ViewHolder holder, final int position) {
//Getting the particular item from the list
TimeLineItem item = timeLineItems.get(position);
if (item.getTotalLikes().equals("0")){
holder.txtLike.setText("");
}else {
holder.txtLike.setText(item.getTotalLikes());
}
if (item.getTotalComment().equals("0")){
holder.txtComment.setText("");
}else {
holder.txtComment.setText("("+item.getTotalComment()+")");
}
if (item.getIsLike() == 0){
}else {
holder.imageLike.setImageBitmap(null);
holder.imageLike.setBackgroundResource(R.drawable.islike);
holder.txtLike.setTextColor(Color.parseColor("#3498db"));
}
holder.name.setText(item.getName() + " " + item.getLname());
/*Long.parseLong(item.getTimeStamp()),
System.currentTimeMillis(), DateUtils.SECOND_IN_MILLIS);*/
holder.timestamp.setText(item.getTimeStamp());
// Chcek for empty status message
if (!TextUtils.isEmpty(item.getStatus())) {
holder.statusMsg.setText(item.getStatus());
holder.statusMsg.setVisibility(View.VISIBLE);
} else {
// status is empty, remove from view
holder.statusMsg.setVisibility(View.GONE);
}
// Checking for null feed url
if (item.getUrl() != null) {
holder.url.setText(Html.fromHtml("<a href=\"" + item.getUrl() + "\">"
+ item.getUrl() + "</a> "));
// Making url clickable
holder.url.setMovementMethod(LinkMovementMethod.getInstance());
holder.url.setVisibility(View.VISIBLE);
} else {
// url is null, remove from the view
holder.url.setVisibility(View.GONE);
}
// user profile pic
holder.profilePic.setImageUrl(item.getProfilePic(), imageLoader);
// Feed image
if (item.getImge() != null) {
holder.feedImageView.setImageUrl(item.getImge(), imageLoader);
holder.feedImageView.setVisibility(View.VISIBLE);
holder.feedImageView
.setResponseObserver(new TimeLineImageView.ResponseObserver() {
#Override
public void onError() {
}
#Override
public void onSuccess() {
}
});
} else {
holder.feedImageView.setVisibility(View.GONE);
}
}
#Override
public int getItemCount() {
return timeLineItems.size();
}
class ViewHolder extends RecyclerView.ViewHolder{
TextView name, timestamp, statusMsg, url, txtLike, txtComment, txtCommentLabel;
NetworkImageView profilePic;
TimeLineImageView feedImageView;
ImageView imageLike;
//Initializing Views
public ViewHolder(View itemView) {
super(itemView);
name = (TextView) itemView.findViewById(R.id.name);
timestamp = (TextView) itemView.findViewById(R.id.timestamp);
statusMsg = (TextView) itemView.findViewById(R.id.txtStatusMsg);
url = (TextView) itemView.findViewById(R.id.txtUrl);
profilePic = (NetworkImageView) itemView.findViewById(R.id.profilePic);
feedImageView = (TimeLineImageView) itemView.findViewById(R.id.feedImage1);
imageLike = (ImageView) itemView.findViewById(R.id.imgLike);
txtLike = (TextView) itemView.findViewById(R.id.txtLike);
txtComment = (TextView) itemView.findViewById(R.id.txtComment);
txtCommentLabel = (TextView) itemView.findViewById(R.id.txtCommentLabel);
}
}
You have to notifiy dataset changed on listview when new feed is added so there are two things you can do :
Create a new TimeLineItem item when new feed is entered and add new item to it like this :
`
item.setStatus("New Status");
item.setProfilePic("New Profile Pic");
item.setTimeStamp("New TimeStamp");
item.setIsLike("True");
item.setTotalLikes("1000");
item.setTotalComment("2");
`
and then use timeLineItems.add(item) to add new item to ArrayList and call adapter.notifyDataSetChanged(); to get it in view .
2. Again create volley request and it will do it automatically but this is slower then above example.
If you have any query please ask .
You have to set this new list to the adapter.
You can create a setDataSet() method in your adapter and call it before notifydatasetchanged
Add below method in adapter
public void setDataSet(List<TimeLineItem> timeLineItems) {
this.timeLineItems = timeLineItems;
}
and call it before notifydatasetChanged like this:
adapter.setDataSet(timeLineItems);
adapter.notifyDataSetChanged();
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
}
I have literally been searching for this for weeks. I am a novice java programmer but I have been able to piece together an app that can use a double latitude and longitude hard coded in the same class. It will show a list of current places surrounding those points. I have another separate class with a method that is able to get the current location based on the gps/network but I can't pass the variables created from this second class to the PlaceRequest class. I have looked through all of the tutorials on the above subjects but there isn't anything combining current location and place search results. I have two getters declared but can't call the variables in these. Again sort of a rookie so may be an easy fix. Any ideas?
Update - Here is my code so far:
GooglePlaceActivity.java
public class GooglePlaceActivity extends Activity {
/** Called when the activity is first created. */
Button btn1;
TextView txt1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.main);
btn1 = (Button)findViewById(R.id.button1);
txt1 = (TextView)findViewById(R.id.textView1);
btn1.setOnClickListener(l);
}
private class SearchSrv extends AsyncTask<Void, Void, PlacesList>{
#Override
protected PlacesList doInBackground(Void... params) {
PlacesList pl = null;
try {
pl = new PlaceRequest().performSearch();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return pl;
}
#Override
protected void onPostExecute(PlacesList result) {
String text = "Result \n";
if (result!=null){
for(Place place: result.results){
text = text + place.name +"\n";
}
txt1.setText(text);
}
setProgressBarIndeterminateVisibility(false);
}
}
View.OnClickListener l = new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
SearchSrv srv = new SearchSrv();
setProgressBarIndeterminateVisibility(true);
srv.execute();
}
};
}
//////////////////////
PlaceRequest.java
public class PlaceRequest {
private static final HttpTransport transport = new ApacheHttpTransport();
private static final String API_KEY = "keyhere";
private static final String LOG_KEY = "GGPlace";
// The different Places API endpoints.
private static final String PLACES_SEARCH_URL = "https://maps.googleapis.com/maps/api/place/search/json?";
private static final String PLACES_AUTOCOMPLETE_URL = "https://maps.googleapis.com/maps/api/place/autocomplete/json?";
private static final String PLACES_DETAILS_URL = "https://maps.googleapis.com/maps/api/place/details/json?";
private static final boolean PRINT_AS_STRING = true;
//double latitude;
//double longitude;
CurrentLocation clo = new CurrentLocation(null);
//clo.onLocationChanged(latitude);
//double longitude = CurrentLocation.getLongitude();
//double latitude = CurrentLocation.getLatitude();
double longi = clo.getLongitude();
double lat = clo.getLatitude();
public PlacesList performSearch() throws Exception {
try {
//CurrentLocation currlo = new CurrentLocation();
//double lat = currlo.getLatitude();
//double longi = currlo.getLongitude();
Log.v(LOG_KEY, "Start Search");
GenericUrl reqUrl = new GenericUrl(PLACES_SEARCH_URL);
reqUrl.put("key", API_KEY);
//reqUrl.put("location", latitude + "," + longitude);
//reqUrl.put("location", getLatitude(latitude) + "," + getLongitude());
reqUrl.put("location", lat + "," + longi);
reqUrl.put("radius", 1600);
reqUrl.put("types", "food");
reqUrl.put("sensor", "false");
Log.v(LOG_KEY, "url= " + reqUrl);
HttpRequestFactory httpRequestFactory = createRequestFactory(transport);
HttpRequest request = httpRequestFactory.buildGetRequest(reqUrl);
Log.v(LOG_KEY, request.execute().parseAsString());
PlacesList places = request.execute().parseAs(PlacesList.class);
Log.v(LOG_KEY, "STATUS = " + places.status);
for (Place place : places.results) {
Log.v(LOG_KEY, place.name);
}
return places;
} catch (HttpResponseException e) {
Log.v(LOG_KEY, e.getResponse().parseAsString());
throw e;
}
catch (IOException e) {
// TODO: handle exception
throw e;
}
}
public static HttpRequestFactory createRequestFactory(final HttpTransport transport) {
return transport.createRequestFactory(new HttpRequestInitializer() {
public void initialize(HttpRequest request) {
GoogleHeaders headers = new GoogleHeaders();
headers.setApplicationName("Google-Places-DemoApp");
request.setHeaders(headers);
JsonHttpParser parser = new JsonHttpParser(new JacksonFactory()) ;
//JsonHttpParser.builder(new JacksonFactory());
//parser.jsonFactory = new JacksonFactory();
request.addParser(parser);
}
});
}
}
/////////////
CurrentLocation.java
public class CurrentLocation {
private static final long MINIMUM_DISTANCE_CHANGE_FOR_UPDATES = 1; // in Meters
private static final long MINIMUM_TIME_BETWEEN_UPDATES = 1000; // in Milliseconds
LocationManager locationManager ;
double latitude=0;
double longitude=0;
public CurrentLocation(Context ctxt) {
super();
locationManager = (LocationManager) ctxt.getSystemService(Context.LOCATION_SERVICE);
// Register the listener with the Location Manager to receive location updates
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
MINIMUM_TIME_BETWEEN_UPDATES,
MINIMUM_DISTANCE_CHANGE_FOR_UPDATES,
new LocationListener() {
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {}
#Override
public void onProviderEnabled(String provider) {}
#Override
public void onProviderDisabled(String provider) {}
#Override
public void onLocationChanged(Location location) {
longitude = location.getLongitude();
latitude = location.getLatitude();
}
});
}
public double getLatitude() {
return latitude;
}
public double getLongitude() {
return longitude;
}
}
Edit: After looking your complete code, I see a few fundamental design flaws so I'm going to show you how I did it and you can adapt it to your program flow. Please keep in mind that this example is vastly simplified from my original, but it should be enough to get you going.
First, the CurrentLocation.java file. My design decision for wrapping this in a Future was so that I can re-use it in multiple activities with the added bonus of killing it when necessary.
public class CurrentLocation implements Callable<Location> {
private static final String TAG = "CurrentLocation";
private Context context;
private LocationManager lm;
private Criteria criteria;
private Location bestResult;
private boolean locationListenerWorking;
public CurrentLocation(Context context) {
lm = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
this.context = context;
criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
bestResult = null;
locationListenerWorking = false;
}
public Location call() {
return getLoc();
}
private Location getLoc() {
String provider = lm.getBestProvider(criteria, true);
if (provider != null) {
Log.d(TAG, "Using provider: " +provider);
locationListenerWorking = true;
lm.requestLocationUpdates(provider,
0,
0,
singeUpdateListener,
context.getMainLooper());
} else {
Log.w(TAG, "Couldn't find a location provider");
return null;
}
while (locationListenerWorking) {
// Check for the interrupt signal - terminate if necessary
if (Thread.currentThread().isInterrupted()) {
Log.i(TAG, "User initiated interrupt (cancel signal)");
cleanup();
break;
}
try {
// ghetto implementation of a busy wait...
Thread.sleep(500); // Sleep for half a second
} catch (Exception e) {
Log.d(TAG, "Thread interrupted..");
cleanup();
break;
}
}
return bestResult;
}
private void cleanup() {
if (lm != null) {
Log.d(TAG, "Location manager not null - cleaning up");
lm.removeUpdates(singeUpdateListener);
} else {
Log.d(TAG, "Location manager was NULL - no cleanup necessary");
}
}
/**
* This one-off {#link LocationListener} simply listens for a single location
* update before unregistering itself. The one-off location update is
* returned via the {#link LocationListener} specified in {#link
* setChangedLocationListener}.
*/
private LocationListener singeUpdateListener = new LocationListener() {
public void onLocationChanged(Location location) {
Log.d(TAG, "Got a location update");
if (location == null) {
Log.d(TAG, "Seems as if we got a null location");
} else {
bestResult = location;
}
cleanup();
locationListenerWorking = false;
}
public void onStatusChanged(String provider, int status, Bundle extras) {}
public void onProviderEnabled(String provider) {}
public void onProviderDisabled(String provider) {}
};
}
Then in your calling class (i.e. where you need the lat/lon coordinates - you want to do this from an Activity):
private class GetLocationTask extends AsyncTask <Void, Void, Location> {
private Future<Location> future;
private ExecutorService executor = new ScheduledThreadPoolExecutor(5);
private boolean cancelTriggered = false;
protected void onPreExecute() {
Log.d(TAG, "Starting location get...");
}
public Location doInBackground(Void... arg) {
CurrentLocation currLoc = new CurrentLocation(getApplicationContext());
future = executor.submit(currLoc);
long LOCATION_TIMEOUT = 20000; // ms = 20 sec
try {
// return future.get(Constants.LOCATION_TIMEOUT, TimeUnit.MILLISECONDS);
return future.get(LOCATION_TIMEOUT, TimeUnit.MILLISECONDS);
} catch (Exception e) {
Log.w(TAG, "Location get timed out");
future.cancel(true);
return null;
}
}
public boolean killTask() {
cancelTriggered = true;
boolean futureCancelRes = future.cancel(true);
this.cancel(true);
Log.d(TAG, "Result of cancelling task: " +futureCancelRes);
return futureCancelRes;
}
protected void onPostExecute(Location res) {
if (cancelTriggered) {
Log.d(TAG, "User initiated cancel - this is okay");
cancelTriggered = false;
} else if (res == null) {
Log.d(TAG, "Could not get a location result");
} else {
double lat = res.getLatitude();
double lon = res.getLongitude();
Log.d(TAG, "Latitude: " +lat);
Log.d(TAG, "Longitude: " +lon);
}
}
}
Finally to wrap things up, here's how you call it:
GetLocationTask t = new GetLocationTask();
t.execute();
And if you need to kill the location update for whatever reason (if your user switches out of your activity, etc), this will kill the AsyncTask as well as the associated Future task.
t.killTask();
P.S. You may want to get your API keys changed and edit it out of your post.