I am creating an application in which I scan a number of bar codes and keep extracting their values and clubbing them in a single place. As simple as this sounds I have been unable to create either an array in which I keep storing new values or a string where I keep concatenating them.
Please comment in case someone needs more code or explanation, I understand the question might not be very rich in either.
EDIT :
public class example
{
String val;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
try
{
String list_id=ToolList3.ID;
String list_qty=ToolScanDet3.qty;
// val is returned from the barcode scanning app.
val=val+issue_id+"~"+issue_qty+";";
Log.d("Tools issued till yet...", val);
/* Club all the tool IDs together and fire a single query to issue
them all against one name. */
Intent i=new Intent(Issue.this,Issue1.class);
startActivity(i);
//Issue1 again returns a pair of id and qty which needs to be saved along with the previous set of values.
}
I am basically having trouble trying to save the returned set of values along with the previous ones, the new ones that are returned wipe out the previous values. I tried putting them in an array too but that requires a counter which again defeats the purpose because the counter will be initialized to zero and start over again.
Unless the number of elements is known and constant, it is preferred to use ArrayList instead of array. In the case when you want to keep the data when the activity is destroyed caused by orientation change, you can save them in onSavedInstanceState :
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("temp", tempString);
}
Then retrieve it back in onCreate:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(savedInstanceState != null) {
your_arraylist = savedInstanceState.getString("temp");
}
EDIT:
According to what you want, the Scan activity should not initialize any string. It should obtain the string value which is passed to it by the main instead:
public class ScanActivity extends Activity {
String tempString;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(savedInstanceState == null) {
tempString = getIntent().getStringExtra("temp");
} else {
// orientation change
tempString = saveInstanceState.getString("temp");
}
}
Once you have finished the scan, do
Intent output = new Intent();
output.putExtra("temp", tempString);
setResult(RESULT_OK, output);
finish();
to send back the string to your Main activity.
I could not find any solution that was feasible to my situation and thats why I had to create a local database using SQL Lite. Pushing values to the database each time needed and then retrieving the values after my work flow was over.
Comment in case anyone needs help with the creation of a local database using SQL Lite. Happy to help :)
Related
this is my first question being asked on stackoverflow. My question is regarding variable use across different recyclable intents.
e is declared like this.
final Bundle e=getIntent().getExtras();
Here i am creating new intents for different setOnClickListener() and passing a different variable for each intent.
Intent info = new Intent(EItemListView.this, ItemInfo.class);
Bundle extras = new Bundle();
int[] a=new int[listview.getAdapter().getCount()];
if (i == 0) {
extras.putIntArray("img", n5x_images);
extras.putString("info", n5x_info);
extras.putInt("pc",a[0]);
} else if (i == 1) {
extras.putIntArray("img", op3_images);
extras.putString("info", op3_info);
extras.putInt("pc",a[1]);
}
info.putExtras(extras);
startActivity(info);
Now this is the OnClickListener() where i am trying to update the variables which i passed through the intent extras, but am unable to update those variables.
addtc.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int c=e.getInt("pc");
c=c+1;
Log.i("Log","value "+c);
}
The log message which i get from the above method is always 1, i think the variable in c is always set to 0 and then increments by 1 and hence the log message shows 1.
I need the variables a[0],a[1],a[2], etc to pertain its increment operation.
To make it more clear, this is the java file i am using. The error is in the OnClickListener of addtc button at the bottom of this code.
public class ItemInfo extends AppCompatActivity {
private ViewAnimator viewanimator;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_item_info);
Button next=(Button)findViewById(R.id.bnext);
Button prev=(Button)findViewById(R.id.bprev);
viewanimator=(ViewAnimator)findViewById(R.id.viewAnimator);
TextView info=(TextView)findViewById(R.id.item_info);
Button addtc=(Button)findViewById(R.id.badd);
Button test=(Button)findViewById(R.id.button);
Bundle e=getIntent().getExtras();
int img[]=e.getIntArray("img");
for(int i=0;i<img.length;i++)
{
ImageView imgview = new ImageView(getApplicationContext());
imgview.setImageResource(img[i]);
viewanimator.addView(imgview);
}
info.setText(e.getString("info"));
next.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
viewanimator.showNext();
}
});
prev.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
viewanimator.showPrevious();
}
});
addtc.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int c=e.getInt("pc");
c=c++;
Log.i("Log","value "+c);
}
});
}
}
Thanks in advance!!!
Your approach is wrong. You cannot do this in this way. Your understanding of what an "extra" in an Intent is incorrect.
When you do this:
extras.putInt("pc",a[1]);
This adds an "extra" to the extras Bundle. The Bundle is simply a key/value pair map and you have added an entry that contains the key "pc" and the value is whatever a[1] is. It puts a copy of the value of a[1] into the Bundle, it does not put a reference to a[1] in the Bundle.
Therefore, if a[1] is 5 when you add it to the extras Bundle, a[1] will always be 5 and will never be changed to anything else.
You can't do this in this way.
Alternative: Depending on your application architecture and what you are trying to do, you can use one of the following methods:
1) Use startActivityForResult(), pass the data from one Activity to another, have the second Activity update the data and put it back into the Intent which is then returned to the "calling" Activity by using setResult().
2) Use a static variable (basically a "global" variable) to contain the data. Both activities can then access the data directly (you don't need to put the data in the Intent.
3) Put the data in a database. Both activities can then read/write from/to the database.
First advice I can give you is debugging and posting debug result. for example, are you sure that a[0] and a[1] aren't 0?
Assuming they are not, why are you declaring the bundle as final? referring to this probably final is not what you were looking for. Try removing it or replacing with private
Another suggestion is more for readable purpose, replace c = c+1; with c++; but this doesn't change the result, it just make it more linear and easier for reading.
Now after this fix (the final keyword one) tell me if something changed please :)
I am new to android. I need some help to work on my app. Basically I am trying to develop a quiz app. I have questions stored in a file. So my app reads each question from the file and displays it on the screen using InputStream and BufferedReader objects.
is = this.getResources().openRawResource(R.raw.sampletest);
br = new BufferedReader(new InputStreamReader(is));
So now when user quits the app in the middle, I want my app to save is and br values(pointing to the question where the app left) and restore them again during the next app run. After doing some browsing, I learned that if we wish to persist the app state between different runs, onPause() is the one for such tasks. But can we save these is and br objects?How to save them in onPause().can someone help me out with a code snippet of saving these objects?
Thank you so much in advance...
No. What you should do is save something simple like the position (question number) and a list of the answers that can be persisted in a bundle in onSaveInstanceState. You can then get these saved values from the Bundle in onCreate.
e.g.
private int position;
private ArrayList<String> answers;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
position = savedInstanceState.getInt("position");
answers = savedInstanceState.getStringArrayList("answers");
} else {
answers = new ArrayList<String>();
}
// This should load up the right question.
displayQuestion(position);
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("position", position);
outState.putStringArrayList("answers", answers);
}
I guess you should write a code that saves the data into file, and on load parses the data from the saved file and creates the object.
onPause is not helpful here because like you said it is about app exit, so all the memory (and your objects) are lost..
edit:
if you are sure your app continues running in background, try to save the objects outside the activity:
Very rough example:
void onPause(...) {
SomeSingleton.getInstance().setObjects(is, br);
}
void onCreate(...) {
is = SomeSingleton.getInstance().getIs();
br = SomeSingleton.getInstance().getBr();
}
Hi everyone.
I'm new in android and I'm working on an app in which I need to recall the same activity to enter the information of a variable amount of entities (passengers).
I have the following:
btnContinue3.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
for (int i=0; i<Pssngr; i++){
passenger[i] = new
Intent(getApplicationContext(), Pasajeros.class);
startActivity(passenger[i]);
}
}
});
Pssngr is the amount of passsengers or entites that need a unique activity to get their information entered.
The trigger is the button then the activities will be called one by one following an array
I try this code but after clicking on the button the app crashed.
Please someone help me find a way to make this work.
thanks
It crashes because You are trying to start x number of Activities at once.
If You have to run new Activity for each of Passengers best in this scenario will be startActivityForResult
I beliver effect You trying to get is that user clicks on button just once and activities for each passenger will open one after another.
To do it in method onClick You will start only first activity, don't use loop.
You start consequently next activities in onActivitiyResult
In addition to what Gustek mentions above, a better way to approach this would be to have one activity and just pass the different values from the parent (PassengersAvitivty) activity through the intent as below:
final Intent intent = new Intent(PassengersAcitivty.this, PassengersEntityActivity.class);
intent.putExtra("PASSENGER_FIRSTNAME", passenger[i].getName());
intent.putExtra("PASSENGER_LASTNAME", passenger[i].getLastName());
intent.putExtra("PASSENGER_EMAIL", passenger[i].getEmail());
startActivity(intent);
and here is how you can retrieve them on your activity (PassengerEntityActivity)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle extras = getIntent().getExtras();
if (extras != null)
{
firstname = extras.getString("PASSENGER_FIRSTNAME");
lastname = extras.getString("PASSENGER_LASTNAME");
email = extras.getString("PASSENGER_EMAIL");
}
else
{
//Log.v("NO VALUE", "OOPS");
}
I can clarify further if needed.
I'm confused when it comes down to saving a state. So I know that onSaveInstanceState(Bundle) is called when the activity is about to be destroyed. But how do you store your information in it and bring it back to its original state in onCreate(Bundle savedInstanceState)? I don't understand how this bundle will restore information. It would be helpful if someone can provide an example.
The Dev guide doesn't do a good job of explaining this.
public class Conversation extends Activity {
private ProgressDialog progDialog;
int typeBar;
TextView text1;
EditText edit;
Button respond;
private String name;
private String textAtView;
private String savedName;
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.dorothydialog);
text1 = (TextView)findViewById(R.id.dialog);
edit = (EditText)findViewById(R.id.repsond);
respond = (Button)findViewById(R.id.button01);
if(savedInstanceState != null){
savedInstanceState.get(savedName);
text1.setText(savedName);
}
else{
text1.setText("Hello! What is your name?");
respond.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
name = edit.getText().toString();
text1.setText("Nice to meet you "+ name);
}
});
}
}
#Override
public void onSaveInstanceState(Bundle outState){
super.onSaveInstanceState(outState);
outState.putString(savedName, name);
}
}
The Bundle is a container for all the information you want to save. You use the put* functions to insert data into it. Here's a short list (there are more) of put functions you can use to store data in the Bundle.
putString
putBoolean
putByte
putChar
putFloat
putLong
putShort
putParcelable (used for objects but they must implement Parcelable)
In your onCreate function, this Bundle is handed back to the program. The best way to check if the application is being reloaded, or started for the first time is:
if (savedInstanceState != null) {
// Then the application is being reloaded
}
To get the data back out, use the get* functions just like the put* functions. The data is stored as a name-value pair. This is like a hashmap. You provide a key and the value, then when you want the value back, you give the key and the function gets the value. Here's a short example.
#Override
public void onSaveInstanceState(Bundle outState) {
outState.putString("message", "This is my message to be reloaded");
super.onSaveInstanceState(outState);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
String message = savedInstanceState.getString("message");
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
}
}
Your saved message will be toasted to the screen.
One major note that all new Android developers should know is that any information in Widgets (TextView, Buttons, etc.) will be persisted automatically by Android as long as you assign an ID to them. So that means most of the UI state is taken care of without issue. Only when you need to store other data does this become an issue.
From Android Docs:
The only work required by you is to
provide a unique ID (with the
android:id attribute) for each widget
you want to save its state. If a
widget does not have an ID, then it
cannot save its state
A good information: you don't need to check whether the Bundle object is null into the onCreate() method. Use the onRestoreInstanceState() method, which the system calls after the onStart() method. The system calls onRestoreInstanceState() only if there is a saved state to restore, so you do not need to check whether the Bundle is null
Store information:
static final String PLAYER_SCORE = "playerScore";
static final String PLAYER_LEVEL = "playerLevel";
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save the user's current game state
savedInstanceState.putInt(PLAYER_SCORE, mCurrentScore);
savedInstanceState.putInt(PLAYER_LEVEL, mCurrentLevel);
// Always call the superclass so it can save the view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}
If you don't want to restore information in your onCreate-Method:
Here are the examples: Recreating an Activity
Instead of restoring the state during onCreate() you may choose to implement onRestoreInstanceState(), which the system calls after the onStart() method. The system calls onRestoreInstanceState() only if there is a saved state to restore, so you do not need to check whether the Bundle is null
public void onRestoreInstanceState(Bundle savedInstanceState) {
// Always call the superclass so it can restore the view hierarchy
super.onRestoreInstanceState(savedInstanceState);
// Restore state members from saved instance
mCurrentScore = savedInstanceState.getInt(PLAYER_SCORE);
mCurrentLevel = savedInstanceState.getInt(PLAYER_LEVEL);
}
Basically onSaveInstanceState(Bundle outBundle) will give you a bundle.
When you look at the Bundle class, you will see that you can put lots of different stuff inside it. At the next call of onCreate(), you just get that Bundle back as an argument.
Then you can read your values again and restore your activity.
Lets say you have an activity with an EditText. The user wrote some text inside it.
After that the system calls your onSaveInstanceState().
You read the text from the EditText and write it into the Bundle via Bundle.putString("edit_text_value", theValue).
Now onCreate is called. You check if the supplied bundle is not null. If thats the case,
you can restore your value via Bundle.getString("edit_text_value") and put it back into your EditText.
This is for extra information.
Imagine this scenario
ActivityA launch ActivityB.
ActivityB launch a new ActivityAPrime by
Intent intent = new Intent(getApplicationContext(), ActivityA.class);
startActivity(intent);
ActivityAPrime has no relationship with ActivityA.
In this case the Bundle in ActivityAPrime.onCreate() will be null.
If ActivityA and ActivityAPrime should be the same activity instead of different activities,
ActivityB should call finish() than using startActivity().
If Data Is not Loaded From savedInstanceState use following code.
The problem is url call is not to complete fully so, check if data is loaded then to show the instanceState value.
//suppose data is not Loaded to savedInstanceState at 1st swipe
if (savedInstanceState == null && !mAlreadyLoaded){
mAlreadyLoaded = true;
GetStoryData();//Url Call
} else {
if (listArray != null) { //Data Array From JsonArray(ListArray)
System.out.println("LocalData " + listArray);
view.findViewById(R.id.progressBar).setVisibility(View.GONE);
}else{
GetStoryData();//Url Call
}
}
I have the following code in one activity:
in= new Intent(ThisActivity.this,AnotherActivity.class);
imgarr = new ImageView[55];
imgarr[0]=(ImageView) findViewById(R.id.species3);
imgarr[0].setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
b.putString("specno",Integer.toString(0)); in.putExtras(b);
in.setClassName("com.DuckHuntersJournal","com.DuckHuntersJournal._1_TagKillActivity");
startActivity(in);
}
});
And this code in another:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.menu1tagkill);
if ((savedInstanceState != null) && savedInstanceState.containsKey("specno")) {
Log.e(tag, "intent from species not null");
species.setText(savedInstanceState.getString("specno"));
}
However, savedInstanceState is null.
Why am I not getting any data back from the first activity?
You need to use :
getIntent().getExtras().getString("specno");
in order to get the passed string from the first activity.
EDIT: I'm not sure what you are trying to do... for getting data from another Activity that started the current one you need to use getIntent().getExtras().
For saving your current stat when the Activity goes to background you save the data in the onSaveInstanceState() method and then in the onCreate(Bundle savedInstance) method you get the saved data from the savedInstance parameter.
You'll need to do the following in your receiving Activity:
String species = getIntent().getStringExtra("specno");