Parcelable ArrayList is always empty - android

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

Related

How do I bind images from gallery to imageView at runtime?

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

How to Using uri get image in RecyclerView?

I'm working on an app in the Android studio. Click the button in the Fragment to open a dialog box and include a picture and a brief description. (Pictures are taken from your gallery.) Click OK to close the dialog box and include the image and description in the RecyclerView that exists in the Fragment. But this code that I've woven has a description, but it doesn's image. I wanted to hear a solution to this, so I asked you a question.
I'd appreciate your reply!
To briefly explain how my code works, when I receive an image from the dialog box, I send the path (/storage/emulated/0/Pictures/a.jpg) of the file as a toast message, and as soon as the dialog is closed, the imagepath and description are transferred to the String form, and the imagepath is converted from Fragment to uri and changed to Bitmap using it to apply to RecyclerView.
Below is my code.
Fragment.java
btn_addlist = view.findViewById(R.id.btn_addlist);
btn_addlist.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DialogFragment_cus dialog = new DialogFragment_cus();
dialog.show(getActivity().getSupportFragmentManager(), "tag");
dialog.setDialogResult(new DialogFragment_cus.OnMyDialogResult() {
// result : uri, result2 : dlg_edtName, result3 : dlg_edtSubtitle
#Override
public void finish(String result, String result2, String result3) {
imageUri = result; RecyclerInputName = result2;
RecyclerInputSubtitle = result3;
Uri uri = Uri.parse("file://" + imageUri);
Bitmap bitmap = null;
try {
bitmap = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), uri);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
RecyclerItem_cus item = new RecyclerItem_cus(bitmap, RecyclerInputName, RecyclerInputSubtitle);
mArrayList.add(0, item);
mAdapter.notifyDataSetChanged();
Toast.makeText(getActivity(), "finish.", Toast.LENGTH_SHORT).show();
}
});
}
});
DialogFragment.java
dlg_AddButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_PICK);
startActivityForResult(intent, 1);
}
});
dlg_ok.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DialogFragment_cus fragment = new DialogFragment_cus();
String input1 = dlg_edtName.getText().toString();
String input2 = dlg_edtSubtitle.getText().toString();
if(fragment != null) {
if(mDialogResult != null ) {
mDialogResult.finish(name_Str, input1, input2);
}
}
dismiss();
}
});
dlg_cancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dismiss();
}
});
return view;
}
public void setDialogResult(OnMyDialogResult dialogResult){
mDialogResult = dialogResult;
}
public interface OnMyDialogResult{
void finish(String result, String result2, String result3);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1 && resultCode == RESULT_OK) {
try {
name_Str = getImageNameToUri(data.getData());
InputStream in = getActivity().getContentResolver().openInputStream(data.getData());
Bitmap img = BitmapFactory.decodeStream(in);
in.close();
dlg_ImageView.setImageBitmap(img);
dlg_ImageView.setBackgroundResource(android.R.color.white);
Toast.makeText(getActivity(), "name_Str : "+name_Str , Toast.LENGTH_LONG).show();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public String getImageNameToUri(Uri uri) {
String[] projection = {MediaStore.Images.Media.DATA};
Cursor cursor = getActivity().getContentResolver().query(uri, projection, null, null, null);
getActivity().startManagingCursor(cursor);
int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(columnIndex);
}
RecyclerView_cusAdapter.java
#Override
public void onBindViewHolder(#NonNull final MyViewHolder myViewHolder, int i) {
final RecyclerItem_cus item = items.get(i);
if (item != null) {
Glide.with(context)
.load(item.getImage())
.asBitmap()
.format(DecodeFormat.PREFER_ARGB_8888)
.into(new SimpleTarget<Bitmap>() {
#Override
public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
myViewHolder.cus_img.setImageBitmap(resource);
}
});
myViewHolder.cus_title.setText(item.getTitle());
myViewHolder.cus_subtitle.setText(item.getSubTitle());
}
}
#Override
public int getItemCount() {
return this.items.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView cus_title;
TextView cus_subtitle;
ImageView cus_img;
public MyViewHolder(View itemView) {
super(itemView);
cus_title = itemView.findViewById(R.id.cus_title);
cus_subtitle = itemView.findViewById(R.id.cus_subtitle);
cus_img = itemView.findViewById(R.id.cus_img);
}
}
RecyclerItem_cus.java
public class RecyclerItem_cus {
private Bitmap image;
private String title;
private String subTitle;
public RecyclerItem_cus(Bitmap image, String title, String subTitle) {
this.image = image;
this.title = title;
this.subTitle = subTitle;
}
public Bitmap getImage() {
return image;
}
public String getTitle() {
return title;
}
public String getSubTitle() {
return subTitle;
}
You can try to use Glide with the File object directly :
Glide.with(mContext)
.load(new File(item.getImage())) // Uri of the picture
.into(myViewHolder.cus_img);

I want to save data in SecondActivity from FirstActivity using Room

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

Save change String on restart in Android

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

Document Missing - Google Cloud Print

I am trying to use google cloud print with my project on android studio to print out a pdf file. I am storing the file in the assets folder of the project and when I go to print it say "Document Missing". this is my java code:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void onPrintClick(View v) {
String path = Environment.getExternalStorageDirectory().getAbsolutePath()
+ "/monsoon.pdf";
File file = new File(path);
if (file.exists()) {
Uri uri = Uri.fromFile(file);
Intent printIntent = new Intent(this, PrintDialogActivity.class);
printIntent.setDataAndType(uri, "application/pdf");
printIntent.putExtra("title", "Gaurang");
startActivity(printIntent);
} else {
Toast.makeText(getApplicationContext(), "No file",
Toast.LENGTH_SHORT).show();
}
}
}
and Here is Android Code for Google Cloud Print with some modification on class PrintDialogJavaScriptInterface...ie. applying annotations #JavascriptInterface
public class PrintDialogActivity extends Activity {
private static final String PRINT_DIALOG_URL = "https://www.google.com/cloudprint/dialog.html";
private static final String JS_INTERFACE = "AndroidPrintDialog";
private static final String CONTENT_TRANSFER_ENCODING = "base64";
private static final String ZXING_URL = "http://zxing.appspot.com";
private static final int ZXING_SCAN_REQUEST = 65743;
/**
* Post message that is sent by Print Dialog web page when the printing
* dialog needs to be closed.
*/
private static final String CLOSE_POST_MESSAGE_NAME = "cp-dialog-on-close";
/**
* Web view element to show the printing dialog in.
*/
private WebView dialogWebView;
/**
* Intent that started the action.
*/
Intent cloudPrintIntent;
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.activity_print_dialog);
dialogWebView = (WebView) findViewById(R.id.webview);
cloudPrintIntent = this.getIntent();
WebSettings settings = dialogWebView.getSettings();
settings.setJavaScriptEnabled(true);
dialogWebView.setWebViewClient(new PrintDialogWebClient());
dialogWebView.addJavascriptInterface(
new PrintDialogJavaScriptInterface(), JS_INTERFACE);
dialogWebView.loadUrl(PRINT_DIALOG_URL);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (requestCode == ZXING_SCAN_REQUEST && resultCode == RESULT_OK) {
dialogWebView.loadUrl(intent.getStringExtra("SCAN_RESULT"));
}
}
final class PrintDialogJavaScriptInterface {
#JavascriptInterface
public String getType() {
return cloudPrintIntent.getType();
}
#JavascriptInterface
public String getTitle() {
return cloudPrintIntent.getExtras().getString("title");
}
#JavascriptInterface
public String getContent() {
try {
ContentResolver contentResolver = getContentResolver();
InputStream is = contentResolver
.openInputStream(cloudPrintIntent.getData());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[4096];
int n = is.read(buffer);
while (n >= 0) {
baos.write(buffer, 0, n);
n = is.read(buffer);
}
is.close();
baos.flush();
return Base64
.encodeToString(baos.toByteArray(), Base64.DEFAULT);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
#JavascriptInterface
public String getEncoding() {
return CONTENT_TRANSFER_ENCODING;
}
#JavascriptInterface
public void onPostMessage(String message) {
if (message.startsWith(CLOSE_POST_MESSAGE_NAME)) {
finish();
}
}
}
private final class PrintDialogWebClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.startsWith(ZXING_URL)) {
Intent intentScan = new Intent(
"com.google.zxing.client.android.SCAN");
intentScan.putExtra("SCAN_MODE", "QR_CODE_MODE");
try {
startActivityForResult(intentScan, ZXING_SCAN_REQUEST);
} catch (ActivityNotFoundException error) {
view.loadUrl(url);
}
} else {
view.loadUrl(url);
}
return false;
}
#Override
public void onPageFinished(WebView view, String url) {
if (PRINT_DIALOG_URL.equals(url)) {
// Submit print document.
view.loadUrl("javascript:printDialog.setPrintDocument(printDialog.createPrintDocument("
+ "window."
+ JS_INTERFACE
+ ".getType(),window."
+ JS_INTERFACE
+ ".getTitle(),"
+ "window."
+ JS_INTERFACE
+ ".getContent(),window."
+ JS_INTERFACE
+ ".getEncoding()))");
// Add post messages listener.
view.loadUrl("javascript:window.addEventListener('message',"
+ "function(evt){window." + JS_INTERFACE
+ ".onPostMessage(evt.data)}, false)");
}
}
}
}
I see two things that might be wrong.
In the getContent method you have return "";
when you send the PDF in the onPrintClick method, you are not converting the PDF to base64.
I hope I spotted something interesting :)

Categories

Resources