How to store phone number chosen from contacts into a string? - java

I am trying to store a phone number that is chosen from the contacts into a string or anything so that I can call it from the different class...
This is my code for contact button
#Override
protected void onCreate(Bundle savedInstanceState)
{
// initialize
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_menu);
//vi1 = (TextView) findViewById (R.id.textView1);
co1 = (Button) findViewById (R.id.button3);
co1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(intent, PICK_CONTACT);
}
});
}
And this is for the onActivityResult to show it to the textview
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
switch (requestCode) {
case PICK_CONTACT:
final TextView vi1 = (TextView) findViewById(R.id.textView1);
Cursor cursor = null;
String phoneNumber = "";
List<String> allNumbers = new ArrayList<String>();
int phoneIdx = 0;
try {
Uri result = data.getData();
String id = result.getLastPathSegment();
cursor = getContentResolver().query(Phone.CONTENT_URI, null, Phone.CONTACT_ID + "=?", new String[] { id }, null);
phoneIdx = cursor.getColumnIndex(Phone.DATA);
if (cursor.moveToFirst()) {
while (cursor.isAfterLast() == false) {
phoneNumber = cursor.getString(phoneIdx);
allNumbers.add(phoneNumber);
cursor.moveToNext();}
} else {
//no results actions
}
} catch (Exception e) {
//error actions
} finally {
if (cursor != null) {
cursor.close();
}
final CharSequence[] items = allNumbers.toArray(new String[allNumbers.size()]);
AlertDialog.Builder builder = new AlertDialog.Builder(MenuActivity.this);
builder.setTitle("Choose a number");
builder.setItems(items, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
String selectedNumber = items[item].toString();
selectedNumber = selectedNumber.replace("-", "");
vi1.setText(selectedNumber);
}
});
AlertDialog alert = builder.create();
if(allNumbers.size() > 1) {
alert.show();
} else {
String selectedNumber = phoneNumber.toString();
selectedNumber = selectedNumber.replace("-", "");
vi1.setText(selectedNumber);
}
if (phoneNumber.length() == 0) {
//no numbers found actions
}
}
break;
}
} else {
//activity result error actions
}
}
I wanted to store the output on the textview into a string or any type of other forms so that I can call it on a different class. Please help me. Thank you!

There are couple of ways by which you can access variable in other classes or Activity.
Database
shared prefrences.
Object serialization.
A class which can hold common data can be named as Common Utilities it depends on you.
It depend upon your project needs.
A. Database
SQLite is an Open Source Database which is embedded into Android. SQLite supports standard relational database features like SQL syntax, transactions and prepared statements.
Tutorials -- http://www.vogella.com/articles/AndroidSQLite/article.html
B. Shared Preferences
Suppose you want to store username. So there will be now two thing a Key Username, Value Value.
How to store
// Create object of SharedPreferences.
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
//now get Editor
SharedPreferences.Editor editor = sharedPref.edit();
//put your value
editor.putString("userName", "stackoverlow");
//commits your edits
editor.commit();
Using putString(),putBoolean(),putInt(),putFloat(),putLong() you can save your desired dtatype.
How to fetch
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
String userName = sharedPref.getString("userName", "Not Available");
http://developer.android.com/reference/android/content/SharedPreferences.html
C. Object Serialization
Object serlization is used if we want to save an object state to send it over network or you can use it for your purpose also.
Use java beans and store in it as one of his fields and use getters and setter for that
JavaBeans are Java classes that have properties. Think of
properties as private instance variables. Since they're private, the only way
they can be accessed from outside of their class is through methods in the class. The
methods that change a property's value are called setter methods, and the methods
that retrieve a property's value are called getter methods.
public class VariableStorage implements Serializable {
private String inString ;
public String getInString() {
return inString;
}
public void setInString(String inString) {
this.inString = inString;
}
}
Set the variable in you mail method by using
VariableStorage variableStorage = new VariableStorage();
variableStorage.setInString(inString);
Then use object Serialzation to serialize this object and in your other class deserialize this object.
In serialization an object can be represented as a sequence of bytes that includes the object's data as well as information about the object's type and the types of data stored in the object.
After a serialized object has been written into a file, it can be read from the file and deserialized that is, the type information and bytes that represent the object and its data can be used to recreate the object in memory.
If you want tutorial for this refer this link
http://javawithswaranga.blogspot.in/2011/08/serialization-in-java.html
Get variable in other classes
D. CommonUtilities
You can make a class by your self which can contain common data which you frequently need in your project.
Sample
public class CommonUtilities {
public static String className = "CommonUtilities";
}

Related

Permanently save intent from other activity (with two values) to listview

