Brief of app: Add contacts / Edit Contacts
-Contato.java //Show a ListView of the contacts, when itemClicked shows a dialog of info(name/telephone) and 3Buttons (Ok/Alter/Delete) the Alter button sends the user to:
-Adicionarcontato.java with the info's to edit, but when I edit and hit the button "Salvar" (save) the error: The application Mensagem(process com.example.mensagem) has stopped unexpectedly. Please try again.
Here is the code of Contato.java of the ListView.
private void ListaContatos(){
ListView user = (ListView) findViewById(R.id.lvShowContatos);
//String = simple value ||| String[] = multiple values/columns
String[] campos = new String[] {"nome", "telefone"};
list = new ArrayList<String>();
c = db.query( "contatos", campos, null, null, null, null, null);
c.moveToFirst();
if(c.getCount() > 0) {
while(true) {
list.add(c.getString(c.getColumnIndex("nome")).toString());
if(!c.moveToNext()) break;
}
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, list);
user.setAdapter(adapter);
user.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
reg = position;
c.moveToPosition(reg);
String nome = c.getString(c.getColumnIndex("nome"));
String telefone = c.getString(c.getColumnIndex("telefone"));
ShowMessage(nome, telefone);
}
});
}
And here is the code in the Adicionarcontato.java:
public SQLiteDatabase db;
private String mIndex = "";
private String nomeant,foneant;
static final String userTable = "contatos";
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.adicionarcontato);
if(getIntent().getExtras() != null) {
if(getIntent().getExtras().containsKey("reg")) mIndex = getIntent().getExtras().getString("reg");
}
db = openOrCreateDatabase("banco.db", Context.MODE_WORLD_WRITEABLE, null);
if(!mIndex.equals("")) {
Cursor c = db.query(false, "contatos", (new String[] {"nome", "telefone"}), null, null, null, null, null, null);
c.moveToPosition(Integer.parseInt(mIndex));
nomeant = c.getString(0);
foneant = c.getString(1);
EditText nome1 = (EditText) findViewById(R.id.etNome);
EditText telefone1 = (EditText) findViewById(R.id.etTelefone);
nome1.setText(nomeant);
telefone1.setText(foneant);
}
AdicionarContato();
ResetarInfo();
}
And the code of the button "Salvar" when clicked:
public void AdicionarContato() {
// TODO Auto-generated method stub
final EditText nm = (EditText) findViewById(R.id.etNome);
final EditText tlf = (EditText) findViewById(R.id.etTelefone);
Button add = (Button) findViewById(R.id.bSalvarContato);
add.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
final String nome = nm.getText().toString();
final String telefone = tlf.getText().toString();
if(nome.length() != 0 && telefone.length() != 0){
if(mIndex.equals("")) {
ContentValues valor = new ContentValues();
valor.put("nome", nome);
valor.put("telefone", telefone);
db.insert("contatos", null, valor);
ShowMessage("Sucesso","O Contato " + nome + " foi salvo com sucesso");
}
else {
String[] whereArgs = {"nome", "telefone"};
ContentValues dataToInsert = new ContentValues();
dataToInsert.put("nome", nome);
dataToInsert.put("telefone", telefone);
db.update("contatos", dataToInsert, "nome='"+nomeant+" and telefone='"+foneant+"'", whereArgs);
ShowMessage("Sucesso","O Contato " + nome + " foi salvo com sucesso");
}
}
}
});
}
The LogCat error it shows that:
Failure 1 (table contatos already exists) on 0x2205b0 when preparing 'create table contatos(nome varchar(50),telefone varchar(20))'.
My POV: the result in the LogCat says that the table already exists but, in the code i cant see where i shows that im trying to create it, wrong, i try to connect to it and not create it.
You don't need the whereArgs here since you are attaching the arguments in the where clause itself. Just supply null to in place of whereArgs -
db.update("contatos", dataToInsert, "nome='"+nomeant+"' and telefone='"+foneant+"'", null);
But it is always better to use the arguments. It prevents sql injection and also takes care of escaping special characters. In your case -
db.update("contatos", dataToInsert, "nome=? and telefone=?", whereArgs);
Also, your whereArgs is wrong. It should be -
String[] whereArgs = new String[] {nomeant, foneant};
FONT from the user Mukesh Soni.
Also using the whereArgs allows for some SQLite optimizations,
another issue in your code is that you dont check for the return values of update and insert operations
db.update("contatos", dataToInsert, "nome='"+nomeant+"' and telefone='"+foneant+"'", null);
db.insert("contatos", null, valor);
ocurrs you have a success in your operation you should check for the returned values of update
and insert to check if the operations actually have had success.
You should also check this good tutorial on SQLite on Android as a good starting point.
Related
I want user to select a number from calllog and that number get selected and come in the activity. So I created custom calllog list. I used this code but it is not showing the call log list in right order
first thing it is showing the callhistory of the first number fully that it gets in the calllog list
second I wnt to show the name also, I tried a lot but I am not able to do
Can anyone tell what amendments i make in this code to make it right
The code I used is:
String[] callLogFields = { android.provider.CallLog.Calls._ID,
android.provider.CallLog.Calls.NUMBER,
android.provider.CallLog.Calls.CACHED_NAME };
String viaOrder = android.provider.CallLog.Calls.DATE + " DESC";
String WHERE = android.provider.CallLog.Calls.NUMBER + " >0"; /*filter out private/unknown numbers */
final Cursor callLog_cursor = this.getContentResolver().query(
android.provider.CallLog.Calls.CONTENT_URI, callLogFields,
WHERE, null, viaOrder);
AlertDialog.Builder myversionOfCallLog = new AlertDialog.Builder(this);
android.content.DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogInterface, int item) {
callLog_cursor.moveToPosition(item);
Log.v("number", callLog_cursor.getString(callLog_cursor
.getColumnIndex(android.provider.CallLog.Calls.NUMBER)));
callLog_cursor.close();
}
};
myversionOfCallLog.setCursor(callLog_cursor, listener,
android.provider.CallLog.Calls.NUMBER);
myversionOfCallLog.setTitle("Choose from Call Log");
myversionOfCallLog.create().show();
You can add the Contact Numbers in a Set, which will prevent adding duplicate contact numbers. Then add the Set's data to listview as you want.
Set<String> setNumbers = new HashSet<String>();
String callNumber = cursor.getString(cursor.getColumnIndex(
android.provider.CallLog.Calls.NUMBER));
setNumbers.add(callNumber);
Hope this helps.
For saving numbers without duplicates, as MysticMagic suggested, use 'Set' as per the link given in the comment.
For getting the contact name from the phone number, use code :
(Reference)
private String getContactName(Context context, String number) {
String name = null;
// define the columns I want the query to return
String[] projection = new String[] {
ContactsContract.PhoneLookup.DISPLAY_NAME,
ContactsContract.PhoneLookup._ID};
// encode the phone number and build the filter URI
Uri contactUri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number));
// query time
Cursor cursor = context.getContentResolver().query(contactUri, projection, null, null, null);
if(cursor != null) {
if (cursor.moveToFirst()) {
name = cursor.getString(cursor.getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME));
Log.v(TAG, "Started uploadcontactphoto: Contact Found # " + number);
Log.v(TAG, "Started uploadcontactphoto: Contact name = " + name);
} else {
Log.v(TAG, "Contact Not Found # " + number);
}
cursor.close();
}
return name;
}
Also refer here for another method to fetch name in phone call history
Uri allCalls = Uri.parse("content://call_log/calls");
Cursor c = managedQuery(allCalls, null, null, null, null);
String num= c.getString(c.getColumnIndex(CallLog.Calls.NUMBER));// for number
String name= c.getString(c.getColumnIndex(CallLog.Calls.CACHED_NAME));// for name
String duration = c.getString(c.getColumnIndex(CallLog.Calls.DURATION));// for duration
int type = Integer.parseInt(c.getString(c.getColumnIndex(CallLog.Calls.TYPE)));// for call type, Incoming or out going
Finally this is the code that worked with the help of MysticMagic and Nishanthi Grashia
Set setA;
setA = new HashSet();
public void getCallLog() {
try {
final String[] projection = null;
final String selection = null;
final String[] selectionArgs = null;
final String sortOrder = "DATE DESC";
final Cursor cursor = this.getContentResolver().query(
Uri.parse("content://call_log/calls"), projection,
selection, selectionArgs, sortOrder);
if (cursor != null) {
// Loop through the call log.
while (cursor.moveToNext()) {
// Common Call Log Items
String callNumber = cursor
.getString(cursor
.getColumnIndex(android.provider.CallLog.Calls.NUMBER));
setA.add(callNumber);
}
generateList();
}
} catch (Exception e) {
}
}
#SuppressLint("NewApi")
private void generateList() {
// TODO Auto-generated method stub
try {
Object[] calllist = new String[setA.size()];
calllist = setA.toArray();
String scalllist[] = Arrays.copyOf(calllist, calllist.length,
String[].class);
for (int i = 0; i < scalllist.length; i++) {
scalllist[i] = scalllist[i] + " "
+ getContactName(this, scalllist[i]);
}
final Dialog d = new Dialog(this);
d.setContentView(R.layout.dialog1);
d.setTitle("Choose from Call Log...");
final ListView lv1 = (ListView) d.findViewById(R.id.listView1);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, android.R.id.text1,
scalllist);
lv1.setAdapter(adapter);
lv1.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
// TODO Auto-generated method stub
String clickednumber[] = (lv1.getItemAtPosition(arg2)
.toString()).split(" ");
usernumber.setText(clickednumber[0]);
try {
username.setText(clickednumber[1]);
} catch (ArrayIndexOutOfBoundsException e) {
username.setText(" ");
}
d.dismiss();
}
});
d.show();
} catch (Exception e) {
}
}
private String getContactName(Context context, String number) {
String name = null;
try {
// define the columns I want the query to return
String[] projection = new String[] {
ContactsContract.PhoneLookup.DISPLAY_NAME,
ContactsContract.PhoneLookup._ID };
// encode the phone number and build the filter URI
Uri contactUri = Uri.withAppendedPath(
ContactsContract.PhoneLookup.CONTENT_FILTER_URI,
Uri.encode(number));
// query time
Cursor cursor = context.getContentResolver().query(contactUri,
projection, null, null, null);
if (cursor != null) {
if (cursor.moveToFirst()) {
name = cursor
.getString(cursor
.getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME));
} else {
name = " ";
}
cursor.close();
}
} catch (Exception e) {
e.printStackTrace();
}
return name;
}
![This is my code for find method in DBHelper].class[1]
public StringBuilder findData(String find)
{
StringBuilder output = new StringBuilder("Our data is:\n");
Cursor c = ourHelper.getReadableDatabase().rawQuery("SELECT abbrevaition FROM abbrtab WHERE acronym"+" = ? ;", new String[]{find});
String remarks=" ";
int iRemarks = c.getColumnIndex(KEY_ABBR);
if( c.moveToFirst() && c.getCount()>0 )
{
remarks= c.getString(iRemarks);
if(remarks.isEmpty())
{
Toast.makeText(ourContext, "not", Toast.LENGTH_LONG).show();
}
output.append(remarks);
}
c.close();
return output;
}
![This is code in Main.java for getting data from SQLite3. When i give the query select * from abbrtab then it execute. and apply the where condition then i'm not get any thing. ][1]
#Override
public void onClick(View v)
{
Toast.makeText(getApplicationContext(), String.valueOf("Hi"),Toast.LENGTH_LONG).show();
// TODO Auto-generated method stub
ASNDBAdapter info = new ASNDBAdapter(AllBranches.this);
info.open();
String data = et.getText().toString();
String result = info.findData(data).toString();
Intent i = new Intent(AllBranches.this, ViewData.class);
i.putExtra("my_data", result);
startActivity(i);
Toast.makeText(getApplicationContext(), String.valueOf(result),
Toast.LENGTH_LONG).show();
info.close();
}
public StringBuilder findData(String find)
{
StringBuilder output = new StringBuilder("Our data is:\n");
Cursor c = ourHelper.getReadableDatabase().query("abbrtab", new String[] {"abbrevaition"},"acronym" +"="+find, null, null, null, null);
String remarks=" ";
int iRemarks = c.getColumnIndex(KEY_ABBR);
if( c.moveToFirst() && c.getCount()>0 )
{
remarks= c.getString(iRemarks);
if(remarks.isEmpty())
{
Toast.makeText(ourContext, "not", Toast.LENGTH_LONG).show();
}
output.append(remarks);
}
c.close();
return output;
}
Here "abbrtab" is table name and "abbrevaition" is name of field .
To get a parameter's value into the query, you have to use a parameter token like ?:
String[] params = new String[]{ find };
Cursor c = db.rawQuery("SELECT abbrevaition FROM abbrtab WHERE acronym = ?",params);
For a simple query like this, you wouldn't need to use rawQuery but could just use query.
String[] params = new String[]{ find };
Cursor c = db.query("abbrtab ", new String{"abbrevaition"},
"acronym = ?", params,
null, null, null);
You also have to ensure that your Column Names are correct.
try this way.
How to retrieve rows from external database and display them in text view??
i have tried some codes but the application stopped.
In my database helper i added that code :
public String[] getData(String l) {
// TODO Auto-generated method stub
String[] columns = new String[] { DB_ID, DB_name, DB_desc };
// FILTERS DEPENDING ON THE CATEGORY TYPE PASSED IN THE PARAMETER
Cursor c = mDataBase.rawQuery("SELECT _id,name,description FROM facilities WHERE name='" + l + "'", null);
String[] result = new String[] { null, null, null, null, null };
int iId = c.getColumnIndex(DB_ID);
int iName = c.getColumnIndex(DB_name);
int iDesc = c.getColumnIndex(DB_desc);
c.moveToFirst();
result[0] = c.getString(iId);
result[1] = c.getString(iName);
result[2] = c.getString(iDesc);
return result;
}
And this code in my activity which i wish to display the string in textview:
for(int i=0;i<4;i++){
// dbhelper.open();
String[] data =dbhelper.getData(namee);
// dbhelper.close();
txt.append("\n"+data[3]+"\n");}
}
This is another code i tried it, from this url :
Return all data from a SQLite DB into two columns in Android
Can you post the LogCat entries?
What does this line do?
String[] result=new String[]{null,null,null,null,null};
Try
String[] result = new String[5];
instead;
I used this in one of my app.... This may help.
I declared the following in the main activity itself
DatabaseHelper myDbHelper = new DatabaseHelper(this);
.
.
try {
myDbHelper.createDataBase();
}
.
.
.
db = myDbHelper.getWritableDatabase();// or db = myDbHelper.getReadableDatabase();
.
.
.
//In another function
Cursor c = db.rawQuery("Whatever you want to query");
String[] s=new String[]{"The fields(columns) you want queried and used in textbox"};
I'm currently developing an app. What it does, the user would input some sentences and then the app will get the ambiguous word and then display it meaning. In my table I have fields like _id, word, meaning, definition_number.
Sample data:
_id word meaning definition_number
1 Break to pause from something 1
2 Break to cut into pieces 2
If the user would input: My break was very fast.
The intended output would be:
Ambiguous word: Break
Meaning: To pause from something
I want to display the it randomly. This is a snippet of code from my DBHelper.class:
public Cursor getAllWords()
{
Cursor localCursor =
//this.myDataBase.query(DB_TABLE, new String[] {
// KEY_ID, KEY_WORD, KEY_MEANING }, null, null, null, null, null);//"RANDOM()");
//this.myDataBase.query(DB_TABLE, new String[] {
// KEY_ID, KEY_WORD, KEY_MEANING }, null, null, null, null, "RANDOM()", " 1");
this.myDataBase.query(DB_TABLE, new String[] {
KEY_ID, KEY_WORD, KEY_MEANING },
null, null, null, null, "RANDOM()");
if (localCursor != null){
localCursor.moveToFirst();
}
return localCursor;
}
MainActivity.class:
ArrayList<String> colWords = new ArrayList<String>();
ArrayList<String> colMeanings = new ArrayList<String>();
String[] words;
String[] meanings;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initControls();
}
private void initControls() {
// TODO Auto-generated method stub
text = (EditText) findViewById (R.id.editText1);
view = (TextView) findViewById (R.id.textView1);
clear = (Button) findViewById (R.id.button2);
clear.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
text.setText("");
view.setText("");
}
});
connectDB();
ok = (Button) findViewById (R.id.button1);
ok.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
//Log.d(strWord, strWord);
strWord = text.getText().toString();
if(strWord.isEmpty()){
Toast.makeText(MainActivity.this, "Please input some data", Toast.LENGTH_SHORT).show();
} else {
checkAmbiguousWord();
}
}
});
}
private void connectDB(){
dbHelper = new DBHelper(MainActivity.this);
try {
dbHelper.createDataBase();
} catch (IOException ioe) {
throw new Error("Unable to create database");
}
try {
dbHelper.openDataBase();
} catch (SQLException sqle) {
throw sqle;
}
cursor = dbHelper.getAllWords();
/*strWord = cursor.getString(cursor.getColumnIndex(DBHelper.KEY_WORD))
+ cursor.getString(cursor.getColumnIndex(DBHelper.KEY_MEANING)); */
colWords.clear();///added code
colMeanings.clear();///added code
/*
for(cursor.moveToFirst(); cursor.moveToNext(); cursor.isAfterLast()) {
colWords.add(cursor.getString(1));
colMeanings.add(cursor.getString(2));
String records = cursor.getString(0);
Log.d("Records", records);
} */
if (cursor != null) {
if (cursor.moveToFirst()) {
do {
colWords.add(cursor.getString(1));
colMeanings.add(cursor.getString(2));
String records = cursor.getString(0);
Log.d("Records", records);
} while (cursor.moveToNext());
}
}
}
private void checkAmbiguousWord(){
final String textToCheck = text.getText().toString();
List<Integer> ambiguousIndexes = findAmbiguousWordIndexes(textToCheck);
view.setText(!ambiguousIndexes.isEmpty() ?
ambigousIndexesToMessage(ambiguousIndexes) : "No ambiguous word/s found.");
}
/**
* #param text checked for ambiguous words
* #return the list of indexes of the ambiguous words in the {#code words} array
*/
private List<Integer> findAmbiguousWordIndexes(String text) {
final String lowerCasedText = text.toLowerCase();
final List<Integer> ambiguousWordIndexList = new ArrayList<Integer>();
words = (String[]) colWords.toArray(new String[colWords.size()]);
meanings = (String[]) colMeanings.toArray(new String[colMeanings.size()]);
for (int i = 0; i < words.length; i++) {
if (lowerCasedText.contains(words[i].toLowerCase())) {
ambiguousWordIndexList.add(i);
}
}
return ambiguousWordIndexList;
}
public String ambigousIndexesToMessage(List<Integer> ambiguousIndexes) {
// create the text using the indexes
// this is an example implementation
StringBuilder sb = new StringBuilder();
for (Integer index : ambiguousIndexes) {
sb.append("Ambiguous words: ");
sb.append(words[index] + "\nMeaning: " + meanings[index] + "\n");
sb.append("");
}
return sb.toString();
}
But all it does is displaying the two records. Both id 1 and id 2. I just want to display only one record randomly. I really need help regarding this. Any ideas? I would gladly appreciate it.
You have RANDOM() ordering but you also need to add a LIMIT 1 to only return one result row. There's an overload of SQLiteDatabase.query() that takes in a limit parameter:
this.myDataBase.query(DB_TABLE, new String[] {
KEY_ID, KEY_WORD, KEY_MEANING },
null, null, null, null, "RANDOM()", "1");
I've been playing with a sample application I found online. Just changing things to see how it works. Yesterday this was not an issue. Today is a different story. I seem to write the correct info to the db. I've checked through log outputs. When I return the information through a cursor I get "null". So, say I enter "Eggs","Bread", and "Candy". I get back "null","null", and "null".
It all starts with the listener for the add grocery button. Adds to the db and writes the list to an label.
Any help?
private void addEvent(String title) {
SQLiteDatabase db = eventsData.getWritableDatabase();
ContentValues values = new ContentValues();
Log.v(TAG, "Adding " + title);
values.put(EventsDataSQLHelper.TITLE, title);
db.insert(EventsDataSQLHelper.TABLE, null, values);
}
private Cursor getEvents() {
SQLiteDatabase db = eventsData.getReadableDatabase();
Cursor cursor = db.query(EventsDataSQLHelper.TABLE, null, null, null, null,
null, EventsDataSQLHelper.TITLE);
startManagingCursor(cursor);
return cursor;
}
private void showEvents(Cursor cursor) {
StringBuilder ret = new StringBuilder();
while (cursor.moveToNext()) {
String title = cursor.getString(1);
ret.append(title + "\n");
Log.v(TAG, "SHOWING RET VARIABLE" + ret);
}
t.setText(ret);
}
View.OnClickListener myhandler = new View.OnClickListener()
{
#Override
public void onClick(View GLview)
{
EditText eT = (EditText)findViewById(R.id.itemName1);
editTextStr = eT.getText().toString();
Log.v(TAG, editTextStr);
if(editTextStr != null)
{
addEvent(editTextStr.toString());
Cursor cursor = getEvents();
showEvents(cursor);
eT.setText(null);
}
}
};
Make sure cursor points to the first element of the result cursor.moveToFirst();
Then call cursor.moveToNext()