I am using openweathermap to parse weather information, it works fine without the city, but when I try to fetch city, it force closes. How do I fix this? been searching for hours but no luck.
#Override
protected void onPostExecute(Weather weather) {
super.onPostExecute(weather);
if (weather.iconData != null && weather.iconData.length > 0) {
Bitmap img = BitmapFactory.decodeByteArray(weather.iconData, 0, weather.iconData.length);
imgView.setImageBitmap(img);
}
cityText.setText(weather.location.getCity() + "," + weather.location.getCountry());
condDescr
.setText(weather.currentCondition.getCondition() + "(" + weather.currentCondition.getDescr() + ")");
temp.setText("" + Math.round((weather.temperature.getTemp() - 273.15)) + "�C");
hum.setText("" + weather.currentCondition.getHumidity() + "%");
press.setText("" + weather.currentCondition.getPressure() + " hPa");
windSpeed.setText("" + weather.wind.getSpeed() + " mps");
windDeg.setText("" + weather.wind.getDeg() + "�");
}
}
public class Location implements Serializable {
private float longitude;
private float latitude;
private long sunset;
private long sunrise;
private String country;
private String city;
...
public String getCountry() {
return country;
}
public String getCity() {
return city;
}
here is my log-
FATAL EXCEPTION: main
Process: com.survivingwithandroid.weatherapp, PID: 2057
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.myweather.weatherapp.model.Location.getCity()' on a null object reference
at com.survivingwithandroid.weatherapp.MainActivity$JSONWeatherTask.onPostExecute(MainActivity.java:114)
UPDATE
JSONWeatherParser.java
package com.survivingwithandroid.weatherapp;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.survivingwithandroid.weatherapp.model.Location;
import com.survivingwithandroid.weatherapp.model.Weather;
public class JSONWeatherParser {
public static Weather getWeather(String data) throws JSONException {
Weather weather = new Weather();
// We create out JSONObject from the data
JSONObject jObj = new JSONObject(data);
// We start extracting the info
Location loc = new Location();
JSONObject coordObj = getObject("coord", jObj);
loc.setLatitude(getFloat("lat", coordObj));
loc.setLongitude(getFloat("lon", coordObj));
JSONObject sysObj = getObject("sys", jObj);
loc.setCountry(getString("country", sysObj));
loc.setSunrise(getInt("sunrise", sysObj));
loc.setSunset(getInt("sunset", sysObj));
loc.setCity(getString("name", jObj));
weather.location = loc;
// We get weather info (This is an array)
JSONArray jArr = jObj.getJSONArray("weather");
// We use only the first value
JSONObject JSONWeather = jArr.getJSONObject(0);
weather.currentCondition.setWeatherId(getInt("id", JSONWeather));
weather.currentCondition.setDescr(getString("description", JSONWeather));
weather.currentCondition.setCondition(getString("main", JSONWeather));
weather.currentCondition.setIcon(getString("icon", JSONWeather));
JSONObject mainObj = getObject("main", jObj);
weather.currentCondition.setHumidity(getInt("humidity", mainObj));
weather.currentCondition.setPressure(getInt("pressure", mainObj));
weather.temperature.setMaxTemp(getFloat("temp_max", mainObj));
weather.temperature.setMinTemp(getFloat("temp_min", mainObj));
weather.temperature.setTemp(getFloat("temp", mainObj));
// Wind
JSONObject wObj = getObject("wind", jObj);
weather.wind.setSpeed(getFloat("speed", wObj));
weather.wind.setDeg(getFloat("deg", wObj));
// Clouds
JSONObject cObj = getObject("clouds", jObj);
weather.clouds.setPerc(getInt("all", cObj));
// We download the icon to show
return weather;
}
private static JSONObject getObject(String tagName, JSONObject jObj) throws JSONException {
JSONObject subObj = jObj.getJSONObject(tagName);
return subObj;
}
private static String getString(String tagName, JSONObject jObj) throws JSONException {
return jObj.getString(tagName);
}
private static float getFloat(String tagName, JSONObject jObj) throws JSONException {
return (float) jObj.getDouble(tagName);
}
private static int getInt(String tagName, JSONObject jObj) throws JSONException {
return jObj.getInt(tagName);
}
}
MainActivity.java
package com.survivingwithandroid.weatherapp;
import org.json.JSONException;
import com.survivingwithandroid.weatherapp.model.Weather;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.widget.ImageView;
import android.widget.TextView;
public class MainActivity extends Activity {
private TextView cityText;
private TextView condDescr;
private TextView temp;
private TextView press;
private TextView windSpeed;
private TextView windDeg;
private TextView hum;
private ImageView imgView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String city = "London,UK";
cityText = (TextView) findViewById(R.id.cityText);
condDescr = (TextView) findViewById(R.id.condDescr);
temp = (TextView) findViewById(R.id.temp);
hum = (TextView) findViewById(R.id.hum);
press = (TextView) findViewById(R.id.press);
windSpeed = (TextView) findViewById(R.id.windSpeed);
windDeg = (TextView) findViewById(R.id.windDeg);
imgView = (ImageView) findViewById(R.id.condIcon);
JSONWeatherTask task = new JSONWeatherTask();
task.execute(new String[] { city });
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
private class JSONWeatherTask extends AsyncTask<String, Void, Weather> {
#Override
protected Weather doInBackground(String... params) {
Weather weather = new Weather();
String data = ((new WeatherHttpClient()).getWeatherData(params[0]));
try {
weather = JSONWeatherParser.getWeather(data);
// Let's retrieve the icon
weather.iconData = ((new WeatherHttpClient()).getImage(weather.currentCondition.getIcon()));
} catch (JSONException e) {
e.printStackTrace();
}
return weather;
}
#Override
protected void onPostExecute(Weather weather) {
super.onPostExecute(weather);
if (weather.iconData != null && weather.iconData.length > 0) {
Bitmap img = BitmapFactory.decodeByteArray(weather.iconData, 0, weather.iconData.length);
imgView.setImageBitmap(img);
}
cityText.setText(weather.location.getCity() + "," + weather.location.getCountry());
condDescr
.setText(weather.currentCondition.getCondition() + "(" + weather.currentCondition.getDescr() + ")");
temp.setText("" + Math.round((weather.temperature.getTemp() - 273.15)) + "�C");
hum.setText("" + weather.currentCondition.getHumidity() + "%");
press.setText("" + weather.currentCondition.getPressure() + " hPa");
windSpeed.setText("" + weather.wind.getSpeed() + " mps");
windDeg.setText("" + weather.wind.getDeg() + "�");
}
}
}
WeatherHttpClient.java
package com.survivingwithandroid.weatherapp;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class WeatherHttpClient {
private static String BASE_URL = "http://api.openweathermap.org/data/2.5/weather?q=";
private static String IMG_URL = "http://openweathermap.org/img/w/";
public String getWeatherData(String location) {
HttpURLConnection con = null;
InputStream is = null;
try {
con = (HttpURLConnection) (new URL(BASE_URL + location)).openConnection();
con.setRequestMethod("GET");
con.setDoInput(true);
con.setDoOutput(true);
con.connect();
// Let's read the response
StringBuffer buffer = new StringBuffer();
is = con.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line = null;
while ((line = br.readLine()) != null)
buffer.append(line + "\r\n");
is.close();
con.disconnect();
return buffer.toString();
} catch (Throwable t) {
t.printStackTrace();
} finally {
try {
is.close();
} catch (Throwable t) {
}
try {
con.disconnect();
} catch (Throwable t) {
}
}
return null;
}
public byte[] getImage(String code) {
HttpURLConnection con = null;
InputStream is = null;
try {
con = (HttpURLConnection) (new URL(IMG_URL + code)).openConnection();
con.setRequestMethod("GET");
con.setDoInput(true);
con.setDoOutput(true);
con.connect();
// Let's read the response
is = con.getInputStream();
byte[] buffer = new byte[1024];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while (is.read(buffer) != -1)
baos.write(buffer);
return baos.toByteArray();
} catch (Throwable t) {
t.printStackTrace();
} finally {
try {
is.close();
} catch (Throwable t) {
}
try {
con.disconnect();
} catch (Throwable t) {
}
}
return null;
}
}
Location.java
package com.survivingwithandroid.weatherapp.model;
import java.io.Serializable;
public class Location implements Serializable {
private float longitude;
private float latitude;
private long sunset;
private long sunrise;
private String country;
private String city;
public float getLongitude() {
return longitude;
}
public void setLongitude(float longitude) {
this.longitude = longitude;
}
public float getLatitude() {
return latitude;
}
public void setLatitude(float latitude) {
this.latitude = latitude;
}
public long getSunset() {
return sunset;
}
public void setSunset(long sunset) {
this.sunset = sunset;
}
public long getSunrise() {
return sunrise;
}
public void setSunrise(long sunrise) {
this.sunrise = sunrise;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}
Weather.java
package com.survivingwithandroid.weatherapp.model;
public class Weather {
public Location location;
public CurrentCondition currentCondition = new CurrentCondition();
public Temperature temperature = new Temperature();
public Wind wind = new Wind();
public Rain rain = new Rain();
public Snow snow = new Snow();
public Clouds clouds = new Clouds();
public byte[] iconData;
public class CurrentCondition {
private int weatherId;
private String condition;
private String descr;
private String icon;
private float pressure;
private float humidity;
public int getWeatherId() {
return weatherId;
}
public void setWeatherId(int weatherId) {
this.weatherId = weatherId;
}
public String getCondition() {
return condition;
}
public void setCondition(String condition) {
this.condition = condition;
}
public String getDescr() {
return descr;
}
public void setDescr(String descr) {
this.descr = descr;
}
public String getIcon() {
return icon;
}
public void setIcon(String icon) {
this.icon = icon;
}
public float getPressure() {
return pressure;
}
public void setPressure(float pressure) {
this.pressure = pressure;
}
public float getHumidity() {
return humidity;
}
public void setHumidity(float humidity) {
this.humidity = humidity;
}
}
public class Temperature {
private float temp;
private float minTemp;
private float maxTemp;
public float getTemp() {
return temp;
}
public void setTemp(float temp) {
this.temp = temp;
}
public float getMinTemp() {
return minTemp;
}
public void setMinTemp(float minTemp) {
this.minTemp = minTemp;
}
public float getMaxTemp() {
return maxTemp;
}
public void setMaxTemp(float maxTemp) {
this.maxTemp = maxTemp;
}
}
public class Wind {
private float speed;
private float deg;
public float getSpeed() {
return speed;
}
public void setSpeed(float speed) {
this.speed = speed;
}
public float getDeg() {
return deg;
}
public void setDeg(float deg) {
this.deg = deg;
}
}
public class Rain {
private String time;
private float ammount;
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public float getAmmount() {
return ammount;
}
public void setAmmount(float ammount) {
this.ammount = ammount;
}
}
public class Snow {
private String time;
private float ammount;
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public float getAmmount() {
return ammount;
}
public void setAmmount(float ammount) {
this.ammount = ammount;
}
}
public class Clouds {
private int perc;
public int getPerc() {
return perc;
}
public void setPerc(int perc) {
this.perc = perc;
}
}
}
Please find attached code for fetching location using LocationManager.
private GoogleApiClient mGoogleApiClient;
private Context mContext;
#SuppressWarnings({"MissingPermission"})
public void getLocation(Context context) {
mContext = context;
LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
if (locationManager != null) {
// getting GPS status
boolean isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
// getting network status
boolean isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnabled && !isNetworkEnabled) {
//Show message alert for gps enable
} else {
mGoogleApiClient = new GoogleApiClient.Builder(context)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
}
}
}
After that, you will get callback on onConnected method and you get location from there
#Override
public void onConnected(#Nullable Bundle bundle) {
Location location = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
if (location != null) {
double lat= location.getLatitude();
double lang= location.getLongitude());
} else {
//No location found message
}
mGoogleApiClient.disconnect();
}
Related
I'm trying to display data in my fragment & activity class from a Weather API using retrofit but on running the app, it displays nothing and meanwhile shows no error at runtime. I'm suspecting it will be due to a wrong connection of my retrofit network setup and I have no clue as to where the fault is, I need help, please.
I added Internet Permission in the Manifest
I also tried running the key on my browser online e.g https://api.openweathermap.org/data/2.5/onecall?lat=9.0765&lon=7.3986&exclude=alert,hourly,daily,minutely&appid= and it works but doesn't display data on my app
My codes are below:
FirstFragment.java
public class FirstFragment extends Fragment {
public static String BaseUrl = "http://api.openweathermap.org/";
public static String AppId = "(My App key)";
public static String lat = "9.0574";
public static String lon = "7.4898";
// User current temperature, current condition, sunrise, sunset, temperature, pressure, humidity, wind_speed, visibility, UV Index
TextView current_temp, current_output, rise_time, set_time, temp_out, Press_out, Humid_out, Ws_out, Visi_out, UV_out;
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
public FirstFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment SecondFragment.
*/
// TODO: Rename and change types and number of parameters
public static FirstFragment newInstance(String param1, String param2) {
FirstFragment fragment = new FirstFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_first, container, false);
current_temp = rootView.findViewById(R.id.textView10);
current_output = rootView.findViewById(R.id.textView11);
rise_time = rootView.findViewById(R.id.textView25);
set_time = rootView.findViewById(R.id.textView26);
temp_out = rootView.findViewById(R.id.textView28);
Press_out = rootView.findViewById(R.id.textView29);
Humid_out = rootView.findViewById(R.id.textView30);
Ws_out = rootView.findViewById(R.id.textView33);
Visi_out = rootView.findViewById(R.id.textView34);
UV_out = rootView.findViewById(R.id.textView35);
Retrofit retrofit = new Retrofit.Builder().baseUrl(BaseUrl).addConverterFactory(GsonConverterFactory.create()).build();
WeatherService service = retrofit.create(WeatherService.class);
Call<WeatherResponse> call = service.getCurrentWeatherData(lat, lon, AppId);
call.enqueue(new Callback<WeatherResponse>() {
#Override
public void onResponse(#NonNull Call<WeatherResponse> call, #NonNull Response<WeatherResponse> response) {
if (response.code() == 200) {
WeatherResponse weatherResponse = response.body();
assert weatherResponse != null;
assert response.body() != null;
current_temp.setText(getString(R.string.blank, response.body().getCurrent().getTemp() + " ℃"));
current_output.setText(response.body().getCurrent().getWeather().get(0).getDescription());
rise_time.setText(getString(R.string.blank, response.body().getCurrent().getSunrise() + " AM"));
set_time.setText(getString(R.string.blank, response.body().getCurrent().getSunset() + " PM"));
temp_out.setText(getString(R.string.blank, response.body().getCurrent().getTemp() + " ℃"));
Press_out.setText(getString(R.string.blank, response.body().getCurrent().getPressure() + " hpa"));
Humid_out.setText(getString(R.string.blank, response.body().getCurrent().getHumidity() + " %"));
Ws_out.setText(getString(R.string.blank, response.body().getCurrent().getWindSpeed() + " Km/h"));
Visi_out.setText(getString(R.string.blank, response.body().getCurrent().getVisibility() + " m"));
}
}
#Override
public void onFailure(#NonNull Call<WeatherResponse> call, #NonNull Throwable t) {
t.printStackTrace();
}
});
return rootView;
}
}
HomeActivity.java
public class HomeActivity extends AppCompatActivity {
public static String BaseUrl = "http://api.openweathermap.org/";
public static String AppId = "(My App key)";
public static String lat = "9.0574";
public static String lon = "7.4898";
// User Timezone name, current time
TextView time_zone, time_field;
ConstraintLayout constraintLayout;
public static int count=0;
int[] drawable =new int[]{R.drawable.dubai,R.drawable.central_bank_of_nigeria,R.drawable.eiffel_tower,R.drawable.hong_kong,R.drawable.statue_of_liberty};
Timer _t;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
time_zone = findViewById(R.id.textView9);
time_field = findViewById(R.id.textView4);
BottomNavigationView bottomNavigationView = findViewById(R.id.bottomNavigationView);
NavController navController = Navigation.findNavController(this, R.id.fragment);
NavigationUI.setupWithNavController(bottomNavigationView, navController);
Retrofit retrofit = new Retrofit.Builder().baseUrl(BaseUrl).addConverterFactory(GsonConverterFactory.create()).build();
WeatherService service = retrofit.create(WeatherService.class);
Call<WeatherResponse> call = service.getCurrentWeatherData(lat, lon, AppId);
call.enqueue(new Callback<WeatherResponse>() {
#Override
public void onResponse(#NonNull Call<WeatherResponse> call, #NonNull Response<WeatherResponse> response) {
if (response.code() == 200) {
WeatherResponse weatherResponse = response.body();
assert weatherResponse != null;
assert response.body() != null;
time_zone.setText(response.body().getTimezone());
time_field.setText(response.body().getCurrent().getDt());
constraintLayout = findViewById(R.id.layout);
constraintLayout.setBackgroundResource(R.drawable.dubai);
_t = new Timer();
_t.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
// run on ui thread
runOnUiThread(() -> {
if (count < drawable.length) {
constraintLayout.setBackgroundResource(drawable[count]);
count = (count + 1) % drawable.length;
}
});
}
}, 5000, 5000);
}
}
#Override
public void onFailure(#NotNull Call<WeatherResponse> call, #NotNull Throwable t) {
}
});
}
}
My Interface
public interface WeatherService {
#GET("data/2.5/weather?")
Call<WeatherResponse> getCurrentWeatherData(#Query("lat") String lat, #Query("lon") String lon, #Query("APPID") String app_id);
}
EDIT
Now it shows java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Integer com.tex.lightweatherforecast.first.Current.getDt()' on a null object reference on runtime after i changed HTTP to https
My Current class:
public class Current {
#SerializedName("dt")
#Expose
private Integer dt;
#SerializedName("sunrise")
#Expose
private Integer sunrise;
#SerializedName("sunset")
#Expose
private Integer sunset;
#SerializedName("temp")
#Expose
private Double temp;
#SerializedName("feels_like")
#Expose
private Double feelsLike;
#SerializedName("pressure")
#Expose
private Integer pressure;
#SerializedName("humidity")
#Expose
private Integer humidity;
#SerializedName("dew_point")
#Expose
private Double dewPoint;
#SerializedName("uvi")
#Expose
private Double uvi;
#SerializedName("clouds")
#Expose
private Integer clouds;
#SerializedName("visibility")
#Expose
private Integer visibility;
#SerializedName("wind_speed")
#Expose
private Double windSpeed;
#SerializedName("wind_deg")
#Expose
private Integer windDeg;
#SerializedName("weather")
#Expose
private List<Weather> weather = null;
public Integer getDt() {
return dt;
}
public void setDt(Integer dt) {
this.dt = dt;
}
public Integer getSunrise() {
return sunrise;
}
public void setSunrise(Integer sunrise) {
this.sunrise = sunrise;
}
public Integer getSunset() {
return sunset;
}
public void setSunset(Integer sunset) {
this.sunset = sunset;
}
public Double getTemp() {
return temp;
}
public void setTemp(Double temp) {
this.temp = temp;
}
public Double getFeelsLike() {
return feelsLike;
}
public void setFeelsLike(Double feelsLike) {
this.feelsLike = feelsLike;
}
public Integer getPressure() {
return pressure;
}
public void setPressure(Integer pressure) {
this.pressure = pressure;
}
public Integer getHumidity() {
return humidity;
}
public void setHumidity(Integer humidity) {
this.humidity = humidity;
}
public Double getDewPoint() {
return dewPoint;
}
public void setDewPoint(Double dewPoint) {
this.dewPoint = dewPoint;
}
public Double getUvi() {
return uvi;
}
public void setUvi(Double uvi) {
this.uvi = uvi;
}
public Integer getClouds() {
return clouds;
}
public void setClouds(Integer clouds) {
this.clouds = clouds;
}
public Integer getVisibility() {
return visibility;
}
public void setVisibility(Integer visibility) {
this.visibility = visibility;
}
public Double getWindSpeed() {
return windSpeed;
}
public void setWindSpeed(Double windSpeed) {
this.windSpeed = windSpeed;
}
public Integer getWindDeg() {
return windDeg;
}
public void setWindDeg(Integer windDeg) {
this.windDeg = windDeg;
}
public List<Weather> getWeather() {
return weather;
}
public void setWeather(List<Weather> weather) {
this.weather = weather;
}
}
I fixed the error by changing the weather? to onecall? in my interface call
Excuse my ignorance but I am very new to Android Studio and Java. I have adapted a lot the following code from another course to my needs, but it is not working.
I am trying to add custom markers to my Google maps Android app. Lhe locations of the markers are stored as geopoints on firebase. I have attempted to do so using cluster marker. The app crashes immediately when I attempt to run it with the following shortened error.
java.lang.NullPointerException: Attempt to invoke virtual method 'com.google.firebase.firestore.CollectionReference com.google.firebase.firestore.FirebaseFirestore.collection(java.lang.String)' on a null object reference
at com.codingwithmitch.googlemaps2018.ui.MapsActivity.addMapMarkers(MapsActivity.java:400)
at com.codingwithmitch.googlemaps2018.ui.MapsActivity.onMapReady(MapsActivity.java:486)
I am attempting to display every geopoint in the Stop Locations Collection
I cannot screen shot my firebase but it looks as follows:
Collection
"Stop Locations">>>>>Documents
"KzDQ2sITZ3O8GEoZgp0I",...etc >>>>>Fields
Geo:""
Name:""
avatar:""
loc_id""
If I were to guess I would say the mLocationInformations is empty, probably originating from here >> mLocationInformations.add(document.toObject(LocationInformation.class))
code from MapsActivity:
private ClusterManager<ClusterMarker> mClusterManager;
private MyClusterManagerRenderer mClusterManagerRenderer;
private ArrayList<ClusterMarker> mClusterMarkers = new ArrayList<>();
private LocationInformation mLocationInformation;
private ArrayList<LocationInformation> mLocationInformations = new ArrayList<>();
private void addMapMarkers(){
CollectionReference locationsRef = mDb
.collection("Stop Locations");
locationsRef.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if(task.isSuccessful()){
for (QueryDocumentSnapshot document : task.getResult()) {
mLocationInformations.add(document.toObject(LocationInformation.class));
}
} else {
Log.d(TAG, "Error getting documents: ", task.getException());
}
}
});
if(mMap != null){
if(mClusterManager == null){
mClusterManager = new ClusterManager<ClusterMarker>(this.getApplicationContext(), mMap);
}
if(mClusterManagerRenderer == null){
mClusterManagerRenderer = new MyClusterManagerRenderer(
this,
mMap,
mClusterManager
);
mClusterManager.setRenderer(mClusterManagerRenderer);
}
for(LocationInformation locationInformation: mLocationInformations){
Log.d(TAG, "addMapMarkers: location: " + locationInformation.getGeo().toString());
try{
String snippet = "";
snippet = "";
int avatar = R.drawable.cartman_cop; // set the default avatar
try{
avatar = Integer.parseInt(locationInformation.getAvatar());
}catch (NumberFormatException e){
Log.d(TAG, "addMapMarkers: no avatar ");
}
ClusterMarker newClusterMarker = new ClusterMarker(
new LatLng(locationInformation.getGeo().getLatitude(), locationInformation.getGeo().getLongitude()),
//locationInformation.getName().getUsername(),
locationInformation.getLoc_id(),
snippet,
avatar,
locationInformation.getName()
);
mClusterManager.addItem(newClusterMarker);//adding to the map
mClusterMarkers.add(newClusterMarker);//making an easy access array list
}catch (NullPointerException e){
Log.e(TAG, "addMapMarkers: NullPointerException: " + e.getMessage() );
}
}
mClusterManager.cluster();
}
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
if(mLocationPermissionGranted){
getDeviceLocation();
}else{
Toast.makeText(this, "mLocationpermission denied at origin", Toast.LENGTH_SHORT).show();
}
addMapMarkers();
}
}
LocationInfromation.java
import com.google.firebase.firestore.GeoPoint;
public class LocationInformation {
private String Name;
private GeoPoint Geo;
private String avatar;
private String loc_id;
public LocationInformation(String Name, GeoPoint Geo, String avatar, String loc_id) {
this.Name = Name;
this.Geo = Geo;
this.avatar = avatar;
this.loc_id = loc_id;
}
public LocationInformation(){
}
public String getLoc_id() {
return loc_id;
}
public void setLoc_id(String loc_id) {
this.loc_id = loc_id;
}
public Double getLongitude() {
return longitude;
}
public void setLongitude(Double longitude) {
this.longitude = longitude;
}
private Double longitude;
public String getName() {
return Name;
}
public void setName(String name) {
this.Name = Name;
}
public GeoPoint getGeo() {
return Geo;
}
public void setGeo(GeoPoint geo) {
this.Geo = Geo;
}
public String getAvatar() {
return avatar;
}
public void setAvatar(String avatar) {
this.avatar = avatar;
}
#Override
public String toString() {
return "LocationInformation{" +
"Name=" + Name +
", Geo=" + Geo +
", avatar='" + avatar +
", loc_id='" + loc_id +
'}';
}
}
ClusterMArker.java
import com.google.android.gms.maps.model.LatLng;
import com.google.maps.android.clustering.ClusterItem;
public class ClusterMarker implements ClusterItem {
private LatLng position; // required field
private String title; // required field
private String snippet; // required field
private int iconPicture;
private String name;
public ClusterMarker(LatLng position, String title, String snippet, int iconPicture, String name) {
this.position = position;
this.title = title;
this.snippet = snippet;
this.iconPicture = iconPicture;
this.name = name;
}
public ClusterMarker() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getIconPicture() {
return iconPicture;
}
public void setIconPicture(int iconPicture) {
this.iconPicture = iconPicture;
}
public void setPosition(LatLng position) {
this.position = position;
}
public void setTitle(String title) {
this.title = title;
}
public void setSnippet(String snippet) {
this.snippet = snippet;
}
public LatLng getPosition() {
return position;
}
public String getTitle() {
return title;
}
public String getSnippet() {
return snippet;
}
}
[enter image description here][1]
To solve this, please add the following line of code:
FirebaseFirestore mDb = FirebaseFirestore.getInstance();
Right before this line:
CollectionReference locationsRef = mDb.collection("Stop Locations");
So your FirebaseFirestore object is initialized correctly.
i just want to implement in-app-purchasement into my app. It is a card game with different rulesets. So now want to implement 2 new rulesets which should work as my products and with in-app-purchasement.
I have this:
`go = (Button)findViewById(R.id.go);
go.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
ArrayList skuList = new ArrayList();
skuList.add(inappid);
Bundle querySkus = new Bundle();
querySkus.putStringArrayList("ITEM_ID_LIST", skuList);
Bundle skuDetails;
try {
skuDetails = mservice.getSkuDetails(3, getPackageName(),
"inapp", querySkus);
int response = skuDetails.getInt("RESPONSE_CODE");
if (response == 0) {
ArrayList<String> responseList =
skuDetails.getStringArrayList("DETAILS_LIST");
for (String thisResponse : responseList) {
JSONObject object = new JSONObject(thisResponse);
String sku = object.getString("productId");
String price = object.getString("price");
if (sku.equals(inappid)) {
System.out.println("price " + price);
Bundle buyIntentBundle =
mservice.getBuyIntent(3, getPackageName(), sku,
"inapp",
"blablabla");
PendingIntent pendingIntent =
buyIntentBundle.getParcelable("BUY_INTENT");
startIntentSenderForResult(
pendingIntent.getIntentSender(), 1001,
new Intent(), Integer.valueOf(0),
Integer.valueOf(0), Integer.valueOf(0));
}
}
}
} catch (RemoteException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} catch (IntentSender.SendIntentException e ) {
e.printStackTrace();
}
}
});`
First click on my ruleset works fine. The second click triggers the app to break down with the following error:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.IntentSender android.app.PendingIntent.getIntentSender()' on a null object reference
Do you have some good in-app tutorials or a tipp for me?
Thanks in advance
JD
Here is my BaseClass that i use everywhere i need. Just extend your activity by this BaseInAppPurchaseActivity
Bonus in this class.
You can get what items are available for purchase so user can not get future exception if item is not available like
checkAvailablePurchases(skuList, new OnResultInApp() {
#Override
public void onResult(ArrayList<AvailablePurchase> availablePurchaseArrayList) {
.. logic for showing view with available purchaseItem
}
});
For purchasing an item
purchaseItem(googleInAppId, new OnResultPurchase() {
#Override
public void onSuccess(PurchaseResponseBean purchaseResponseBean, String inAppPurchaseData) {
// your stuff
}
#Override
public void onError() {
showToast(R.string.something_went_wrong);
}
});
Isn't this look pretty clean and nice.
BaseInAppPurchaseActivity.class
package in.kpis.nearyou.base;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.content.ServiceConnection;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import com.android.vending.billing.IInAppBillingService;
import com.google.gson.Gson;
import org.json.JSONException;
import org.json.JSONObject;
import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import in.kpis.nearyou.entity.AvailablePurchase;
import in.kpis.nearyou.entity.Helper;
import in.kpis.nearyou.entity.PurchaseResponseBean;
import in.kpis.nearyou.entity.UserPurchaseItemsBean;
import in.kpis.nearyou.utilities.AppPreference;
import static in.kpis.nearyou.base.BaseInAppPurchaseActivity.ConsuptionResponseType.SUCCESS;
import static in.kpis.nearyou.base.BaseInAppPurchaseActivity.PurchaseStateTypes.PURCHASED;
public class BaseInAppPurchaseActivity extends BaseAppCompatActivity {
private static final String TAG = BaseInAppPurchaseActivity.class.getSimpleName();
private IInAppBillingService mService;
private static final char[] symbols = new char[36];
static {
for (int idx = 0; idx < 10; ++idx)
symbols[idx] = (char) ('0' + idx);
for (int idx = 10; idx < 36; ++idx)
symbols[idx] = (char) ('a' + idx - 10);
}
public void startInAppPurchaseServices() {
Intent serviceIntent = new Intent("com.android.vending.billing.InAppBillingService.BIND");
serviceIntent.setPackage("com.android.vending");
bindService(serviceIntent, mServiceConn, Context.BIND_AUTO_CREATE);
}
private String appPackageName;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
appPackageName = this.getPackageName();
startInAppPurchaseServices();
}
ServiceConnection mServiceConn = new ServiceConnection() {
#Override
public void onServiceDisconnected(ComponentName name) {
mService = null;
}
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
mService = IInAppBillingService.Stub.asInterface(service);
startAsyncForCheckingAvailablePurchase();
}
};
private void startAsyncForCheckingAvailablePurchase() {
if (skuListByNearyouServer != null && skuListByNearyouServer.size() > 0 & onResultInApp != null) {
AvailablePurchaseAsyncTask mAsyncTask = new AvailablePurchaseAsyncTask(appPackageName, skuListByNearyouServer, onResultInApp);
mAsyncTask.execute();
}
}
private ArrayList<String> skuListByNearyouServer = new ArrayList<>();
OnResultInApp onResultInApp;
public void checkAvailablePurchases(ArrayList<String> skuList, OnResultInApp onResultInApp) {
skuListByNearyouServer = skuList;
this.onResultInApp = onResultInApp;
if (mService == null) startInAppPurchaseServices();
else startAsyncForCheckingAvailablePurchase();
}
public interface OnResultPurchase {
void onSuccess(PurchaseResponseBean purchaseResponseBean, String inAppPurchaseData);
void onError();
}
private OnResultPurchase onResultPurchase;
private String itemToPurchaseSku;
public void purchaseItem(String sku, OnResultPurchase onResultPurchase) {
this.onResultPurchase = onResultPurchase;
itemToPurchaseSku = sku;
if (isBillingSupported()) {
String generatedPayload = getPayLoad();
AppPreference.getInstance(BaseInAppPurchaseActivity.this).setDeveloperPayload(generatedPayload);
try {
Bundle buyIntentBundle = mService.getBuyIntent(3, getPackageName(), sku, "inapp", generatedPayload);
PendingIntent pendingIntent = buyIntentBundle.getParcelable("BUY_INTENT");
try {
startIntentSenderForResult(pendingIntent.getIntentSender(), Helper.RESPONSE_CODE, new Intent(), Integer.valueOf(0), Integer.valueOf(0), Integer.valueOf(0));
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == Helper.RESPONSE_CODE) {
if (data != null && data.getExtras() != null && data.getStringExtra("INAPP_DATA_SIGNATURE") != null & data.getStringExtra("INAPP_PURCHASE_DATA") != null) {
int responseCode = data.getIntExtra("RESPONSE_CODE", 0);
String purchaseData = data.getStringExtra("INAPP_PURCHASE_DATA");
String dataSignature = data.getStringExtra("INAPP_DATA_SIGNATURE");
if (resultCode == RESULT_OK && responseCode == 0) {
try {
PurchaseResponseBean purchaseResponseBean = new Gson().fromJson(purchaseData, PurchaseResponseBean.class);
String sku = purchaseResponseBean.getProductId();
String developerPayload = purchaseResponseBean.getDeveloperPayload();
int responseCodeConsuption = consumePurchaseItem(purchaseResponseBean.getPurchaseToken());
if (responseCodeConsuption == SUCCESS) {
if (purchaseResponseBean.getPurchaseState() == PURCHASED && itemToPurchaseSku.equals(sku) && developerPayload.equals(AppPreference.getInstance(BaseInAppPurchaseActivity.this).getDeveloperPayload())) {
if (onResultPurchase != null)
onResultPurchase.onSuccess(purchaseResponseBean, purchaseData);
} else onErrorOfPurchase();
} else onResultPurchase.onSuccess(purchaseResponseBean, purchaseData);
} catch (Exception e) {
e.printStackTrace();
onErrorOfPurchase();
}
} else onErrorOfPurchase();
}
} else onErrorOfPurchase();
}
private void onErrorOfPurchase() {
if (onResultPurchase != null) onResultPurchase.onError();
}
interface PurchaseStateTypes {
int PURCHASED = 0;
int CANCELED = 1;
int REFUNDED = 2;
}
interface ConsuptionResponseType {
int SUCCESS = 0;
}
private String getPayLoad() {
RandomString randomString = new RandomString(36);
String payload = randomString.nextString();
return payload;
}
private class RandomString {
private final Random random = new Random();
private final char[] buf;
RandomString(int length) {
if (length < 1)
throw new IllegalArgumentException("length < 1: " + length);
buf = new char[length];
}
String nextString() {
for (int idx = 0; idx < buf.length; ++idx)
buf[idx] = symbols[random.nextInt(symbols.length)];
return new String(buf);
}
}
public final class SessionIdentifierGenerator {
private SecureRandom random = new SecureRandom();
public String nextSessionId() {
return new BigInteger(130, random).toString(32);
}
}
public interface OnResultInApp {
void onResult(ArrayList<AvailablePurchase> canPurchaseList);
}
private class AvailablePurchaseAsyncTask extends AsyncTask<Void, Void, Bundle> {
String packageName;
ArrayList<String> skuList;
OnResultInApp OnResultInApp;
AvailablePurchaseAsyncTask(String packageName, ArrayList<String> skuList, OnResultInApp OnResultInApp) {
this.packageName = packageName;
this.skuList = skuList;
this.OnResultInApp = OnResultInApp;
}
#Override
protected Bundle doInBackground(Void... voids) {
Bundle query = new Bundle();
query.putStringArrayList(Helper.ITEM_ID_LIST, skuList);
Bundle skuDetails = null;
try {
skuDetails = mService.getSkuDetails(3, packageName, "inapp", query);
} catch (RemoteException e) {
e.printStackTrace();
}
return skuDetails;
}
#Override
protected void onPostExecute(Bundle skuDetails) {
ArrayList<AvailablePurchase> availablePurchaseArrayList = new ArrayList<>();
if (skuDetails != null) {
int response = skuDetails.getInt("RESPONSE_CODE");
if (response == 0) {
ArrayList<String> responseList = skuDetails.getStringArrayList("DETAILS_LIST");
if (responseList != null) {
for (String thisResponse : responseList) {
JSONObject object = null;
try {
object = new JSONObject(thisResponse);
String sku = object.getString("productId");
String price = object.getString("price");
availablePurchaseArrayList.add(new AvailablePurchase(sku, price, false));
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
}
for (AvailablePurchase availablePurchase : availablePurchaseArrayList) {
for (String sku : skuList) {
if (sku.equals(availablePurchase.getSku())) {
availablePurchase.setActive(true);
}
}
}
if (OnResultInApp != null) {
OnResultInApp.onResult(availablePurchaseArrayList);
}
}
}
public boolean isBillingSupported() {
int response = 1;
try {
response = mService.isBillingSupported(3, getPackageName(), "inapp");
} catch (RemoteException e) {
e.printStackTrace();
}
if (response > 0) {
return false;
}
return true;
}
public int consumePurchaseItem(String purchaseToken) {
if (isBillingSupported()) {
try {
int response = mService.consumePurchase(3, getPackageName(), purchaseToken);
return response;
} catch (RemoteException e) {
e.printStackTrace();
return -1;
}
} else return -1;
}
public Bundle getAllUserPurchase() {
Bundle ownedItems = null;
try {
ownedItems = mService.getPurchases(3, getPackageName(), "inapp", null);
} catch (RemoteException e) {
e.printStackTrace();
}
return ownedItems;
}
public List<UserPurchaseItemsBean> extractAllUserPurchase(Bundle ownedItems) {
List<UserPurchaseItemsBean> mUserItems = new ArrayList<UserPurchaseItemsBean>();
int response = ownedItems.getInt("RESPONSE_CODE");
if (response == 0) {
ArrayList<String> ownedSkus = ownedItems.getStringArrayList("INAPP_PURCHASE_ITEM_LIST");
ArrayList<String> purchaseDataList = ownedItems.getStringArrayList("INAPP_PURCHASE_DATA_LIST");
ArrayList<String> signatureList = ownedItems.getStringArrayList("INAPP_DATA_SIGNATURE_LIST");
String continuationToken = ownedItems.getString("INAPP_CONTINUATION_TOKEN");
if (purchaseDataList != null) {
for (int i = 0; i < purchaseDataList.size(); ++i) {
String purchaseData = purchaseDataList.get(i);
assert signatureList != null;
String signature = signatureList.get(i);
assert ownedSkus != null;
String sku = ownedSkus.get(i);
UserPurchaseItemsBean allItems = new UserPurchaseItemsBean(sku, purchaseData, signature);
mUserItems.add(allItems);
}
}
}
return mUserItems;
}
#Override
public void onDestroy() {
super.onDestroy();
stopInAppPurchaseService();
}
private void stopInAppPurchaseService() {
if (mService != null) {
unbindService(mServiceConn);
}
}
}
AvailablePurchase.class
/**
* Created by KHEMRAJ on 7/13/2017.
*/
public class AvailablePurchase {
private String sku;
private String price;
private boolean isActive;
public AvailablePurchase(String sku, String price, boolean isActive) {
this.sku = sku;
this.price = price;
this.isActive = isActive;
}
public String getSku() {
return sku;
}
public String getPrice() {
return price;
}
public boolean isActive() {
return isActive;
}
public void setActive(boolean active) {
isActive = active;
}
}
Helper.class
/**
* Created by KHEMRAJ on 7/13/2017.
*/
import android.content.Context;
import android.widget.Toast;
public class Helper {
public static final String ITEM_ID_LIST = "ITEM_ID_LIST";
public static final String ITEM_ONE_ID = "android.test.purchased";
public static final String ITEM_TWO_ID = "2";
public static final String ITEM_THREE_ID = "3";
public static final String ITEM_FIVE_ID= "4";
public static final String ITEM_SIX_ID = "5";
public static final int RESPONSE_CODE = 1001;
public static void displayMessage(Context context, String message){
Toast.makeText(context.getApplicationContext(), message, Toast.LENGTH_LONG).show();
}
}
PurchaseResponseBean.class
/**
* Created by KHEMRAJ on 7/15/2017.
*/
public class PurchaseResponseBean {
private String productId;
private String developerPayload;
private String purchaseToken;
private String orderId;
private String purchaseTime;
private int purchaseState;
public String getProductId() {
return productId;
}
public void setProductId(String productId) {
this.productId = productId;
}
public String getDeveloperPayload() {
return developerPayload;
}
public void setDeveloperPayload(String developerPayload) {
this.developerPayload = developerPayload;
}
public String getPurchaseToken() {
return purchaseToken;
}
public void setPurchaseToken(String purchaseToken) {
this.purchaseToken = purchaseToken;
}
public String getOrderId() {
return orderId;
}
public void setOrderId(String orderId) {
this.orderId = orderId;
}
public String getPurchaseTime() {
return purchaseTime;
}
public void setPurchaseTime(String purchaseTime) {
this.purchaseTime = purchaseTime;
}
public int getPurchaseState() {
return purchaseState;
}
public void setPurchaseState(int purchaseState) {
this.purchaseState = purchaseState;
}
}
UserPurchaseItemsBean.class
public class UserPurchaseItemsBean {
private String sku;
private String purchasedata;
private String signature;
public UserPurchaseItemsBean(String sku, String purchasedata, String signature) {
this.sku = sku;
this.purchasedata = purchasedata;
this.signature = signature;
}
public String getSku() {
return sku;
}
public String getPurchasedata() {
return purchasedata;
}
public String getSignature() {
return signature;
}
}
AppPreference.java
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
public class AppPreference {
String DEVELOPERPAYLOAD = "DEVELOPERPAYLOAD";
String PURCHASETOKEN = "PURCHASETOKEN";
//Configuration Variable
private static AppPreference singletonPreference = null;
private SharedPreferences sp;
private Context context;
private AppPreference(Context context) {
if (context == null)
return;
this.context = context;
sp = context.getSharedPreferences(Constants.sharedPreference.PREFERENCE, 0);
}
public static AppPreference getInstance(Context context) {
if (singletonPreference == null)
singletonPreference = new AppPreference(context);
return singletonPreference;
}
public void clearOnlogout() {
Editor prefsEditor = sp.edit();
prefsEditor.clear();
prefsEditor.apply();
}
void removeData(String key) {
SharedPreferences.Editor editor = sp.edit();
editor.remove(key);
editor.apply();
}
public void setStringData(String pKey, String pData) {
SharedPreferences.Editor editor = sp.edit();
editor.putString(pKey, pData);
editor.apply();
}
public void setBooleanData(String pKey, boolean pData) {
SharedPreferences.Editor editor = sp.edit();
editor.putBoolean(pKey, pData);
editor.apply();
}
void setIntegerData(String pKey, int pData) {
SharedPreferences.Editor editor = sp.edit();
editor.putInt(pKey, pData);
editor.apply();
}
public String getStringData(String pKey) {
return sp.getString(pKey, "");
}
public boolean getBooleanData(String pKey) {
return sp.getBoolean(pKey, false);
}
public int getIntegerData(String pKey) {
return sp.getInt(pKey, 0);
}
public String getDeveloperPayload() {
return sp.getString(DEVELOPERPAYLOAD, "");
}
public void setDeveloperPayload(String developerPayload) {
SharedPreferences.Editor editor = sp.edit();
editor.putString(DEVELOPERPAYLOAD, developerPayload);
editor.apply();
}
}
Happy coding :)
I've success to populate data into listview, but my way seems very bad because when i scroll the list view, the retrofit always get All the Repository. So, what is the best way to populate Endless List view's data with retrofit ? Thanks ...
MainActivity.java
public class MainActivity extends Activity {
public static final String ENDPOINT = "http://rfhan.com";
private List<Tempat> tempatList;
private TempatAdapter tadapter;
private EndlessListView lv;
private int start=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tempatList = new ArrayList<Tempat>();
tadapter = new TempatAdapter(this, R.layout.item_tempat, tempatList);
lv = (EndlessListView) findViewById(R.id.el);
lv.setLoadingView(R.layout.loading_layout);
lv.setAdapter(tadapter);
//init data to my list
requestData();
//scroll listener
lv.setListener(new EndlessListener() {
#Override
public void loadData() {
requestData();
}
});
}
private void requestData(){
RestAdapter adapter = new RestAdapter.Builder()
.setEndpoint(ENDPOINT)
.build();
TempatAPI api = adapter.create(TempatAPI.class);
api.getAllData(new Callback<List<Tempat>>() {
//here the problem
#Override
public void success(List<Tempat> data, Response arg1) {
updateData(data);
}
#Override
public void failure(RetrofitError arg0) {
Toast.makeText(MainActivity.this, "Retrofit Error!", Toast.LENGTH_LONG).show();
Toast.makeText(MainActivity.this, arg0+"", Toast.LENGTH_LONG).show();
}
});
}
//the tmpt list is contain all Tempat's data
//code below is to get some tmpt's data into new Arraylist
//and update the adapter's data
//it's work but seems bad way
private void updateData(List<Tempat> tmpt){
tempatList = new ArrayList<Tempat>();
start+=10;
for(int i=start-10;(i<start&&start<tmpt.size());i++)
tempatList.add(tmpt.get(i));
lv.addNewData(tempatList);
}
protected boolean isOnline() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnectedOrConnecting()) {
return true;
} else {
return false;
}
}
}
Model Tempat.java
import java.math.BigInteger;
import android.graphics.Bitmap;
public class Tempat {
BigInteger idkoleksi;
String nama;
String kategori;
String alamat;
String notelp;
String jambuka;
String jamtutup;
String harga;
String imageHeaderURL;
double latitude;
double longitude;
int jumlahview;
int jumlatrate;
double rating;
String tanggal;
Bitmap bitmap;
public BigInteger getIdkoleksi() {
return idkoleksi;
}
public String getNama() {
return nama;
}
public String getKategori() {
return kategori;
}
public String getAlamat() {
return alamat;
}
public String getNotelp() {
return notelp;
}
public String getJambuka() {
return jambuka;
}
public String getJamtutup() {
return jamtutup;
}
public String getHarga() {
return harga;
}
public String getImageHeaderURL() {
return imageHeaderURL;
}
public double getLatitude() {
return latitude;
}
public double getLongitude() {
return longitude;
}
public int getJumlahview() {
return jumlahview;
}
public int getJumlatrate() {
return jumlatrate;
}
public double getRating() {
return rating;
}
public String getTanggal() {
return tanggal;
}
public void setIdkoleksi(BigInteger idkoleksi) {
this.idkoleksi = idkoleksi;
}
public void setNama(String nama) {
this.nama = nama;
}
public void setKategori(String kategori) {
this.kategori = kategori;
}
public void setAlamat(String alamat) {
this.alamat = alamat;
}
public void setNotelp(String notelp) {
this.notelp = notelp;
}
public void setJambuka(String jambuka) {
this.jambuka = jambuka;
}
public void setJamtutup(String jamtutup) {
this.jamtutup = jamtutup;
}
public void setHarga(String harga) {
this.harga = harga;
}
public void setImageHeaderURL(String imageHeaderURL) {
this.imageHeaderURL = imageHeaderURL;
}
public void setLatitude(double latitude) {
this.latitude = latitude;
}
public void setLongitude(double longitude) {
this.longitude = longitude;
}
public void setJumlahview(int jumlahview) {
this.jumlahview = jumlahview;
}
public void setJumlatrate(int jumlatrate) {
this.jumlatrate = jumlatrate;
}
public void setRating(double rating) {
this.rating = rating;
}
public void setTanggal(String tanggal) {
this.tanggal = tanggal;
}
public Bitmap getBitmap() {
return bitmap;
}
public void setBitmap(Bitmap bitmap) {
this.bitmap = bitmap;
}
}
Repository TempatAPI.java
import java.util.List;
import retrofit.Callback;
import retrofit.http.GET;
public interface TempatAPI {
#GET("api/tempat/get_all_data.php")
public void getAllData(Callback<List<Tempat>> response);
}
Webservice API get_all_data.php
<?php
$response = array();
require_once __DIR__ . '/db_connect.php';
$db = new DB_CONNECT();
$nama=$_GET["nama"];
$query = "SELECT DataKoleksi.* , DataStatistikKoleksi.* FROM DataKoleksi, DataStatistikKoleksi WHERE DataKoleksi.idkoleksi = DataStatistikKoleksi.idkoleksi";
$result = mysql_query($query) or die(mysql_error());
$response = array();
if (mysql_num_rows($result) > 0) {
while ($row = mysql_fetch_array($result)) {
$koleksi = array();
$koleksi["idkoleksi"] = $row["idkoleksi"];
$koleksi["nama"] = $row["nama"];
$koleksi["kategori"] = $row["kategori"];
$koleksi["alamat"] = $row["alamat"];
$koleksi["notelp"] = $row["notelp"];
$koleksi["jambuka"] = $row["jambuka"];
$koleksi["jamtutup"] = $row["jamtutup"];
$koleksi["harga"] = $row["harga"];
$koleksi["imageHeaderURL"] = $row["imageHeaderURL"];
$koleksi["latitude"] = $row["latitude"];
$koleksi["longitude"] = $row["longitude"];
$koleksi["jumlahview"] = $row["jumlahview"];
$koleksi["jumlahrate"] = $row["jumlahrate"];
$koleksi["rating"] = $row["rating"];
$koleksi["tanggal"] = $row["tanggal"];
array_push($response, $koleksi);
}
echo json_encode($response);
} else {
// no found
echo json_encode($response);
}
?>
You need to add a listener to your listview to see if you have scrolled to the end of the list. In my example below, we check if we have reached the end of the list and if we have, we try to load 10 more items. The listview is then updated.
lvEvents.setOnScrollListener(new AbsListView.OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView absListView, int scrollState) {}
#Override
public void onScroll(AbsListView absListView, int firstVisible, int visibleCount, int totalCount) {
boolean loadMore = firstVisible + visibleCount >= totalCount;
if (loadMore && !isLoadingEvents && futureEvents.size() >= 10 && !noMoreEvents) {
Log.d(TAG, "LOADING MORE EVENTS");
isLoadingEvents = true;
networkManager.getTenMoreEvents(getActivity(), new NetworkManager.Request() {
#Override
public void finished() {
updateEventsFeed();
isLoadingEvents = false;
}
});
}
}
});
I want to save a custom object myObject in shared preferences. Where this custom object has ArrayList<anotherCustomObj>. This anotherCustomObj has primary variables.
Both myObject and anotherCustomObj are parcelable.
I tried below code to convert it to String and save it :
String myStr = gson.toJson(myObject);
editor.putString(MY_OBJ, myStr);
But it gives RunTimeException.
EDIT : Below is logcat screen shot.
anotherCustomObj implementation :
package com.objectlounge.ridesharebuddy.classes;
import java.io.File;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Parcel;
import android.os.Parcelable;
import android.preference.PreferenceManager;
import android.util.Log;
import com.google.gson.annotations.SerializedName;
import com.objectlounge.ridesharebuddy.R;
public class RS_SingleMatch implements Parcelable {
private static final String RIDESHARE_DIRECTORY = "RideShareBuddy";
private static final String TAG = "RS_SingleMatch";
private static final String IMAGE_PATH = "imagePath";
private static final String IMAGE_NAME_PREFIX = "RideShareBuddyUserImage";
private Context context;
#SerializedName("id")
private int userId;
private int tripId;
private String imageUrl;
#SerializedName("userName")
private String email;
private String realName;
private String gender;
private int reputation;
private String createdAt;
private String birthdate;
private float fromLat, fromLon, toLat, toLon;
private String fromPOI, toPOI;
private String departureTime;
private int matchStrength;
// Constructor
public RS_SingleMatch(Context context) {
this.context = context;
}
// Constructor to use when reconstructing an object from a parcel
public RS_SingleMatch(Parcel in) {
readFromParcel(in);
}
#Override
public int describeContents() {
return 0;
}
#Override
// Called to write all variables to a parcel
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(userId);
dest.writeInt(tripId);
dest.writeString(imageUrl);
dest.writeString(email);
dest.writeString(realName);
dest.writeString(gender);
dest.writeInt(reputation);
dest.writeString(createdAt);
dest.writeString(birthdate);
dest.writeFloat(fromLat);
dest.writeFloat(fromLon);
dest.writeFloat(toLat);
dest.writeFloat(toLon);
dest.writeString(fromPOI);
dest.writeString(toPOI);
dest.writeString(departureTime);
dest.writeInt(matchStrength);
}
// Called from constructor to read object properties from parcel
private void readFromParcel(Parcel in) {
// Read all variables from parcel to created object
userId = in.readInt();
tripId = in.readInt();
imageUrl = in.readString();
email = in.readString();
realName = in.readString();
gender = in.readString();
reputation = in.readInt();
createdAt = in.readString();
birthdate = in.readString();
fromLat = in.readFloat();
fromLon = in.readFloat();
toLat = in.readFloat();
toLon = in.readFloat();
fromPOI = in.readString();
toPOI = in.readString();
departureTime = in.readString();
matchStrength = in.readInt();
}
// This creator is used to create new object or array of objects
public static final Parcelable.Creator<RS_SingleMatch> CREATOR = new Parcelable.Creator<RS_SingleMatch>() {
#Override
public RS_SingleMatch createFromParcel(Parcel in) {
return new RS_SingleMatch(in);
}
#Override
public RS_SingleMatch[] newArray(int size) {
return new RS_SingleMatch[size];
}
};
// Getters
public int getUserId() {
return userId;
}
public int getTripId() {
return tripId;
}
public String getImageUrl() {
return imageUrl;
}
public Bitmap getImage() {
Bitmap image = null;
// If imageUrl is not empty
if (getImageUrl().length() > 0) {
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(this.context);
String imagePath = prefs.getString(IMAGE_PATH + getUserId(), "");
// Get image from cache
if ((image = RS_FileOperationsHelper.getImageAtPath(imagePath)) == null) {
Log.d(TAG, "Image not found on disk.");
Thread t = new Thread(new Runnable() {
#Override
public void run() {
// If image not found on storage then download it
setImage(downloadImage(getImageUrl()));
}
});
t.start();
}
} else {
// Use default image
image = getDefaultProfileImage();
}
image = RS_ImageViewHelper.getRoundededImage(image, image.getWidth());
Log.d(TAG, "Image width : " + image.getWidth());
return image;
}
public String getEmail() {
return email;
}
public String getRealName() {
return realName;
}
public String getGender() {
return gender;
}
public int getReputation() {
return reputation;
}
public String getCreatedAt() {
return createdAt;
}
public String getBirthdate() {
return birthdate;
}
public float getFromLat() {
return fromLat;
}
public float getFromLon() {
return fromLon;
}
public float getToLat() {
return toLat;
}
public float getToLon() {
return toLon;
}
public String getFromPOI() {
return fromPOI;
}
public String getToPOI() {
return toPOI;
}
public String getDepartureTime() {
return departureTime;
}
public int getMatchStrength() {
return matchStrength;
}
// Setters
public void setContext(Context context) {
this.context = context;
}
public void setUserId(int userId) {
this.userId = userId;
}
public void setTripId(int tripId) {
this.tripId = tripId;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
public void setImage(Bitmap img) {
if (img != null) {
// Get cache directory's path and append RIDESHARE_DIRECTORY.
String cacheDirStoragePath = context.getCacheDir()
+ "/"
+ RIDESHARE_DIRECTORY;
// Create directory at cacheDirStoragePath if does not exist.
if (RS_FileOperationsHelper
.createDirectoryAtPath(cacheDirStoragePath)) {
String imagePath = cacheDirStoragePath + "/"
+ IMAGE_NAME_PREFIX + this.userId + ".png";
// Save new image to cache
RS_FileOperationsHelper.saveImageAtPath(img, imagePath, this.context);
SharedPreferences pref = PreferenceManager
.getDefaultSharedPreferences(context);
Editor e = pref.edit();
e.putString(IMAGE_PATH + getUserId(), imagePath);
e.commit();
}
}
}
public void setEmail(String email) {
this.email = email;
}
public void setRealName(String realName) {
this.realName = realName;
}
public void setGender(String gender) {
this.gender = gender;
}
public void setReputation(int reputation) {
this.reputation = reputation;
}
public void setCreatedAt(String createdAt) {
this.createdAt = createdAt;
}
public void setBirthdate(String birthdate) {
this.birthdate = birthdate;
}
public void setFromLat(float fromLat) {
this.fromLat = fromLat;
}
public void setFromLon(float fromLon) {
this.fromLon = fromLon;
}
public void setToLat(float toLat) {
this.toLat = toLat;
}
public void setToLon(float toLon) {
this.toLon = toLon;
}
public void setFromPOI(String fromPOI) {
this.fromPOI = fromPOI;
}
public void setToPOI(String toPOI) {
this.toPOI = toPOI;
}
public void setDepartureTime(String departureTime) {
this.departureTime = departureTime;
}
public void setMatchStrength(int matchStrength) {
this.matchStrength = matchStrength;
}
// calculates age using given date
#SuppressLint("SimpleDateFormat")
public int calculateAge(String date) {
int age = 0;
try {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
Date bdate = formatter.parse(date);
Calendar lCal = Calendar.getInstance();
lCal.setTime(bdate);
int lYear = lCal.get(Calendar.YEAR);
int lMonth = lCal.get(Calendar.MONTH) + 1;
int lDay = lCal.get(Calendar.DATE);
Calendar dob = Calendar.getInstance();
Calendar today = Calendar.getInstance();
dob.set(lYear, lMonth, lDay);
age = today.get(Calendar.YEAR) - dob.get(Calendar.YEAR);
if (today.get(Calendar.DAY_OF_YEAR) < dob.get(Calendar.DAY_OF_YEAR)) {
age--;
}
} catch (ParseException e) {
e.printStackTrace();
}
return age;
}
// Download image if not available
protected void downloadAndSaveImage() {
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(this.context);
String imagePath = prefs.getString(IMAGE_PATH + getUserId(), "");
File file = new File(imagePath);
// If image path not stored in user defaults or image does not exists
// then
if ((imagePath == null || !file.exists()) && this.imageUrl.length() > 0) {
// Download on separate thread
Thread t = new Thread(new Runnable() {
#Override
public void run() {
setImage(downloadImage(getImageUrl()));
}
});
t.start();
}
}
// Download an image
private Bitmap downloadImage(String imageUrl) {
Log.d(TAG, "Image url : " + imageUrl);
Bitmap image = null;
try {
// Download an image from url
InputStream in = new java.net.URL(imageUrl.trim()).openStream();
image = BitmapFactory.decodeStream(in);
} catch (Exception e) {
e.printStackTrace();
}
Log.d(TAG, "Image downloading complete. image : " + image);
return image;
}
// Get default image
protected Bitmap getDefaultProfileImage() {
Bitmap image = BitmapFactory.decodeResource(
this.context.getResources(), R.drawable.default_male);
if (this.gender.toUpperCase(Locale.US).startsWith("F")) {
image = BitmapFactory.decodeResource(this.context.getResources(),
R.drawable.default_female);
}
return image;
}
}
Link posted by damian was helpful to solve my problem. However, in my case there was no view component in custom object.
According to my observation if you find multiple JSON fields for ANY_VARIABLE_NAME, then it is likely that it is because GSON is not able to convert the object. And you can try below code to solve it.
Add below class to to tell GSON to save and/or retrieve only those variables who have Serialized name declared.
class Exclude implements ExclusionStrategy {
#Override
public boolean shouldSkipClass(Class<?> arg0) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean shouldSkipField(FieldAttributes field) {
SerializedName ns = field.getAnnotation(SerializedName.class);
if(ns != null)
return false;
return true;
}
}
Below is the class whose object you need to save/retrieve.
Add #SerializedName for variables that needs to saved and/or retrieved.
class myClass {
#SerializedName("id")
int id;
#SerializedName("name")
String name;
}
Code to convert myObject to jsonString :
Exclude ex = new Exclude();
Gson gson = new GsonBuilder().addDeserializationExclusionStrategy(ex).addSerializationExclusionStrategy(ex).create();
String jsonString = gson.toJson(myObject);
Code to get object from jsonString :
Exclude ex = new Exclude();
Gson gson = new GsonBuilder().addDeserializationExclusionStrategy(ex).addSerializationExclusionStrategy(ex).create();
myClass myObject = gson.fromJson(jsonString, myClass.class);