I'm attempting to update an existing RealmObject (IncidentCard) which include a RealmList of type IncidentPhoto. The object is updated without any problems as long as I don't attempt to update the RealmList, when I include the list I get the following error message:
E/AndroidRuntime: FATAL EXCEPTION: main
E/AndroidRuntime: Process: com.trollvik.android.incidents247, PID: 31923
E/AndroidRuntime: java.lang.IllegalArgumentException: Each element of 'value' must be a valid managed object.
E/AndroidRuntime: at io.realm.IncidentCardRealmProxy.setPhotos(IncidentCardRealmProxy.java:218)
E/AndroidRuntime: at com.trollvik.android.incidents247.activities.EditCardActivity.saveIncidentCard(EditCardActivity.java:155)
E/AndroidRuntime: at com.trollvik.android.incidents247.activities.EditCardActivity$1.onClick(EditCardActivity.java:95)
E/AndroidRuntime: at android.view.View.performClick(View.java:5197)
E/AndroidRuntime: at android.view.View$PerformClick.run(View.java:20926)
E/AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:739)
E/AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:95)
E/AndroidRuntime: at android.os.Looper.loop(Looper.java:145)
E/AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:5944)
E/AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime: at java.lang.reflect.Method.invoke(Method.java:372)
E/AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1388)
E/AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1183)
This is the IncidentCard class:
public class IncidentCard extends RealmObject {
#PrimaryKey
private long id;
private String timestamp;
private String type;
private RealmList<IncidentPhoto> photos;
public IncidentCard() {
}
public IncidentCard(long id, String timestamp, String type){
this.id = id;
this.timestamp = timestamp;
this.type = type;
}
public IncidentCard(long id, String timestamp, String type, RealmList<IncidentPhoto> photos){
this.id = id;
this.timestamp = timestamp;
this.type = type;
this.photos = photos;
}
public long getId() {
return this.id;
}
public void setId(long id) {
this.id = id;
}
public String getTimestamp(){
return this.timestamp;
}
public void setTimestamp(String timestamp) {
this.timestamp = timestamp;
}
public String getType(){
return this.type;
}
public void setType(String type){
this.type = type;
}
public RealmList<IncidentPhoto> getPhotos() {
return this.photos;
}
public void setPhotos(RealmList<IncidentPhoto> photos) {
this.photos = photos;
}
}
This is the IncidentPhoto class:
public class IncidentPhoto extends RealmObject {
private String photoPath;
public IncidentPhoto() {
}
public IncidentPhoto(String photoPath) {
this.photoPath = photoPath;
}
public String getPhotoPath(){
return this.photoPath;
}
public void setPhotoPath(String photoPath){
this.photoPath = photoPath;
}
}
To query the Realm DB I created this helper class:
public class IncidentDbHelper {
private Realm realm;
public IncidentDbHelper(Context context) {
realm = Realm.getInstance(context);
}
public void setObject(IncidentCard incidentCard) {
realm.beginTransaction();
IncidentCard incident = realm.copyToRealmOrUpdate(incidentCard);
realm.commitTransaction();
}
public IncidentCard getObject(Long id) {
return realm.where(IncidentCard.class).equalTo("id", id).findFirst();
}
public void close(){
if (realm != null) {
realm.close();
}
}
}
When I add a new incident card I call this activity:
public class NewCardActivity extends AppCompatActivity {
private static final int REQUEST_IMAGE_CAPTURE = 1;
private static final String INSTANCE_STATE = "currentPhotoPath";
private static final String INSTANCE_STATE_LIST = "currentPhotoList";
private Context mContext;
private IncidentCard mIncidentCard;
private IncidentDbHelper mDbHelper;
private IncidentCardId mIncidentId;
private IncidentCardTimestamp mIncidentTimestamp;
private RealmConverter mRealmConverter;
private Resources mRes;
private PhotoPath mPath;
private String mCurrentPhotoPath;
private ArrayList<String> mCurrentPhotoList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = this;
mDbHelper = new IncidentDbHelper(mContext);
mIncidentCard = new IncidentCard();
mRealmConverter = new RealmConverter();
mCurrentPhotoList = new ArrayList<String>();
mIncidentId = new IncidentCardId();
mIncidentTimestamp = new IncidentCardTimestamp();
mRes = getResources();
mPath = new PhotoPath();
// If savedInstanceState is empty, ignore this code.
if(savedInstanceState != null){
mCurrentPhotoPath = savedInstanceState.getString(INSTANCE_STATE);
mCurrentPhotoList = savedInstanceState.getStringArrayList(INSTANCE_STATE_LIST);
}
}
protected void saveIncidentCard(){
Realm realm = Realm.getInstance(this);
Spinner spinner = (Spinner) findViewById(R.id.content_new_card_type);
String incidentType = spinner.getSelectedItem().toString();
realm.beginTransaction();
mIncidentCard.setId(mIncidentId.getNewId());
mIncidentCard.setTimestamp(mIncidentTimestamp.getNewTimestamp());
mIncidentCard.setType(incidentType);
mIncidentCard.setPhotos(mRealmConverter.toRealmList(mCurrentPhotoList));
realm.commitTransaction();
mDbHelper.setObject(mIncidentCard);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_new_card, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_new_photo:
dispatchTakePictureIntent();
default:
// If we got here, the user's action was not recognized.
// Invoke the superclass to handle it.
return super.onOptionsItemSelected(item);
}
}
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File imageFile = null;
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
try {
imageFile = mPath.createImageFile();
mCurrentPhotoPath = imageFile.getAbsolutePath();
} catch (java.io.IOException e) {
Log.e(TAG, e.toString());
}
// Continue only if the File was successfully created
if (imageFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(imageFile.getAbsoluteFile()));
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putString(INSTANCE_STATE, mCurrentPhotoPath);
savedInstanceState.putStringArrayList(INSTANCE_STATE_LIST, mCurrentPhotoList);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
mCurrentPhotoList.add(mCurrentPhotoPath);
}
}
#Override
protected void onDestroy() {
super.onDestroy();
mDbHelper.close();
}
}
While I capture new photos I save the paths of previously captured photos in a ArrayList of type String. Before I set the list of paths to the IncidentCard object I convert the list to a RealmList. This part seems to be working fine.
The problem occurs after I try to save an existing object in EditCardActivity:
public class EditCardActivity extends AppCompatActivity {
private static final String INTENT_EXTRA = "EXTRA_INCIDENT_ID";
private static final int REQUEST_IMAGE_CAPTURE = 2;
private static final String INSTANCE_STATE = "currentPhotoPath";
private static final String INSTANCE_STATE_LIST = "currentPhotoList";
private Context mContext;
private Long mIncidentId;
private IncidentCard mIncidentCard;
private IncidentDbHelper mDbHelper;
private IncidentCardTimestamp mIncidentTimestamp;
private RealmConverter mRealmConverter;
private Resources mRes;
private PhotoPath mPath;
Spinner mSpinnerType;
private String mCurrentPhotoPath;
private ArrayList<String> mCurrentPhotoList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mRealmConverter = new RealmConverter();
mContext = this;
mDbHelper = new IncidentDbHelper(mContext);
mIncidentCard = new IncidentCard();
mCurrentPhotoList = new ArrayList<String>();
mIncidentTimestamp = new IncidentCardTimestamp();
mRes = getResources();
mPath = new PhotoPath();
// If savedInstanceState is empty, ignore this code.
if(savedInstanceState != null){
mCurrentPhotoPath = savedInstanceState.getString(INSTANCE_STATE);
mCurrentPhotoList = savedInstanceState.getStringArrayList(INSTANCE_STATE_LIST);
}
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
saveIncidentCard();
finish();
}
});
// Get Incident ID passed from Main Activity
Intent intent = getIntent();
mIncidentId = intent.getLongExtra(INTENT_EXTRA, 0);
mIncidentCard = mDbHelper.getObject(mIncidentId);
mTextViewId = (TextView) findViewById(R.id.content_edit_card_id);
mSpinnerType = (Spinner) findViewById(R.id.content_edit_card_type);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_dropdown_item, items);
mSpinnerType.setAdapter(adapter);
String compareValue = mIncidentCard.getType();
if (!compareValue.equals(null)) {
int spinnerPosition = adapter.getPosition(compareValue);
mSpinnerType.setSelection(spinnerPosition);
}
mCurrentPhotoList = mRealmConverter.toArrayList(mIncidentCard.getPhotos());
}
protected void saveIncidentCard(){
Realm realm = Realm.getInstance(this);
Spinner spinner = (Spinner) findViewById(R.id.content_edit_card_type);
String incidentType = spinner.getSelectedItem().toString();
realm.beginTransaction();
mIncidentCard.setTimestamp(mIncidentTimestamp.getNewTimestamp());
mIncidentCard.setType(incidentType);
mIncidentCard.setPhotos(mRealmConverter.toRealmList(mCurrentPhotoList));
realm.commitTransaction();
mDbHelper.setObject(mIncidentCard);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_edit_card, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_edit_photo:
dispatchTakePictureIntent();
default:
// If we got here, the user's action was not recognized.
// Invoke the superclass to handle it.
return super.onOptionsItemSelected(item);
}
}
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File imageFile = null;
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
try {
imageFile = mPath.createImageFile();
mCurrentPhotoPath = imageFile.getAbsolutePath();
} catch (java.io.IOException e) {
Log.e(TAG, e.toString());
}
// Continue only if the File was successfully created
if (imageFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(imageFile.getAbsoluteFile()));
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putString(INSTANCE_STATE, mCurrentPhotoPath);
savedInstanceState.putStringArrayList(INSTANCE_STATE_LIST, mCurrentPhotoList);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
mCurrentPhotoList.add(mCurrentPhotoPath);
}
}
#Override
protected void onDestroy() {
super.onDestroy();
mDbHelper.close();
}
}
So, if I comment out mIncidentCard.setPhotos() everything seems to work fine, but when I try to set the photos to the IncidentCard object the IllegalArgumentException is triggered.
This is the method I created for converting ArrayLists to RealmLists:
public RealmList<IncidentPhoto> toRealmList(ArrayList<String> arrayList){
mRealmList = new RealmList<IncidentPhoto>();
for (int i = 0; i < arrayList.size(); i++){
IncidentPhoto incidentPhoto = new IncidentPhoto();
incidentPhoto.setPhotoPath(arrayList.get(i));
mRealmList.add(incidentPhoto);
}
return mRealmList;
}
I've been struggling with this for a while now and I don't understand what I'm doing wrong, so any help will be greatly appreciated.
Realm Exception 'value' is not a valid managed object
Realm Java Doc
The problem is, when calling setters to set a RealmList, every element in the list has to be managed by Realm already.
Similar question here Adding standalone-objects to a RealmList
You can modify toRealmList as below:
public RealmList<IncidentPhoto> toRealmList(Realm realm, ArrayList<String> arrayList) {
mRealmList = new RealmList<IncidentPhoto>();
for (int i = 0; i < arrayList.size(); i++){
// Create a IncidentPhoto object which is managed by Realm.
IncidentPhoto incidentPhoto = realm.createObject(IncidentPhoto.class);
incidentPhoto.setPhotoPath(arrayList.get(i));
mRealmList.add(incidentPhoto);
}
return mRealmList;
}
or
public RealmList<IncidentPhoto> toRealmList(Realm realm, ArrayList<String> arrayList) {
mRealmList = new RealmList<IncidentPhoto>();
for (int i = 0; i < arrayList.size(); i++){
IncidentPhoto incidentPhoto = new IncidentPhoto();
incidentPhoto.setPhotoPath(arrayList.get(i));
// Copy the standalone object to Realm, and get the returned object which is managed by Realm.
incidentPhoto = realm.copyToRealm(incidentPhoto);
mRealmList.add(incidentPhoto);
}
return mRealmList;
}
Related
I have a homework about doing whatsapp clone. But I have a problem. I have a add contact screen. Users choose an image from gallery and enter their name. When they click add button, list item will be added to chat activity. Screenshot is below. I have a person class like:
public class Person
{
private int id;
private string name;
private int imageId;
public Person(int id, string name, int imageId)
{
this.id = id;
this.name = name;
this.imageId = imageId;
}
public int Id // property
{
get { return id; } // get method
set { id = value; } // set method
}
public string Name // property
{
get { return name; } // get method
set { name = value; } // set method
}
public int ImageId // property
{
get { return imageId; } // get method
set { imageId = value; } // set method
}
public static explicit operator Java.Lang.Object(Person v)
{
throw new NotImplementedException();
}
}
public class PersonAdapter : BaseAdapter
{
private LayoutInflater mInflater;
private List<Person> personArrayList;
public PersonAdapter(Activity activity, List<Person> personArrayList)
{
this.mInflater = (LayoutInflater)activity.GetSystemService(Context.LayoutInflaterService);
this.personArrayList = personArrayList;
}
public override int Count => personArrayList.Count;
public override Object GetItem(int position)
{
return (Object)personArrayList.ElementAt(position);
}
public override long GetItemId(int position)
{
return position;
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
convertView = mInflater.Inflate(Resource.Layout.List_Item, null);
TextView personName = (TextView)convertView.FindViewById(Resource.Id.name);
TextView personMessage = (TextView)convertView.FindViewById(Resource.Id.message);
ImageView personImage = (ImageView)convertView.FindViewById(Resource.Id.imageView);
Person person = personArrayList.ElementAt(position);
personName.Text = person.Name;
if(MainActivity.messages[person.Id].Count != 0)
{
personMessage.Text = MainActivity.messages[person.Id][MainActivity.messages[person.Id].Count - 1];
}
else
{
personMessage.Text = "";
}
personImage.SetImageResource(person.ImageId);
return convertView;
}
}
}
I have a personAdapter class and chat activity has only listView. So I am binding list to listView via adapter. I added some person manually to see chat menu. If I add images to drawable folder, there is no problem. But how do I add images to create new person. I can't add images to drawable at runtime. When I try to read images from external storage. They have no resource id. So person class do not accept that.
{
[Activity(Label = "#string/app_name", Theme = "#style/AppTheme", MainLauncher = true)]
public class MainActivity : AppCompatActivity
{
public static List<Person> persons = new List<Person>();
public static Dictionary<int, List<string>> messages = new Dictionary<int, List<string>>();
PersonAdapter adapter;
private static int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 1;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.activity_main);
persons.Add(new Person(0,"Safa", Resource.Drawable.person));
persons.Add(new Person(1,"Melis", Resource.Drawable.person));
persons.Add(new Person(2,"Orkun", Resource.Drawable.person));
messages[0] = new List<string>();
messages[1] = new List<string>();
messages[2] = new List<string>();
messages[0].Add("Naber?");
messages[0].Add("Nasılsın?");
messages[1].Add("Nerdesin?");
messages[1].Add("Saat Kaç?");
messages[2].Add("Buluşalım mı?");
messages[2].Add("Kaçta?");
ListView listView = (ListView)FindViewById(Resource.Id.listView);
adapter = new PersonAdapter(this,persons);
listView.Adapter = adapter;
listView.ItemClick += (object sender, ItemClickEventArgs e) =>
{
Person person = persons[e.Position];
var intent = new Intent(this, typeof(ChatActivity));
intent.PutExtra("name", person.Name);
intent.PutExtra("id", person.Id);
this.StartActivity(intent);
};
FloatingActionButton fab = (FloatingActionButton)FindViewById(Resource.Id.fab);
fab.Click += delegate
{
var intent = new Intent(this, typeof(AddContactActivity));
this.StartActivity(intent);
};
if(Intent.GetStringExtra("person") != null)
{
Person newPerson = JsonConvert.DeserializeObject<Person> (Intent.GetStringExtra("person"));
persons.Add(newPerson);
messages.Add(newPerson.Id, new List<string>());
adapter.NotifyDataSetChanged();
}
}
}
}
AddContactActivity:
public class AddContactActivity : Activity
{
private ImageView imageView;
private Button loadButton;
private Button addButton;
private EditText nameEditText, surnameEditText;
private int index;
private string filename;
public static int SELECT_IMAGE = 1001;
Drawable drawable;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.activity_addContact);
imageView = FindViewById<ImageView>(Resource.Id.load_image_imageView);
loadButton = FindViewById<Button>(Resource.Id.load_image_button);
addButton = FindViewById<Button>(Resource.Id.add_contact_button);
nameEditText = FindViewById<EditText>(Resource.Id.name_editText);
surnameEditText = FindViewById<EditText>(Resource.Id.surname_editText);
loadButton.Click += loadButtonClicked;
addButton.Click += addContactButtonClicked;
}
private void addContactButtonClicked(object sender, EventArgs e)
{
index = MainActivity.messages.Count;
Console.WriteLine(index);
Person newPerson = new Person(index, nameEditText.Text + " " + surnameEditText.Text, drawable.GetHashCode());
Intent intent = new Intent(this, typeof(MainActivity));
intent.PutExtra("person", JsonConvert.SerializeObject(newPerson));
StartActivity(intent);
}
private void loadButtonClicked(object sender, EventArgs e)
{
if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.ReadExternalStorage) == (int)Permission.Granted)
{
Intent = new Intent();
Intent.SetType("image/*");
Intent.SetAction(Intent.ActionGetContent);
StartActivityForResult(Intent.CreateChooser(Intent, "Select Picture"), SELECT_IMAGE);
}
else
{
ActivityCompat.RequestPermissions(this, new String[] { Manifest.Permission.ReadExternalStorage }, 12);
}
}
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
if ((requestCode == SELECT_IMAGE) && (resultCode == Result.Ok) && (data != null))
{
Android.Net.Uri uri = data.Data;
Bitmap bitmap = MediaStore.Images.Media.GetBitmap(ContentResolver, uri);
imageView.SetImageBitmap(bitmap);
}
else
{
Toast.MakeText(this.ApplicationContext, "You haven't picked an image", ToastLength.Short).Show();
}
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
{
if (requestCode == 12)
{
if ((grantResults.Length == 1) && (grantResults[0] == Permission.Granted))
{
Intent = new Intent();
Intent.SetType("image/*");
Intent.SetAction(Intent.ActionGetContent);
StartActivityForResult(Intent.CreateChooser(Intent, "Select Picture"), SELECT_IMAGE);
}
}
else
{
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
Do you want to achieve the result like this GIF?
Based on your code, you need serveral steps to achieve it.
First of all, we should use Convert Bitmap to Base64 string to achieve it, we can create a MyUtils.cs
public class MyUtils
{
public static string ConvertBitMapToString(Bitmap bitmap)
{
byte[] bitmapData;
using (MemoryStream stream = new MemoryStream())
{
bitmap.Compress(Android.Graphics.Bitmap.CompressFormat.Jpeg, 50, stream);
bitmapData = stream.ToArray();
}
string ImageBase64 = Convert.ToBase64String(bitmapData);
return ImageBase64;
}
public static Bitmap ConvertStringToBitmap(string mystr)
{
byte[] decodedString = Base64.Decode(mystr, Base64.Default);
Bitmap decodedByte = BitmapFactory.DecodeByteArray(decodedString, 0, decodedString.Length);
return decodedByte;
}
}
Then we should change the type of ImageId to string like following code.
public string ImageId // property
{
get { return imageId; } // get method
set { imageId = value; } // set method
}
Please change set the Image way in MainActiviy and Adapter.
Here is my demo, you can download it and refer to it.
https://github.com/851265601/TransferImageBtwActivities
I have three activities, I capture all data but one from DetailActivity upon button click and save in database using Room; My intention is to insert all these data into the database and start ReviewActivity so as to get the arraylist of reviews and also insert it in the database. Everything seems to work fine until when I want to view review offline because I believe it has been saved, reviews does not get loaded.
This is my DetailActivity,
TextView overview_tv; ImageView image_tv; TextView name_tv; TextView ratings; Context context; TextView release_date; ImageView backdrop_poster; private ExpandableHeightListView trailers; public static ArrayList<Youtube> youtube; public static ArrayList<Review> reviews; TrailerViewAdapter adapter; public static DataObject data; DataObject dataObject; ArrayList<Review> savedReview; private static final String IMAGE_URL = "http://image.tmdb.org/t/p/w185/"; private static final String THE_MOVIEDB_URL2 = "https://api.themoviedb.org/3/movie/"; private static final String MOVIE_QUERY2 = "api_key"; private static final String API_KEY2 = "6cc4f47bd4a64e0117e157b79072ae37"; private static String SEARCH_QUERY2 = "videos"; public static int movieId; Button viewReviews; Button favourite; String movieRating; private static final int YOUTUBE_SEARCH_LOADER = 23; private static final int REVIEW_SEARCH_LOADER = 24; File file; String name; String overview; String releaseDate; int switcher; public static ArrayList<Review> favouriteReviews; TextView trev; AppDatabase mDb; //Navigation arrow on the action bar #Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == android.R.id.home) { NavUtils.navigateUpFromSameTask(this); } return super.onOptionsItemSelected(item); } #Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_detail); mDb = AppDatabase.getInstance(getApplicationContext()); youtube = new ArrayList<Youtube>(); reviews = new ArrayList<Review>(); adapter = new TrailerViewAdapter(this, youtube); //Credit to Paolorotolo #github trailers = findViewById(R.id.expandable_list); trailers.setAdapter(adapter); trailers.setExpanded(true); //Navigation arrow on the acton bar; check also override onOptionsItemSelected ActionBar actionBar = this.getSupportActionBar(); if (actionBar != null) { actionBar.setDisplayHomeAsUpEnabled(true); } context = getApplicationContext(); Intent intent = getIntent(); if (intent == null) { closeOnError(); } switcher = getIntent().getIntExtra("switch", 3); overview_tv = findViewById(R.id.overview); image_tv = findViewById(R.id.image); name_tv = findViewById(R.id.name); ratings = findViewById(R.id.ratings); release_date = findViewById(R.id.release_date); backdrop_poster = findViewById(R.id.backdrop_poster); trev = findViewById(R.id.review_show); viewReviews = findViewById(R.id.review_button); favourite = findViewById(R.id.favourite_button); addListenerOnRatingBar(ratings); if (switcher != 2) { favourite.setVisibility(View.INVISIBLE); dataObject = (DataObject) getIntent().getParcelableExtra("array"); final String favouriteName = dataObject.getName(); final String favouriteOverview = dataObject.getOverview(); final String favouriteReleaseDate = dataObject.getReleaseDate(); ArrayList<Youtube> savedTrailer = dataObject.getTrailers(); savedReview = dataObject.getMovieReviews(); movieRating = dataObject.getRating(); name_tv.setText(favouriteName); overview_tv.setText(favouriteOverview); ratings.setText("Rating: " + movieRating); release_date.setText("Release Date: " + favouriteReleaseDate);// Toast.makeText(this, "Testing Reviews " + savedReview.get(0).getAuthor(), Toast.LENGTH_SHORT).show(); String imagePath = name_tv.getText().toString() + "0i"; String backdropPath = name_tv.getText().toString() + "1b"; try { DataObjectAdapter.downloadImage(imagePath, image_tv, this); } catch (Exception e) { e.printStackTrace(); } try { DataObjectAdapter.downloadImage(backdropPath, backdrop_poster, context); } catch (Exception e) { e.printStackTrace(); } if (savedTrailer != null) { TrailerViewAdapter lv = new TrailerViewAdapter(DetailActivity.this, savedTrailer); trailers.setAdapter(lv); switcher = 3; } } else { name = getIntent().getStringExtra("Name"); overview = getIntent().getStringExtra("Overview"); final String image = getIntent().getStringExtra("Image"); movieId = getIntent().getIntExtra("movieId", 1); final String backdrop = getIntent().getStringExtra("backdrop"); releaseDate = getIntent().getStringExtra("releaseDate"); movieRating = getIntent().getStringExtra("rating"); Log.i("this", "switch " + switcher); name_tv.setText(name); overview_tv.setText(overview); ratings.setText("Rating: " + movieRating); release_date.setText("Release Date: " + releaseDate); //load backdrop poster Picasso.with(context) .load(IMAGE_URL + backdrop) .fit() .placeholder(R.drawable.placeholder_image) .error(R.drawable.placeholder_image) .into(backdrop_poster); Picasso.with(context) .load(IMAGE_URL + image) .fit() .placeholder(R.drawable.placeholder_image) .error(R.drawable.placeholder_image) .into(image_tv); getSupportLoaderManager().initLoader(YOUTUBE_SEARCH_LOADER, null, this); //getSupportLoaderManager().initLoader(REVIEW_SEARCH_LOADER, null, this); //loadTrailers(); //loadReviews(); //populateKeys(); } /** * Here manages the views(list) for reviews */ viewReviews.setOnClickListener(new View.OnClickListener() { #Override public void onClick(View v) { if (switcher == 3) { startActivity(new Intent(DetailActivity.this, ReviewActivity.class) .putExtra("switch", 3)); } else { Log.i("this", "I am from initial" + switcher); startActivity(new Intent(DetailActivity.this, ReviewActivity.class).putExtra("id", movieId)); } } } ); favourite.setOnClickListener(new View.OnClickListener() { #Override public void onClick(View v) { data = new DataObject(); data.setName(name); data.setOverview(overview); data.setRating(movieRating); data.setReleaseDate(releaseDate); data.setTrailers(youtube);// data.setMovieReviews(reviews); try { saveImage(name_tv.getText().toString() + "0i", image_tv); saveImage(name_tv.getText().toString() + "1b", backdrop_poster); } catch (IOException e) { e.printStackTrace(); } Toast.makeText(context, "The movie is saved as a favourite", Toast.LENGTH_LONG).show(); AppExecutors.getInstance().diskIO().execute(new Runnable() { #Override public void run() { mDb.dataDao().insertData(data); } }); startActivity(new Intent(DetailActivity.this, ReviewActivity.class).putExtra("id", movieId) .putExtra(ReviewActivity.EXTRA_DATA_ID, 20)); } } ); }
And my ReviewActivity
public class ReviewActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<ArrayList<Review>>{ public static ArrayList<Review> reviews; public static List<DataObject> favouriteReviews; public static RecyclerView reviewList; ArrayList<Review> r; private static final int REVIEW_SEARCH_LOADER = 24; private static final String MOVIE_QUERY3 = "api_key"; private static final String API_KEY3 = "6cc4f47bd4a64e0117e157b79072ae37"; private static String SEARCH_QUERY3 = "reviews"; private static final String THE_MOVIEDB_URL3 = "https://api.themoviedb.org/3/movie/"; private static int movId; public static final String EXTRA_DATA_ID = "extraDataId"; private static final int DEFAULT_TASK_ID = -1; private int mTaskId = DEFAULT_TASK_ID; DataObject data1; AppDatabase mDb; ReviewAdapter revAdapter; int loaderSwitch; #Override protected void onResume() { super.onResume(); } #Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_review); mDb = AppDatabase.getInstance(getApplicationContext()); reviews = new ArrayList<Review>(); favouriteReviews = new ArrayList<DataObject>(); reviewList = findViewById(R.id.review_list); LinearLayoutManager layoutManager = new LinearLayoutManager(getApplicationContext()); reviewList.setLayoutManager(layoutManager); reviewList.setHasFixedSize(true); int switcher = getIntent().getIntExtra("switch", 1); Intent intent = getIntent(); if (intent == null) { finish(); } Log.i("this", "swithcer " + switcher); Log.i("this loader", "Loader " + loaderSwitch); if (switcher == 3){ DataObject dataObject = (DataObject) getIntent().getParcelableExtra("ArrayOfReviews"); if (dataObject != null){ ArrayList<Review> movieReviews = dataObject.getMovieReviews(); Toast.makeText(this, "There are reviews saved", Toast.LENGTH_LONG).show(); revAdapter = new ReviewAdapter(this, movieReviews ); reviewList.setAdapter(revAdapter); } } else { movId = getIntent().getIntExtra("id", 20); revAdapter = new ReviewAdapter(this, reviews); reviewList.setAdapter(revAdapter); loadReviews(); //populateReview(); } DividerItemDecoration decoration = new DividerItemDecoration(this, VERTICAL); reviewList.addItemDecoration(decoration); } #Override protected void onStart() { super.onStart(); //loadReviews(); } public static URL buildUrl3(String stringUrl) { Uri uri = Uri.parse(THE_MOVIEDB_URL3).buildUpon() .appendPath(stringUrl) .appendPath(SEARCH_QUERY3) .appendQueryParameter(MOVIE_QUERY3, API_KEY3) .build(); URL url = null; try { url = new URL(uri.toString()); } catch (MalformedURLException exception) { Log.e(TAG, "Error creating URL", exception); } return url; } public void loadReviews(){ // COMPLETED (19) Create a bundle called queryBundle Bundle queryBundle = new Bundle(); // COMPLETED (20) Use putString with SEARCH_QUERY_URL_EXTRA as the key and the String value of the URL as the value// queryBundle.putString(SEARCH_QUERY_URL_EXTRA, url.toString()); // COMPLETED (21) Call getSupportLoaderManager and store it in a LoaderManager variable LoaderManager loaderManager = getSupportLoaderManager(); // COMPLETED (22) Get our Loader by calling getLoader and passing the ID we specified Loader<ArrayList<Review>> movieReviews = loaderManager.getLoader(REVIEW_SEARCH_LOADER); // COMPLETED (23) If the Loader was null, initialize it. Else, restart it. if (movieReviews == null) { loaderManager.initLoader(REVIEW_SEARCH_LOADER, queryBundle, this); } else { loaderManager.restartLoader(REVIEW_SEARCH_LOADER, queryBundle, this); } } #Override public Loader<ArrayList<Review>> onCreateLoader(int id, Bundle args) { return new AsyncTaskLoader<ArrayList<Review>>(this) { #Override protected void onStartLoading() { super.onStartLoading(); forceLoad(); } #Override public ArrayList<Review> loadInBackground() { String g = String.valueOf(movId); // Create URL object URL url = buildUrl3(g); // Perform HTTP request on the URL and receive a JSON response back String jsonResponse = ""; try { jsonResponse = getResponseFromHttpUrl(url); } catch (Exception e) { e.printStackTrace(); } reviews = MovieJsonUtils.parseReview(jsonResponse); return reviews; } }; } #Override public void onLoadFinished(Loader<ArrayList<Review>> loader, ArrayList<Review> dat) { if (reviews != null) { Intent intent = getIntent(); if (intent != null && intent.hasExtra(EXTRA_DATA_ID)) { //mButton.setText(R.string.update_button); if (mTaskId == DEFAULT_TASK_ID) { mTaskId = intent.getIntExtra(EXTRA_DATA_ID, DEFAULT_TASK_ID); AppExecutors.getInstance().diskIO().execute(new Runnable() { #Override public void run() { data.setMovieReviews(reviews); mDb.dataDao().updateData(data); //mDb.dataDao().insertData(data); final List<DataObject> task = mDb.dataDao().loadById(mTaskId); runOnUiThread(new Runnable() { #Override public void run() { populateUI(task); } }); } }); } } else { ReviewAdapter lv = new ReviewAdapter(ReviewActivity.this, reviews); reviewList.setAdapter(lv); } } } #Override public void onLoaderReset(Loader<ArrayList<Review>> loader) { }
Data gets loaded from MainActivity, the saved data is passed on to other activities as a parcellable bundle via intent, the passed data is displayed in DetailActivity but not in ReviewActivity.
Alternatively, if I can load reviews alongside YouTube keys from DetailActivity, I believe I can handle the database issue from there, but two Loaders wouldn't just work together, the app crashes; I am aware two AsyncTasks concurrently run together solved this problem, but I prefer to use Loaders because of performance on configuration change
Im building an app where I have an Array list with strings and a button.
When I press the button it deletes the string from the list (with string.remove) and display it in another activity..
The problem is that when I close the app and reopen it everything goes back to normal. How to save the changes made?
Here is the code:
public class TasksActivity extends AppCompatActivity {
private static ArrayList<String> list;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_tasks);
final Button tasksbtn = (Button) findViewById(R.id.btnfortasks);
Button checkTask = (Button) findViewById(R.id.remove_case);
final TextView tasksView = (TextView) findViewById(R.id.tasks_textView);
final ArrayList<String> tasks = new ArrayList<String>();
tasks.add("one");
tasks.add("two");
tasks.add("three");
tasks.add("four");
tasks.add("five");
tasks.add("six");
Collections.shuffle(tasks);
tasksView.setText(tasks.get(0));
assert tasksbtn != null;
tasksbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Collections.shuffle(tasks);
tasksView.setText(tasks.get(0));
}
});
checkTask.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(TasksActivity.this, CompletedTasks.class);
intent.putExtra("completedTasks", tasks.get(0));
tasks.remove(tasks.get(0));
startActivity(intent);
}
});
}
}
And the second Activity
public class CompletedTasks extends AppCompatActivity {
String completedTasks;
Global_Variable object = new Global_Variable();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_completed_tasks);
TextView completedTasksView = (TextView) findViewById(R.id.completed_tasks);
Intent intent = getIntent();
completedTasks = intent.getExtras().getString("completedTasks");
object.tasks.add(completedTasks + "\n");
String a = "";
for (int i = 0; i < object.tasks.size(); i++) {
a += object.tasks.get (i);
completedTasksView.setText(a);
Log.d("a", "a---------" + a);
}
}
}
You should probably give try to serialization. Please take look over below sample example.
public class SerializationDemo extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Person person = new Person();
person.setName("CoderzHeaven");
person.setAddress("CoderzHeaven India");
person.setNumber("1234567890");
//save the object
saveObject(person);
// Get the Object
Person person1 = (Person)loadSerializedObject(new File("/sdcard/save_object.bin")); //get the serialized object from the sdcard and caste it into the Person class.
System.out.println("Name : " + person1.getName());
}
public void saveObject(Person p){
try
{
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("/sdcard/save_object.bin"))); //Select where you wish to save the file...
oos.writeObject(p); // write the class as an 'object'
oos.flush(); // flush the stream to insure all of the information was written to 'save_object.bin'
oos.close();// close the stream
}
catch(Exception ex)
{
Log.v("Serialization Save Error : ",ex.getMessage());
ex.printStackTrace();
}
}
public Object loadSerializedObject(File f)
{
try
{
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(f));
Object o = ois.readObject();
return o;
}
catch(Exception ex)
{
Log.v("Serialization Read Error : ",ex.getMessage());
ex.printStackTrace();
}
return null;
}
Person implements Serializable //Added implements Serializable
{
String name="";
private String number="";
private String address="";
private static final long serialVersionUID = 46543445;
public void setName(String name)
{
this.name = name;
}
public void setNumber(String number)
{
this.number = number;
}
public void setAddress(String address)
{
this.address = address;
}
public String getName()
{
return name;
}
public String getNumber()
{
return number;
}
public String getAddress()
{
return address;
}
}
}
You could try saving your changes to the SharedPreferences. Then when you resatrt your app, read the changes from your ShraredPreferences and apply it to your ListView or whatever you are using.
You can read more about SharedPreferences here: https://developer.android.com/training/basics/data-storage/shared-preferences.html
I want to pass ArrayList via Intent to another activity. However, the code doesn't give any errors but List is always empty. Any idea what i'm doing wrong ? ty
Activity1
private ArrayList<ResimBean> rbList = new ArrayList<ResimBean>();
Bitmap bmp = (Bitmap) data.getExtras().get("data");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] thumbArray = stream.toByteArray();
Uri selectedImageUri = data.getData();
String fotopath = getRealPathFromURI(selectedImageUri);
ResimBean rb = new ResimBean(Parcel.obtain());
// rb.setResim(bar);
rb.setThumbnail(thumbArray);
rb.setPath(fotopath);
rbList.add(rb);
Intent intent = new Intent(getApplicationContext(), ResimListActivity.class);
intent.putParcelableArrayListExtra("reslist",rbList);
startActivityForResult(intent, 100);
Activity2
Bundle extras = getIntent().getExtras();
if (extras != null) {
try {
Intent i = getIntent();
ArrayList<ResimBean> rbList = i.getParcelableArrayListExtra("reslist");
} catch (Exception ex) {
String msg = ex.getMessage();
}
}
Its not giving any error but list is always empty.
EDIT
Added the code how i fill in list.
EDIT 2
Something wrong with my Parcelable class or what ?
public class ResimBean implements Parcelable {
private int Id;
private int HataBildirimId;
private byte[] Resim;
private byte[] Thumbnail;
public byte[] getThumbnail() {
return Thumbnail;
}
public void setThumbnail(byte[] thumbnail) {
Thumbnail = thumbnail;
}
private String Path;
public String getPath() {
return Path;
}
public void setPath(String path) {
Path = path;
}
public int getHataBildirimId() {
return HataBildirimId;
}
public void setHataBildirimId(int hataBildirimId) {
HataBildirimId = hataBildirimId;
}
public int getId() {
return Id;
}
public void setId(int id) {
Id = id;
}
public byte[] getResim() {
return Resim;
}
public void setResim(byte[] resim) {
Resim = resim;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(HataBildirimId);
dest.writeByteArray(Resim);
dest.writeByteArray(Thumbnail);
}
public ResimBean(Parcel in) {
readFromParcel(in);
}
public void readFromParcel(Parcel in){
this.HataBildirimId = in.readInt();
this.Resim = new byte[in.readInt()];
this.Thumbnail = new byte[in.readInt()];
}
public static final Parcelable.Creator<ResimBean> CREATOR = new Parcelable.Creator<ResimBean>() {
#Override
public ResimBean createFromParcel(Parcel in) {
return new ResimBean(in);
}
#Override
public ResimBean[] newArray(int size) {
return new ResimBean[size];
}
};
The way you are showing, you create a new ArrayList<> and send it empty as extra via intent to the next activity.
Where exactly do you populate your ArrayList?
You should do something like this:
private ArrayList<ResimBean> rbList = new ArrayList<ResimBean>();
//populate rbList using adapter, then call intent
Intent intent = new Intent(getApplicationContext(), ResimListActivity.class);
intent.putParcelableArrayListExtra("reslist",rbList);
startActivityForResult(intent, 100);
Otherwise, the rbList you send as extra will always be empty. It sounds obvious but I don't know how you are doing it, so this is my best guess.
You can follow this tutorial:
http://aryo.lecture.ub.ac.id/android-passing-arraylist-of-object-within-an-intent/
I got it working like this
Bundle extras = this.getIntent().getExtras();
if (extras != null) {
try {
Intent i = getIntent();
ArrayList<ResimBean> rbList = (ArrayList<ResimBean>) i.getExtras().get("reslist");
Log.i("mytag", " "+i.getExtras().get("reslist").toString());
Log.i("mytag", " "+rbList.get(0).toString());
} catch (Exception ex) {
String msg = ex.getMessage();
}
}
With the rbList in Activity2 size=1,
With your code I was getting size=0
I have an app that shows notification in a listview. I want these notifications to be saved so that if I open the app and see notification I can see these notifications again when I close the app and then open it. I tried this
but nothing was saved.
Another major question is how can I run this app in background? So if notification is received the app lists that notification in the listview without being opened?
My Code
public class MainActivity extends Activity {
ListView list;
CustomListAdapter adapter;
ArrayList<Model> modelList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
modelList = new ArrayList<Model>();
adapter = new CustomListAdapter(getApplicationContext(), modelList);
list=(ListView)findViewById(R.id.list);
list.setAdapter(adapter);
LocalBroadcastManager.getInstance(this).registerReceiver(onNotice, new IntentFilter("Msg"));
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);//Menu Resource, Menu
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_settings:
Intent intent = new Intent(
"android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");
startActivity(intent);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private BroadcastReceiver onNotice= new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String pack = intent.getStringExtra("package");
String title = intent.getStringExtra("title");
String text = intent.getStringExtra("text");
//int id = intent.getIntExtra("icon",0);
Context remotePackageContext = null;
if (pack.contains("fake")){
try {
// remotePackageContext = getApplicationContext().createPackageContext(pack, 0);
// Drawable icon = remotePackageContext.getResources().getDrawable(id);
// if(icon !=null) {
// ((ImageView) findViewById(R.id.imageView)).setBackground(icon);
// }
byte[] byteArray = intent.getByteArrayExtra("icon");
Bitmap bmp = null;
if (byteArray != null) {
bmp = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);
}
Model model = new Model();
if(text.contains("") && !text.contains(" messages")) {
model.setName(title + ": " + text);
model.setImage(bmp);
if (modelList != null) {
modelList.add(model);
adapter.notifyDataSetChanged();
} else {
modelList = new ArrayList<Model>();
modelList.add(model);
adapter = new CustomListAdapter(getApplicationContext(), modelList);
list = (ListView) findViewById(R.id.list);
list.setAdapter(adapter);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
};
}
Make a class Cache which has the capabilities to serialize and deserialize data.
public class Cache {
private static Cache CACHE;
public static Cache get() {
if (!SharedPreferencesHelper.isCacheAvailable()) {
CACHE = new Cache();
SharedPreferencesHelper.saveCache(CACHE);
} else {
CACHE = SharedPreferencesHelper.getCache();
}
return CACHE;
}
ArrayList<Taxonomy> cachedTaxonomies;
public Cache() {
cachedTaxonomies = new ArrayList<Taxonomy>();
}
public ArrayList<Taxonomy> getCachedTaxonomies() {
return cachedTaxonomies;
}
public static String serialize(Cache cache) {
GsonBuilder builder = new GsonBuilder();
Gson gson = builder.enableComplexMapKeySerialization().setPrettyPrinting().create();
return gson.toJson(cache);
}
public static Cache deserialize(String json) {
Type type = new TypeToken<Cache>() {
}.getType();
return new Gson().fromJson(json, type);
}
public void update() {
SharedPreferencesHelper.saveCache(this);
}
}
Here Taxonomy is a model.
Below is the class which helps you save in SharedPrefs
public class SharedPreferencesHelper {
private static final String PREFS_CACHE = "prefs_cache";
public static SharedPreferences getSharedPreferences() {
return SpreeApplication.getSharedPreferences();
}
// Cache -------------------------------------
public static boolean isCacheAvailable() {
SharedPreferences sharedPreferences = getSharedPreferences();
String json = sharedPreferences.getString(PREFS_CACHE, "");
if(json.equals("")) {
return false;
} else {
return true;
}
}
public static Cache getCache() {
SharedPreferences sharedPreferences = getSharedPreferences();
String json = sharedPreferences.getString(PREFS_CACHE, "");
if(json.equals("")) {
return null;
} else {
return Cache.deserialize(json);
}
}
public static void saveCache(Cache cache) {
saveString(PREFS_CACHE, Cache.serialize(cache));
}
// -----------------------------------------------------
private static void saveString(String prefKey, String value) {
SharedPreferences sharedPreferences = getSharedPreferences();
SharedPreferences.Editor prefEditor = sharedPreferences.edit();
prefEditor.putString(prefKey, value);
prefEditor.commit();
}
private static void saveBoolean(String prefKey, boolean value) {
SharedPreferences sharedPreferences = getSharedPreferences();
SharedPreferences.Editor prefEditor = sharedPreferences.edit();
prefEditor.putBoolean(prefKey, value);
prefEditor.commit();
}
}
To save write this :
List<Taxonomy> taxonomies = new ArrayList<Taxonomy>();
Cache cache = Cache.get();
cache.getCachedTaxonomies().clear();
cache.getCachedTaxonomies().addAll(taxonomies);
SharedPreferencesHelper.saveCache(cache);
this is my spreeapplication class which is a custom application class
Remember you have to mention in manifest if you create a custom application class
public class SpreeApplication extends Application{
private final static String DEFAULT_PREFERENCES = "spree";
private static SharedPreferences sharedPreferences;
private static Context applicationContext;
#Override
public void onCreate() {
super.onCreate();
applicationContext = this;
sharedPreferences = getSharedPreferences(DEFAULT_PREFERENCES, Context.MODE_PRIVATE);
}
public static SharedPreferences getSharedPreferences() {
return sharedPreferences;
}
public static SharedPreferences.Editor getSharedPreferencesEditor() {
return sharedPreferences.edit();
}
public static Context getContext() {
return applicationContext;
}
}