I'm trying to save two values from an activity (where the user can put in two different values, one String value and one integer value) in the listview from another activity. In the first activity, it shows a list with a course and the amount of points for that course in one listview, like this:
Course: English
Points: 4
Now, the problem is, everytime I want to put in another value using the add_course_actitivty, it overwrites the previous value. I've looked at different solutions, like with sharedpreferences (Add items to listview from other activity), but this uses only one value and if I try to work with sharedpreferences, it overwrites the other value in the sharedpreferences, but I want users to add multiple courses and corresponding points. Also on restart, it deletes the values in the listview (I read to prevent this you need to store it in sharedpreferences, but this doesn't work the way I need it to be)
KeuzeActivity.class (shows the listview):
public class KeuzeActivity extends AppCompatActivity {
private FloatingActionButton fab_add;
private String student_naam;
private ListView keuze_list;
boolean wantDelete;
private ArrayAdapter adapter;
private String vak;
private int ec;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_keuze);
// setting title
student_naam = getIntent().getStringExtra("student");
setTitle("Keuzevakken en projecten van " + student_naam);
//initialzing elements
fab_add = (FloatingActionButton)findViewById(R.id.fab_add);
keuze_list = (ListView) findViewById(R.id.keuze_list);
//initializing list
final ArrayList<Course> courseItems = new ArrayList<Course>();
adapter = new ArrayAdapter<Course>(this, android.R.layout.simple_list_item_1, courseItems);
keuze_list.setAdapter(adapter);
// checks if intent has required values, put it in listview
if (getIntent().hasExtra("vak") && getIntent().hasExtra("ec")) {
vak = getIntent().getStringExtra("vak");
ec = getIntent().getIntExtra("ec", ec);
courseItems.add(new Course(vak, ec));
adapter.notifyDataSetChanged();
}
// make fab go to other activity
fab_add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(KeuzeActivity.this, add_course_activity.class));
}
});
// long press deletes item
keuze_list.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
showDeleteDialog();
if (wantDelete) {
courseItems.remove(position);
adapter.notifyDataSetChanged();
}
return true;
}
});
}
private void showDeleteDialog() {
AlertDialog.Builder infobuilder = new AlertDialog.Builder(this);
infobuilder.setCancelable(false);
infobuilder.setTitle("Vak/project verwijderen");
infobuilder.setMessage("Weet je zeker dat je het vak of project wilt verwijderen?");
final TextView text = new TextView(this);
// action when pressed OK
infobuilder.setPositiveButton("Ja", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
wantDelete = true;
dialog.cancel();
}
});
infobuilder.setNegativeButton("Nee", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
wantDelete = false;
dialog.cancel();
}
});
infobuilder.show();
}
}
add_course_activity.class (let's users input course and points)
public class add_course_activity extends AppCompatActivity {
private EditText course_edit;
private EditText ec_edit;
private Button save_btn;
private String student_name;
private int ec;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_course);
setTitle("Voeg vak of project toe");
final Context context = getApplicationContext();
// initializing elements
course_edit = (EditText) findViewById(R.id.edit_vak);
ec_edit = (EditText) findViewById(R.id.edit_ec);
save_btn = (Button) findViewById(R.id.save_button);
// action on savebutton
save_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (course_edit.getText().toString().trim().length() > 0 && ec_edit.getText().toString().trim().length() > 0 ) {
ec = Integer.parseInt(ec_edit.getText().toString());
Intent goBack = new Intent(add_course_activity.this, KeuzeActivity.class);
goBack.putExtra("vak", course_edit.getText().toString());
goBack.putExtra("ec", ec);
goBack.putExtra("student", PreferenceManager.getDefaultSharedPreferences(context).getString("student_name", student_name));
startActivity(goBack);
}
else {
Toast.makeText(context, "Voer juiste informatie in!", Toast.LENGTH_SHORT).show();
}
}
});
}
}
Course.java class (getters and setters + with toString method)
public class Course {
private String vak;
private int ec;
public Course(String vak, int ec) {
this.vak = vak;
this.ec = ec;
}
public String getVak() {
return vak;
}
public void setVak(String vak) {
this.vak = vak;
}
public int getEc() {
return ec;
}
public void setEc(int ec) {
this.ec = ec;
}
#Override
public String toString() {
return ("Vak: " + vak + "\n" + "Punten: " + ec);
}
}
Note that my code isn't clean or done, but to get further I need to fix this problem.
You have several way to do it. As other replies have suggested you can use an SQLLite database and add data to a course table and retrieve data from it.
If you find Db approach to complicated/heavy
You could also use SharedPreferences what you need to do is figure a way to store a string that represent a list of course. It is not the best way to approach it but it will work.
Lets say you choose to serialize your Course object with "vac-ec"
Then you just store a serialized list of course. Example "vac1-ec1,vac2-ec2"
When you need to add a course you juste grab the previous string split it to list, append the new course to the list and re-serialize the list to a string to encode it.
Other solution could be to use Realm.
You should used SQLiteDatabase and create a table with valid attributes and insert your new values into them
Okay, now things are clearer. As answered by #Dwijraj, when storing what potentially will be a large set of data, for maximum control it is best to use SQLite.
You can read more about the different Saving Data methods here:
https://developer.android.com/training/basics/data-storage/index.html
SharedPreferences are best used to store small amounts of information, like storing the settings of an application. [Mute] for example. Or a highscore in case of a game.
A Database is a better option when it comes to storing large pieces of data that you will potentially manipulate.
Your data structure can be something like this, Courses table containing Unique_ID , Course Name, Course Level, Course summary.
A table for English for example which will contain
Exams, Scores, Duration.
There are a lot of things you can do.
Try by storing the records in SQLite, and get it when you want to show.
By this, You can have a track of all added items. And you can show the items you want.

