Currently, my app allows the user to click on a "default avatar pic" and then select from a group of images. This image is then returned to the first activity via "startActivityForResult". My next task is to take the image that is now set in the first activity and send it to a third activity when the user presses the "submit button". Right now, I'm trying the below code, but it's not working as I don't know which image is going to be selected by the user until it's selected. Can anyone help me out here?
findViewById(R.id.buttonSubmit).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, DisplayActivity.class);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.select_avatar);
intent.putExtra("IMAGE", bitmap);
startActivity(intent);
}
});
//second activity
Bitmap bitmap = intent.getParcelableExtra("Bitmap");
imageViewAvatar.findViewById(R.id.imageViewFinalAvatar);
imageViewAvatar.setImageBitmap(bitmap);
You can just simply use the ImageView Id as a integer or string value, then pass it. No need to use any bitmap. Bitmap takes too much memory.
Image should be work as a resource id if the image is selected from your resource folder. If your image comes from cloud, then definitely have a url as a string. So handle it as a string as resource id/file path/url.
int imageID = R.drawable.select_avatar;
findViewById(R.id.buttonSubmit).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, DisplayActivity.class);
intent.putInt("image_id", imageID); // Integer Value
startActivity(intent);
}
});
//second activity
Intent intent = getIntent();
int imageIdValue = intent.getIntExtra("image_id", 0);
imageViewAvatar.setImageResource(0);
imageViewAvatar.setImageResource(imageIdValue);
If you need to receive an ImageView on another activity, you might face scalability problems in the future with your app.
If you have your avatar image on the first activity selected, that drawable selection can be saved in a local storage like Shared Preferences, then in your second activity and any other activity you have on the future you can retrieve that value from SharedPreferences as-well, for example:
Store your Drawable idName: (You DON'T want to store the int id because that id changes if you add more drawables and it can break your app in the future)
int[] drawablesArray = {R.id.monkey, R.id.balloon};
int id = drawablesArray[imageSelectedIndex];
String idName = getResources().getResourceEntryName(id);
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(YourActivityName.this);
SharedPreferences.Editor editor = preferences.edit();
editor.putString("avatarPicture",idName);
editor.apply();
Retrieve your Drawable idName on the second Activity:
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(YourActivityName.this);
int avatarPicture = preferences.getString("avatarPicture", "");
if(!avatarPicture.isEmpty())
{
imageView2ndActivity.setBackgroundResource(getResources().getIdentifier(idName, "drawable", getPackageName()));
}
Hope it helps.
Possibly you miss the knowledge of how getting results from another Activity, please see the official documentation.
The second Activity that have to receive the information, needs to be called by a method called onActivityResult(example from the link)
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// Check which request we're responding to
if (requestCode == PICK_CONTACT_REQUEST) {
// Make sure the request was successful
if (resultCode == RESULT_OK) {
// The user picked a contact.
// The Intent's data Uri identifies which contact was selected.
// Do something with the contact here (bigger example below)
}
}
}
Usually in real life scenarios developers use EventBus or Otto or RxJava (steep learning curve this last one)
Related
I am developing an android app which is used to add text on image and do some editing. I have the main image editing activity (mainEditActivity) where I have my image, textview and editing panel. I can change the selected image in two ways
Select one from the gallery which used the following code
pickGalleryBtn.setOnClickListener((View view) -> {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE);
});
and on activity result
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == PICK_IMAGE && null != data) {
Uri selectedImageUri = data.getData();
Intent intent = new Intent(mainEditActivity, ImageCropActivity.class);
intent.putExtra("image.url", selectedImageUri.toString());
mainEditActivity.startActivity(intent);
} else {
Toast.makeText(getContext(), "There was an error reading the file", Toast.LENGTH_LONG);
}
}
ImageCropActivity will start the MainEditActivity after cropping the image
The user can also download an image by going to another page, which will again go through ImageCropActivity and land on MainEditActivity.
My problem is when user is changing the image through any of the above ways, the preferences (such as, text size, position, color, font ..) set on the textview is getting lost as the MainEditActivity restarts.
Is there any way I can save the textView itself (not just the text) so the user will not lose the preferences. I have tried, passing data intent, sharedprefrences, savedinstancestate etc but they will only allow String or Serializable object (TextView is not serializable)
Thanks Manish
I realized that there is no need to pass/save TextView object. I can consider the MainEditActivity as a parent activity for all other activities where the control is passed to other activities, but not completely. Before I used to start the activity using startActivity method which causes to lose all the data in that activity. Now I have changed the way I am calling the activities using startActivityForResult so that I will set the necessary data from other activities in MaindEditActivity.
I am creating an Android app. One of the functions is to collect some data (item name, item ID and the barcode string) from the user .
Activity1 is a form. User enters the item name and item number manually. For the barcode string, user clicks on the "scan" button then Activity2 (Scanner) is started in order to scan and read the barcode. Once the barcode is read, Activity1 (the form) starts again and all data should appear on the form.
When Activity2 starts by Intent, Activity1 is killed. So, I have to get the item name and item number and store them temporarily before staring the Intent. Then when Activity1 starts again, those data will be rendered on the form again.
Now I am thinking to use Intent Extra to keep the item name and number, and pass them to Activity2 and back to Activity1. Given that Activity2 doesn't need those data, I wonder if that is the right way to do in this scenario. Is there any better way? Should I use Shared Preferences instead?
In Your first activity use put extra argument to intent like this:
// Assuming Activity2.class is second activity
Intent intent = new Intent(this, Activity2.class);
intent.putExtra("variable_name", var); // here you are passing var to second activity
startActivity(intent);
Then in second activity retrieve argument like this:
String var2 = getIntent().getStringExtra(variable_name);
You could create a singleton class and expose setter(for saving) and getter (for retrieving) methods for the model objects (here two private string variables).This class will be alive with your application:
public class MyClass{
private static MyClass instance=null;
public static getInstance(){
if(instance==null){
instance=new MyClass();
}
return instance;
}
private String itemName;
private String itemNumber;
//setter and getter methods here
}
why need to kill the Activity 1, try to call
on Activity 1
declare private int SCAN_BARCODE_REQUEST = 101;
and then
//finish(); dont use this to destroy activity 1
startActivityForResult(new intent(this,Activity2.class), SCAN_BARCODE_REQUEST);
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == SCAN_BARCODE_REQUEST) {
if (resultCode == RESULT_OK) {
String barcode = data.getStringExtra("BARCODE");
//handle your barcode string here
}
}
}
on your Activity 2,
change your start Activity1 with
Intent intent = new Intent();
intent.putExtra("BARCODE", barcodeString);
setResult(RESULT_OK, intent);
finish();
You can use SharedPreferences.
You can learn how to use them here:
https://www.tutorialspoint.com/android/android_shared_preferences.htm
https://developer.android.com/training/basics/data-storage/shared-preferences.html
SharedPreferences is a really good solution for such applications. It is very simple and easy to use and implement.
I have an Activity that uses the following code to retrieve information from another activity:
Bundle extras = getIntent().getExtras();
if (extras != null) {
int tok = extras.getInt("Token");
tempToken += tok;
}
This is the Code inside the first other class that sends this information:
final Button mainMen = (Button) findViewById(R.id.toMainMenu);
mainMen.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent i = new Intent(getApplicationContext(),
Menu.class);
i.putExtra("Token", tok + teTok);
startActivity(i);
}
});
Now i have another Activity that also wants to sen information to the Main Activity like so:
maMenu.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(Campaign.this, Menu.class);
intent.putExtra("Token", player.tokens);
intent.putExtra("Round", player.round);
intent.putExtra("Rank", player.rank);
intent.putExtra("Score", player.score);
intent.putExtra("Sec", player.secondsTapped);
intent.putExtra("Min", player.minutesTapped);
intent.putExtra("Hour", player.hoursTapped);
intent.putExtra("Day", player.daysTapped);
intent.putExtra("LifeTap", player.tapsInLife);
intent.putExtra("SecTap", player.tapsPerSec);
intent.putExtra("TapRo", player.tapps);
startActivity(intent);
}
});
Now my question is, how do i handle these different extras from multiple Activities inside the one Main Activity?
Thank You for your time :)
There are two ways to solve your problem..
1)
You can pass one boolean value to or and int variable with some value.. And retrieve this in your new Activity and check with boolean value or int value and get correct data correspond to Activity.
2) You can save your all Data in Shared Preference. And get your all Data in any Activity.
you can send one boolean value that data is in first class or second class and in MainActivity check the value and get the correct data
this may sounds stupid but I can't wrap my head around it.
I have a custom ListAdapter that populates the rows with images, text and other stuff thats all structured by my models. Now I want that when you click on a (any) image in that list, the camera shall open and the user should be able to take a picture and then the image that was clicked should display the pic that was taken with the cam. Get it?
Now in the adapter I just do something like that:
public View getView(int position, View convertView, ViewGroup parent) {
...stuff...
ImageView image = (ImageView) elementView.findViewById(R.id.element_image);
image.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent takePicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
((Activity) context).startActivityForResult(takePicture, 0);
}
...other stuff...
});
I add for each ImageView a onClick Option that can open the camera and let the user take a picture.
The problem is that the context (my MainActivity) gets a callback on the method 'onActivityResult', but how do I know which callback belongs to which ImageView?
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent)
Is it possible to send a reference within the intent? Or how should it know which intent-call belongs to which ImageView?
I hope you understand my question. Otherwise just ask. Thank you in advance ;)
A quick and easy solution, would be to store the position of your ListAdapter in the SharedPreference. In you onActivityResult, you can extract that SharedPreference again, to know which one was requested:
#Override
public void onClick(View v) {
// Store in shared preferences
SharedPreferences sharedPref = getSharedPreferences("FileName",MODE_PRIVATE);
SharedPreferences.Editor prefEditor = sharedPref.edit();
prefEditor.putInt("position_in_adapter",position);
prefEditor.commit();
Intent takePicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
((Activity) context).startActivityForResult(takePicture, 0);
}
And than in your activity result:
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent){
SharedPreferences sharedPref = context.getSharedPreferences("FileName",MODE_PRIVATE);
// Extract again
int position= sharedPref.getInt("position_in_adapter", -1);
}
EDIT: Another option is to use your requestCode as your position. E.g.
startActivityForResult(takePicture, position);
and extract it again in your onActivityResult:
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent){
// requestCode is the position in your adapter
}
This is what i want to do. When a user starts the game, he is taken to a dashboard screen with several categories that he is suppossed to choose from. On clicking any of the categories one is lead to to the a single activity where i need to know how to find which category button was choosen in the ActivityB.
So, in the DashboardActivity, i have this code:
public void onGeneralKnowledgeClick(View v) {
createIntent("GENERAL_KNOWLEDGE", 1);
}
........
........
........
public void onCelebritiesClick(View v) {
createIntent("CELEBRITIES", 6);
}
private void createIntent(String category, int result) {
Bundle bundle = new Bundle();
bundle.putInt(category, result);
Intent intent = new Intent(this.getApplicationContext(),
QuestionActivity.class);
intent.putExtras(bundle);
startActivityForResult(intent, 0);
}
Now, in my QuestionActivity class, i have a method that tries to get the categoryNumber associated with the intent that was started. So, i have something like this:
private int getCategory() {
Bundle bundle = this.getIntent().getExtras();
int categ = bundle.getInt("GENERAL_KNOWLEDGE");
return categ;
}
My problem is that, how do i return the integer category such and not hardcording as i did up here. I want this method to return a the integer from the respective bundle. my idea is to have a switch statement inside the getCategory but i don't know what case value to use. Also, i saw someone saying that onActivityResult can be used but i don't see how.
Please help!
I believe you're a bit confused. You merely need to do:
bundle.putInt("CATEGORY", result); //where result == the categoryId and "CATEGORY" is always "CATEGORY"
Then in your getCategory():
int categ = bundle.getInt("CATEGORY") //you'll get the int value that you fed before
Unless I misunderstood.