I made a small android app that, from a listview, opens a google maps activity and when you longpress on the map, it saves the address of that location in an ArrayList
and then adds it to the list view,the latitute and longitute of the location are also saved that way, and then I save all of that information through SharedPreferences.
My problem is, that even though the listview is updated when the app is running, I lose all of the data when I restart the app, basically meaning the information is never being saved in the first place.
The saving of data is done on the onMapLongClick
method in the MapsActivity, and the data load is done on the OnCreate
method in the MainActivity.
MainActivity:
package com.rapha.favoriteplaces;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import java.io.IOException;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
static ArrayList<String> places = new ArrayList<>();
static ArrayList<String> lats = new ArrayList<>();
static ArrayList<String> lngs = new ArrayList<>();
static ArrayAdapter arrayAdapter;
@Override
public void onBackPressed()
{
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView listView = (ListView)findViewById(R.id.list);
places.add("Add a location...");
final Intent intent = new Intent(getApplicationContext(), MapsActivity.class);
SharedPreferences sharedPreferences = this.getSharedPreferences("package com.rapha.favoriteplaces", Context.MODE_PRIVATE);
try {
places = (ArrayList<String>) ObjectSerializer.deserialize(sharedPreferences.getString("places", ObjectSerializer.serialize(new ArrayList<String>())));
lats = (ArrayList<String>)ObjectSerializer.deserialize(sharedPreferences.getString("lats", ObjectSerializer.serialize(new ArrayList<String>())));
lngs = (ArrayList<String>)ObjectSerializer.deserialize(sharedPreferences.getString("lngs", ObjectSerializer.serialize(new ArrayList<String>())));
} catch (IOException e) {
e.printStackTrace();
}
if(places.size() > 0 && lats.size() > 0 && lngs.size() > 0)
{
System.out.println("load data sucessfully check");
}
arrayAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, places);
listView.setAdapter(arrayAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if(position == 0)
{
intent.putExtra("coisa", position);
startActivity(intent);
}
else
{
intent.putExtra("coisa", position);
String lat = ((lats.get(position - 1)));
String lon = ((lngs.get(position - 1)));
intent.putExtra("lat", lat);
intent.putExtra("lon", lon);
intent.putExtra("ad", places.get(position));
startActivity(intent);
}
}
});
}
}
MapsActivity:
package com.rapha.favoriteplaces;
import android.*;
import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.widget.Toast;
import com.google.android.gms.appindexing.Action;
import com.google.android.gms.appindexing.AppIndex;
import com.google.android.gms.appindexing.Thing;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, GoogleMap.OnMapLongClickListener {
private GoogleMap mMap;
LocationManager locationManager;
LocationListener locationListener;
String address;
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults.length > 0 && grantResults[0] != PackageManager.PERMISSION_GRANTED) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5, 100000, locationListener);
}
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
Intent intent = getIntent();
mMap.setOnMapLongClickListener(this);
int coisa = intent.getIntExtra("coisa", 0);
if(coisa == 0)
{
locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
locationListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
LatLng userLocation = new LatLng(location.getLatitude(), location.getLongitude());
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(userLocation, 15));
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
};
if (Build.VERSION.SDK_INT < 23) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 100, locationListener);
} else {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
} else {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 100, locationListener);
mMap.clear();
Location lastKnownLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
LatLng userLocation = new LatLng(lastKnownLocation.getLatitude(), lastKnownLocation.getLongitude());
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(userLocation, 15));
}
}
}
else
{
double lat = Double.parseDouble(intent.getStringExtra("lat"));
double lon = Double.parseDouble(intent.getStringExtra("lon"));
LatLng location = new LatLng(lat, lon);
mMap.addMarker(new MarkerOptions().position(location).title(intent.getStringExtra("ad")));
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(location, 15));
}
}
@Override
public void onMapLongClick(LatLng latLng) {
Geocoder geocoder = new Geocoder(getApplicationContext(), Locale.getDefault());
try {
List<Address> addresses = geocoder.getFromLocation(latLng.latitude, latLng.longitude, 1);
if (addresses != null && addresses.size() > 0) {
address = addresses.get(0).getAddressLine(0);
}
} catch (IOException e) {
e.printStackTrace();
}
mMap.addMarker(new MarkerOptions().position(latLng).title(address));
MainActivity.lats.add(String.valueOf(latLng.latitude));
MainActivity.lngs.add(String.valueOf(latLng.longitude));
MainActivity.places.add(address);
MainActivity.arrayAdapter.notifyDataSetChanged();
SharedPreferences sharedPreferences = getSharedPreferences("com.rapha.favoriteplaces",Context.MODE_PRIVATE);
try {
sharedPreferences.edit().putString("lats", ObjectSerializer.serialize(MainActivity.lats)).apply();
sharedPreferences.edit().putString("lngs", ObjectSerializer.serialize(MainActivity.lngs)).apply();
sharedPreferences.edit().putString("places", ObjectSerializer.serialize(MainActivity.places)).apply();
} catch (IOException e) {
e.printStackTrace();
}
}
}
The Object Serializer class:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class ObjectSerializer {
public static String serialize(Serializable obj) throws IOException {
if (obj == null) return "";
try {
ByteArrayOutputStream serialObj = new ByteArrayOutputStream();
ObjectOutputStream objStream = new ObjectOutputStream(serialObj);
objStream.writeObject(obj);
objStream.close();
return encodeBytes(serialObj.toByteArray());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static Object deserialize(String str) throws IOException {
if (str == null || str.length() == 0) return null;
try {
ByteArrayInputStream serialObj = new ByteArrayInputStream(decodeBytes(str));
ObjectInputStream objStream = new ObjectInputStream(serialObj);
return objStream.readObject();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static String encodeBytes(byte[] bytes) {
StringBuffer strBuf = new StringBuffer();
for (int i = 0; i < bytes.length; i++) {
strBuf.append((char) (((bytes[i] >> 4) & 0xF) + ((int) 'a')));
strBuf.append((char) (((bytes[i]) & 0xF) + ((int) 'a')));
}
return strBuf.toString();
}
public static byte[] decodeBytes(String str) {
byte[] bytes = new byte[str.length() / 2];
for (int i = 0; i < str.length(); i += 2) {
char c = str.charAt(i);
bytes[i / 2] = (byte) ((c - 'a') << 4);
c = str.charAt(i + 1);
bytes[i / 2] += (c - 'a');
}
return bytes;
}
}
You seem to be putting into and getting from two different preference.
When fetching from preference, you are using package com.rapha.favoriteplaces
:
SharedPreferences sharedPreferences = this.getSharedPreferences("package com.rapha.favoriteplaces", Context.MODE_PRIVATE);
try {
places = (ArrayList<String>) ObjectSerializer.deserialize(sharedPreferences.getString("places", ObjectSerializer.serialize(new ArrayList<String>())));
// ...
When saving the values you use com.rapha.favoriteplaces
:
SharedPreferences sharedPreferences = getSharedPreferences("com.rapha.favoriteplaces",Context.MODE_PRIVATE);
sharedPreferences.edit().putString("lats", ObjectSerializer.serialize(MainActivity.lats)).apply();
Make both of them same and then try.