Resaving object instead of creating a new one in list

Solved - Answer is at end of thread
I'm creating a notes app. And in that app everything is going well so far except that when I'm trying to edit the note (in a recycler view) and I click save, it creates a new one instead of resaving the contents of the existing note. Because I don't have a way to save it again, that being because I'm not sure how to go about it. Here is how I handle saving the note in my activity, CreateNoteActivity.java
// FAB
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Check to see if at least one field is populated with data
String title = etTitle.getText().toString();
String description = etDescription.getText().toString();
title = title.trim(); // Remove whitespaces at the beginning/end
description = description.trim();
// Get intent extras
Intent intent = getIntent();
String alreadyCreatedTitle = intent.getStringExtra(CreateNoteActivity.EXTRA_TITLE);
String alreadyCreatedDescription = intent.getStringExtra(CreateNoteActivity.EXTRA_DESCRIPTION);
// Check to see if note title is empty, if it is, don't save
if (title == "" || title.isEmpty()) {
Snackbar snackbar = Snackbar.make(view, "Title may not be empty", Snackbar.LENGTH_SHORT);
snackbar.show();
// If the user clicked an already made note and did not change its contents, go back to MainActivity
} else if (title.equals(alreadyCreatedTitle) && description.equals(alreadyCreatedDescription)) {
finish();
CreateNoteActivity.didClick = false;
// The user is editing a note
} else if (didClick) {
// If the title or description is different then resave the note
if (!title.equals(alreadyCreatedTitle) || !description.equals(alreadyCreatedDescription)) {
// TODO: Make it resave the note object
}
} else {
saveNote();
CreateNoteActivity.didClick = false;
}
}
});
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
After that, it comes to my MainActivity.java class where onActivityResult() handles the data and saves a new note, or updates the existing note (not yet implemented)
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 123) {
if (resultCode == Activity.RESULT_OK) {
String passedTitle = data.getStringExtra(CreateNoteActivity.EXTRA_TITLE);
String passedDescription = data.getStringExtra(CreateNoteActivity.EXTRA_DESCRIPTION);
if (CreateNoteActivity.didClick) { // User is saving an existing note
// TODO: Resave the existing note object
// **************************
} else { // User is creating a new note
notes.add(new Note(passedTitle, passedDescription));
}
}
refreshAdapter();
if (resultCode == Activity.RESULT_CANCELED) {
// Do something if it's cancelled. Happens when you click the back button for example
}
}
}
As you can see, i have a variable, "CreateNoteActivity.didClick = false;" of static boolean in this class that I am using to keep track if the user clicked on a note, and it brought them to this activity.
I keep track of that in my adapter class
#Override
public void onClick(View view) {
CreateNoteActivity.didClick = true;
Log.d("TAG", "onClick() called on row: " + getAdapterPosition());
Intent intent = new Intent(context, CreateNoteActivity.class);
intent.putExtra(CreateNoteActivity.EXTRA_TITLE, titleTV.getText().toString());
intent.putExtra(CreateNoteActivity.EXTRA_DESCRIPTION, descriptionTV.getText().toString());
((Activity) context).startActivityForResult(intent, 123);
}
So when the user clicks a note at a specific index, it passes the intent extras to CreateNoteActivity.java so it can retrieve them, and populate the edit text with their info. So now what I am wanting to do is if the user clicks save, it doesn't make a new note, but instead resaves the old note
I really would appreciate anyones help and feedback with solving this problem. Been stuck on it for a couple hours now and I just don't know how to wrap my head around going for this. Thank you very much.
My simple notes class
public class Note {
private String title;
private String description;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Note(String title, String description) {
this.title = title;
this.description = description;
}
public Note() {
// Empty
}
}
Solution
So what I ended up doing was creating a static int and setting it to getAdapterPosition() so that I could always get the position the certain object was at. I then passed it as an intent extra and retrieved it so that I could mess with it. Removed it at that specified index, and set a new one at that index.
if (CreateNoteActivity.didClick) { // User is saving an existing note
note.setTitle(passedTitle);
note.setDescription(passedDescription);
notes.remove(passedID); // Remove note so I can put that same one at the top
notes.add(0, note); // Put note at top of list
CreateNoteActivity.didClick = false;
recyclerView.scrollToPosition(0); // Scroll to top
} else { // User is creating a new note
note.setTitle(passedTitle);
note.setDescription(passedDescription);
notes.add(0, note);
recyclerView.scrollToPosition(0);
}
}
You should also store id of a Note and pass it to be able to edit. You can use its position as the id.
if (CreateNoteActivity.didClick) { // User is saving an existing note
Note anote = notes.getItem(passedNoteId);
anote.setTitle(passedTitle);
anote.setDescription(passedDescription);
} else { // User is creating a new note
notes.add(new Note(passedTitle, passedDescription));
}

setText on button from another activity android

I have a problem, I want to click on the list, calling a new activity and rename the button to another name.
I tried several things, nothing worked, can someone please help me?
My class EditarTimes:
private AdapterView.OnItemClickListener selecionarTime = new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView arg0, View arg1, int pos, long id) {
t = times.get(pos);
CadastroTimes cad = new CadastroTimes();
CadastroTimes.salvar.setText("Alterar");
Intent intent = new Intent(EditarTimes.this, CadastroTimes.class);
startActivity(intent);
}
};
public class CadastroTimes extends AppCompatActivity {
private Time t;
private timeDatabase db;
private EditText edID;
private EditText edNome;
public Button salvar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cadastro_times);
edID = (EditText) findViewById(R.id.edID);
edNome = (EditText) findViewById(R.id.edNome);
db = new timeDatabase(getApplicationContext());
salvar = (Button) findViewById(R.id.btnCadastrar);
salvar.setText("Cadastrar");
String newString;
if (savedInstanceState == null) {
Bundle extras = getIntent().getExtras();
if(extras == null) {
newString= null;
} else {
newString= extras.getString("Alterar");
}
} else {
newString= (String) savedInstanceState.getSerializable("Alterar");
}
//button in CadastroTimes activity to have that String as text
System.out.println(newString + " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
salvar.setText(newString);
}
public void salvarTime(View v) {
t = new Time();
t.setNome(edNome.getText().toString());
if (salvar.getText().equals("Alterar")) {
db.atualizar(t);
exibirMensagem("Time atualizado com sucesso!");
} else {
db.salvar(t);
exibirMensagem("Time cadastrado com sucesso!");
}
Intent intent = new Intent(this, EditarTimes.class);
startActivity(intent);
}
private void limparDados() {
edID.setText("");
edNome.setText("");
edNome.requestFocus();
}
private void exibirMensagem(String msg) {
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
}
}
public class EditarTimes extends AppCompatActivity {
private Time t;
private List<Time> times;
private timeDatabase db;
private ListView lvTimes;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_editar_times);
lvTimes = (ListView) findViewById(R.id.lvTimes);
lvTimes.setOnItemClickListener(selecionarTime);
lvTimes.setOnItemLongClickListener(excluirTime);
times = new ArrayList<Time>();
db = new timeDatabase(getApplicationContext());
atualizarLista();
}
private void excluirTime(final int idTime) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Excluir time?")
.setIcon(android.R.drawable.ic_dialog_alert)
.setMessage("Deseja excluir esse time?")
.setCancelable(false)
.setPositiveButton(getString(R.string.sim),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
if (db.deletar(idTime)) {
atualizarLista();
exibirMensagem(getString(R.string.msgExclusao));
} else {
exibirMensagem(getString(R.string.msgFalhaExclusao));
}
}
})
.setNegativeButton(getString(R.string.nao),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
builder.create();
builder.show();
atualizarLista();
}
private void atualizarLista() {
times = db.listAll();
if (times != null) {
if (times.size() > 0) {
TimeListAdapter tla = new TimeListAdapter(
getApplicationContext(), times);
lvTimes.setAdapter(tla);
}
}
}
private AdapterView.OnItemClickListener selecionarTime = new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1, int pos, long id) {
t = times.get(pos);
Intent intent = new Intent(EditarTimes.this, CadastroTimes.class);
String strName = "Alterar";
intent.putExtra("Alterar", strName);
startActivity(intent);
}
};
private AdapterView.OnItemLongClickListener excluirTime = new AdapterView.OnItemLongClickListener() {
public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
int pos, long arg3) {
excluirTime(times.get(pos).getId());
return true;
}
};
private void exibirMensagem(String msg) {
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
}
public void telaCadastrar(View view) {
Intent intent = new Intent(this, CadastroTimes.class);
startActivity(intent);
}
public void botaoSair(View view) {
Intent intent = new Intent(this, TelaInicial.class);
startActivity(intent);
}
}
You can pass the button caption to CadastroTimes with intent as
Intent intent = new Intent(EditarTimes.this, CadastroTimes.class);
intent.putExtra("buttontxt","Changed Text");
startActivity(intent);
Then in CadastroTimes.java set the text of the button to the new value that you passed. The code will look like:
button = (Button)findViewById(R.id.button); // This is your reference from the xml. button is my name, you might have your own id given already.
Bundle extras = getIntent().getExtras();
String value = ""; // You can do it in better and cleaner way
if (extras != null) {
value = extras.getString("buttontxt");
}
button.setText(value);
Do remember to do it in onCreate after setContentView
//From Activity
Intent intent = new Intent(EditarTimes.this, CadastroTimes.class);
intent.putExtra("change_tag", "text to change");
startActivity(intent);
//To Activity
public void onCreate(..){
Button changeButton = (Button)findViewById(R.id.your_button);
// Button to set received text
Intent intent = getIntent();
if(null != intent &&
!TextUtils.isEmpty(intent.getStringExtra("change_tag"))) {
String changeText = intent.getStringExtra("change_tag");
// Extracting sent text from intent
changeButton.setText(changeText);
// Setting received text on Button
}
}
1: Use intent.putExtra() to share a value from one activity another activity, as:
In ActivityOne.class :
startActivity(
Intent(
applicationContext,
ActivityTwo::class.java
).putExtra(
"key",
"value"
)
)
In ActivityTwo.class :
var value = ""
if (intent.hasExtra("key")
value = intent.getStringExtra("key")
2: Modify button text programatically as:
btn_object.text = value
Hope this will help you
For changing the button text:
Use a static method to call from the other activity to directly modify the button caption.
Use an intent functionality, which is preferable.
Use an Interface and implement it, which is used for communicating between activities or fragment in a manner of fire and forget principle.
Now, i got you:
Your EditarTimes activity with listview:
//set setOnItemClickListener
youtListView.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
Intent i = new Intent(EditarTimes.this, CadastroTimes.class);
//text which you want to display on the button to CadastroTimes activity
String strName = "hello button";
i.putExtra("STRING_I_NEED", strName);
}
});
In CadastroTimes activity,
under onCreate() method, get the text string as:-
String newString;
if (savedInstanceState == null) {
Bundle extras = getIntent().getExtras();
if(extras == null) {
newString= null;
} else {
newString= extras.getString("STRING_I_NEED");
}
} else {
newString= (String) savedInstanceState.getSerializable("STRING_I_NEED");
}
//button in CadastroTimes activity to have that String as text
yourButton.setText(newString);
Ok, so the first step would be to take the button you want and make it a public static object (and put it at the top of the class).
public static Button button;
Then you can manipulate that using this in another class:
ClassName.button.setText("My Button");
In your case it is
CadastroTimes.salvar.setText("Alterar");
if you want to change value from that do not do not go the activity via intent you can use file to save value to file or you have multiple values the use database and access
the value oncreate to set the value of text....
In my case, I had to send an EditText value from a Dialog styled Activity, which then got retrieved from a Service.. My Example is similar to some of the above answers, which are also viable.
TimerActivity.class
public void buttonClick_timerOK(View view) {
// Identify the (EditText) for reference:
EditText editText_timerValue;
editText_timerValue = (EditText) findViewById(R.id.et_timerValue);
// Required 'if' statement (to avoid NullPointerException):
if (editText_timerValue != null) {
// Continue with Button code..
// Convert value of the (EditText) to a (String)
String string_timerValue;
string_timerValue = editText_timerValue.getText().toString();
// Declare Intent for starting the Service
Intent intent = new Intent(this, TimerService.class);
// Add Intent-Extras as data from (EditText)
intent.putExtra("TIMER_VALUE", string_timerValue);
// Start Service
startService(intent);
// Close current Activity
finish();
} else {
Toast.makeText(TimerActivity.this, "Please enter a Value!", Toast.LENGTH_LONG).show();
}
}
And then inside my Service class, I retrieved the value, and use it inside onStartCommand.
TimerService.class
// Retrieve the user-data from (EditText) in TimerActivity
intent.getStringExtra("TIMER_VALUE"); // IS THIS NEEDED, SINCE ITS ASSIGNED TO A STRING BELOW TOO?
// Assign a String value to the (EditText) value you retrieved..
String timerValue;
timerValue = intent.getStringExtra("TIMER_VALUE");
// You can also convert the String to an int, if needed.
// Now you can reference "timerValue" for the value anywhere in the class you choose.
Hopefully my contribution helps!
Happy coding!
Accessing view reference of another Activity is a bad practice. Because there is no guarantee if the reference is still around by the time you access it (considering the null reference risk).
What you need to do is to make your other Activity read values (which you want to display) from a data source (e.g. persistence storage or shared preferences), and the other Activity manipulates these values. So it appears as if it changes the value of another activity, but in reality it takes values from a data source.
Using SharedPreferences:
Note: SharedPreferences saves data in the app if you close it but it will be lost when it has been deleted.
In EditarTimes.java:
private AdapterView.OnItemClickListener selecionarTime = new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView arg0, View arg1, int pos, long id) {
t = times.get(pos);
SharedPreferences.Editor editor = getSharedPreferences("DATA", MODE_PRIVATE).edit();
editor.putString("btnText", "Your desired text");
editor.apply();
Intent intent = new Intent(EditarTimes.this, CadastroTimes.class);
startActivity(intent);
}
};
In CadastroTimes.java
public Button salvar;
salvar.setText(getSharedPreferences("DATA", MODE_PRIVATE).getString("btnText", ""));
//note that default value should be blank
As far as my thoughts go, I can realize that the problem is not with the code you provided as it seems to be implemented correctly. It is possible that you have saved the activityState somewhere in your actual code and because it is not implemented properly, the savedInstanceState found in the onCreate method is not null but the required information is missing or not correct. That's why newString is getting null and salvar textview is getting blank.
Here, I need to know which one is more useful to you - information from getIntent() or from savedInstanceState? The code you provided insists me to assume that savedInstanceState has got the preference.
If you prefer savedInstanceState, then you may use SharedPreferences like this to get the same value you want:
private SharedPreferences mPrefs;
private String newString;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
........
// try to get the value of alterarValue from preference
mPrefs = getSharedPreferences("MyData", MODE_PRIVATE);
newString = mPrefs.getString("alterarValue", "");
if (newString.equals("")){
// we have not received the value
// move forward to get it from bundle
newString = getIntent().getStringExtra("Alterar");
}
// now show it in salvar
salvar.setText(newString);
}
protected void onPause() {
super.onPause();
// you may save activity state or other info in this way
SharedPreferences.Editor ed = mPrefs.edit();
ed.putString("alterarValue", newString);
ed.commit();
}
Or if you don't need to get it from savedInstanceState, please use it:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
........
// try to get the value of alterarValue from bundle
String newString = getIntent().getStringExtra("Alterar");
// now show it in salvar
salvar.setText(newString);
}
That's all I know. Hope it will help. If anything goes wrong, please let me know.

Android: Java cannot refer to a non-final variable

In my Android application, when the users click on Sales button, it will show another view to perform the sales.
My application is working without having any problems before I have implemented an alert dialog to display a warning message to users if GST License expiry date of selected customer is less than 7 days and going to expire soon. Now I am getting the following error message if I don't declare final to these two variables, customer and v.
Cannot refer to a non-final variable customer inside an inner class defined in a different method
Cannot refer to a non-final variable v inside an inner class defined in a different method
I understand that
The reference declared as final cannot be modified once it is
initialized.
So, what will happen if I assign these two variables as final? It always contain the same value? Can someone please explain to me why the compiler giving me these errors and why I should declare final to these two variables?
Here is my source code:
private OnClickListener salesBtnClick = new OnClickListener() {
#Override
public void onClick(View v) {
Customer customer = salesCustAdpt.getSelectedCustomer();
if (customer != null) {
Date expiryDate = customer.getGSTLicenseExpiryDate();
if (checkCustomerGSTLicenseExpiryDate(expiryDate)) {
AlertDialog.Builder builder = new AlertDialog.Builder(SalesCustomerActivity.this);
builder.setCancelable(false)
.setPositiveButton(
"OK",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
try {
//Perform sales here!
Intent intent = null;
intent = new Intent(v.getContext(), SalesActivity.class);//Error msg here!
Bundle bundle = new Bundle();
bundle.putSerializable("selCustomer", customer);//Error msg here!
intent.putExtra("bundle", bundle);
startActivity(intent);
finish();
} catch (Exception ex) {
AddPlusUtil.displayErrorMsg(
SalesCustomerActivity.this,
ex);
}
}
});
AlertDialog alert = builder.create();
alert.setTitle("Warning Message");
String errMsg = "GST License Expiry Date of selected customer is \n" + expiryDate + " and going to expire soon.";
alert.setMessage(errMsg);
alert.setIcon(android.R.drawable.stat_notify_error);
alert.show();
} else {
//Perform Sales
}
}
}
}
When defining Customer, use final:
final Customer customer = salesCustAdpt.getSelectedCustomer();
Also, in your onClick method, set the View as final:
public void onClick(final View v) {
Hope this helps :)
Define that customer and v globally in your class. It will resolve the issue.
Create one global view object than assign it with your v
globalView = v;
and use that globalView for calling intent.
and by the way you can use yourClass.this as context instead of your view context.

Android changing XML layout Changes data fields

Here's a head scratcher...(at least for me)
I have a contact list that displays a list of contacts from my Db. When a user clicks on one of the contacts an edit activity comes up. It all works perfectly as laid out currently, but I need to have the edit activity display the last name entry before the first name. Thinking that all the fields should have a one to one relationship, I went ahead and moved the editText(XML) for the last name above the first name in the edit activity thinking that this should be referenced by the id of the EditText. After doing so, the program is now displaying the first name in the last name field and vise-versa. I have tried wiping the user data on the emulator with no difference. I already realize this is probably one of those UH-DUH! type questions, but if anyone can point out the obvious for me, it would be appreciated. All the code shown is in the now-working state:
I've removed some chunks that would have nothing to do with my issue.
Thanks to anyone having a look at this for me!
Ken
XML:
<EditText
android:id="#+id/contact_edit_first_name"
android:inputType="textPersonName"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="#string/contact_edit_first_name"
android:imeOptions="actionNext"
android:background="#color/warn" >
</EditText>
<EditText
android:id="#+id/contact_edit_last_name"
android:inputType="textPersonName"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="top"
android:hint="#string/contact_edit_last_name"
android:imeOptions="actionNext"
android:background="#color/warn" >
</EditText>
This is the contact activity that displays the listView rows, and calls
createContact which sends an intent to add, edit or delete rows.
public class ContactsActivity extends ListActivity implements
LoaderManager.LoaderCallbacks<Cursor> {
private SimpleCursorAdapter adapter;
/** Called when the activity is first created. */
#Override
public void onCreate //DO THE ON CREATE STUFF -removed
fillData();
registerForContextMenu(getListView());
Button add_contact = (Button) findViewById(R.id.add_contact_button);
add_contact.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
createContact();
}
});
}
// Create the options menu to INSERT from the XML file
// removed - not relevant
// return true for the menu to be displayed
}
// When the insert menu item is selected, call CreateContact
//Removed
createContact();
return true;
}
return super.onOptionsItemSelected(item);
}
private void createContact() {
Intent i = new Intent(this, ContactEditActivity.class);
startActivity(i);
}
//The onListItemClick sends a URI which flags the contactEditActivity
//that this is an edit rather than a new insert.
#Override
protected void onResume() {
super.onResume();
//Starts a new or restarts an existing Loader in this manager
getLoaderManager().restartLoader(0, null, this);
}
//The fillData method binds the simpleCursorAadapter to the listView.
private void fillData() {
//The desired columns to be bound:
String[] from = new String[] { ContactsDB.COLUMN_LAST_NAME, ContactsDB.COLUMN_FIRST_NAME };
//The XML views that the data will be bound to:
int[] to = new int[] {R.id.label2, R.id.label};
// The creation of a loader using the initLoader method call.
getLoaderManager().initLoader(0, null, this);
adapter = new SimpleCursorAdapter(this, R.layout.contact_row, null, from,
to, 0);
setListAdapter(adapter);
}
// Sort the names by last name, then by first name
String orderBy = ContactsDB.COLUMN_LAST_NAME + " COLLATE NOCASE ASC"
+ "," + ContactsDB.COLUMN_FIRST_NAME + " COLLATE NOCASE ASC" ;
// Creates a new loader after the initLoader () call
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
//ETC
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
adapter.swapCursor(data); //Call requires Min API 11
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
// swap the cursor adapter
}
And Finally, this is the contact edit code that is likely the source of my grief...maybe not. Could be the save state doesn't map to the id's?
#Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.activity_contact_edit);
Log.i(TAG, "INSIDE ONCREATE");
mCategory = (Spinner) findViewById(R.id.category);
mLastName = (EditText) findViewById(R.id.contact_edit_last_name);
mFirstName = (EditText) findViewById(R.id.contact_edit_first_name);
mHomePhone = (EditText) findViewById(R.id.contact_edit_home_phone);
mCellPhone = (EditText) findViewById(R.id.contact_edit_cell_phone);
//****************ECT. ETC.
//DECLARE THE BUTTONS AND SET THE DELETE ENABLED FALSE - REMOVED - NOT PERTINANT
Bundle extras = getIntent().getExtras();
// Check if the URI is from a new instance or a saved record
}
// Set the save button to check the required fields, save the contact and finish
saveButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
if (TextUtils.isEmpty(mLastName.getText().toString()) ||
TextUtils.isEmpty(mFirstName.getText().toString())) {
makeToast();
} else {
setResult(RESULT_OK);
finish();
}
}
});
// Set the delete button to delete the contact and finish - REMOVED - NOT PERTINANT
private void fillData(Uri uri) {
// QUERY PARAMETER projection - A list of which columns to return.
// Passing null will return all columns, which is inefficient (but used now!)
// null, null and null are: selection, selection args, and sort order for specific items
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
String category = cursor.getString(cursor
.getColumnIndexOrThrow(ContactsDB.COLUMN_CATEGORY));
for (int i = 0; i < mCategory.getCount(); i++) {
String s = (String) mCategory.getItemAtPosition(i);
Log.i("CATEGORY", s); ////////////////////////////////////////////
if (s.equalsIgnoreCase(category)) {
mCategory.setSelection(i);
}
};
mLastName.setText(cursor.getString(cursor
.getColumnIndexOrThrow(ContactsDB.COLUMN_LAST_NAME)));
mFirstName.setText(cursor.getString(cursor
.getColumnIndexOrThrow(ContactsDB.COLUMN_FIRST_NAME)));
mHomePhone.setText(cursor.getString(cursor
.getColumnIndexOrThrow(ContactsDB.COLUMN_PHONE_NUMBER)));
mCellPhone.setText(cursor.getString(cursor
.getColumnIndexOrThrow(ContactsDB.COLUMN_CELL_NUMBER)));
mWorkPhone.setText(cursor.getString(cursor
.getColumnIndexOrThrow(ContactsDB.COLUMN_WORK_NUMBER)));
mFax.setText(cursor.getString(cursor
//****************ECT. ETC.
//close the cursor
}
}
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
saveState();
outState.putParcelable(whateverContentProvider.CONTENT_ITEM_TYPE, contactUri);
}
#Override
protected void onPause() {
super.onPause();
saveState();
}
private void saveState() {
String category = (String) mCategory.getSelectedItem();
String someLAST = mLastName.getText().toString().valueOf(findViewById(R.id.contact_edit_last_name));
String lastName = mLastName.getText().toString();
String firstName = mFirstName.getText().toString();
String someFIRST = mFirstName.getText().toString().valueOf(findViewById(R.id.contact_edit_first_name));
String homePhone = mHomePhone.getText().toString();
String somePhone = mHomePhone.getText().toString().valueOf(findViewById(R.id.contact_edit_home_phone));
String cellPhone = mCellPhone.getText().toString();
String workPhone = mWorkPhone.getText().toString();
//****************ECT. ETC.
//Some logging I used to show that the first name field still came up first
//after changing the order of the editTexts.
Log.i("LAST NAME", lastName);
Log.i("SOME LAST", someLAST);
Log.i("FIRST NAME", firstName);
Log.i("SOME FIRST", someFIRST);
Log.i("Home Phone", homePhone);
Log.i("SOME PHONE", somePhone);
// Save if first name and last name are entered
// The program will save only last name when a user presses back button with text in last name
if (lastName.length() == 0 || firstName.length() == 0) {
return;
}
// ContentValues class is used to store a set of values that the contentResolver can process.
ContentValues values = new ContentValues();
values.put(ContactsDB.COLUMN_CATEGORY, category);
values.put(ContactsDB.COLUMN_LAST_NAME, lastName);//ANNIE
values.put(ContactsDB.COLUMN_FIRST_NAME, firstName);
values.put(ContactsDB.COLUMN_PHONE_NUMBER, homePhone);
//****************ECT. ETC.
if (contactUri == null) {
// Create a new contact
contactUri = getContentResolver().insert(whateverContentProvider.CONTENT_URI, values);
} else {
// Update an existing contact
getContentResolver().update(contactUri, values, null, null);
}
}
//MAKE A TOAST DOWN HERE - REMOVED - NOT PERTINANT
}
Have you tried cleaning the project (regenerating de R).
Also, try restarting your IDE.
This may seem stupid but actually can solve the issue...
try cleaning your project. Weird things happen sometimes within Eclipse.

Categories