I need your help to fix my code.
My intention is if i click the item on ListView it will take me to intent action_view.
The problem is i got force close if i click the item on ListView.
I think the problem is in onItemClick method, can you give the better way to get it done.
Here's my code:
public class HotelList extends ListActivity{
hotelHelper dbHotelHelper;
protected Cursor cursor;
protected ListAdapter adapter;
ListView numberList;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.hotellist);
numberList = (ListView)findViewById(android.R.id.list);
numberList.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position,
long arg3) {
// TODO Auto-generated method stub
String selectedItem = (String) getListAdapter().getItem(position);
String query = "SELECT lat, long FROM hoteltbl WHERE name = '" + selectedItem + "'";
SQLiteDatabase dbs = dbHotelHelper.getReadableDatabase();
Cursor result = dbs.rawQuery(query, null);
result.moveToFirst();
double lat = result.getDouble(result.getColumnIndex("lat"));
double longi = result.getDouble(result.getColumnIndex("long"));
Intent intent = new Intent(android.content.Intent.ACTION_VIEW, Uri.parse("http://maps.google.com/maps?f=d&saddr=&daddr="+lat+","+longi));
startActivity(intent);
}
});
dbHotelHelper = new hotelHelper(this);
try{
dbHotelHelper.createDataBase();
}
catch (Exception ioe){
Log.e("err","Unable to create database");
}
view();
}
private void view() {
// TODO Auto-generated method stub
SQLiteDatabase db = dbHotelHelper.getReadableDatabase();
try{
cursor = db.rawQuery("SELECT * FROM hoteltbl", null);
adapter = new SimpleCursorAdapter(
this,
android.R.layout.simple_list_item_1,
cursor,
new String[]{"name"},
new int[] {android.R.id.text1}
);
numberList.setAdapter(adapter);
}
catch (Exception e){
Log.e("error",e.toString());
}
}
}
Inside item click
you have many ways it might cause exception,
Exception will cause your app force close
your code is not handled with exceptions
I am listing down the causes it might cause the exception, please check followings
String selectedItem = (String) getListAdapter().getItem(position);
here you might get type conversation issue, you are converting something is not supported by String
SQLiteDatabase dbs = dbHotelHelper.getReadableDatabase();
Cursor result = dbs.rawQuery(query, null);
result.moveToFirst();
double lat = result.getDouble(result.getColumnIndex("lat"));
double longi = result.getDouble(result.getColumnIndex("long"));
If dbHotelHelper.getReadableDatabase returns null or dbHotelHelper null, in this case your app will force close
In case dbs.rawQuery return null, your app will force close
if result null then you might calling moveToFirst, getDouble and getColumnIndex on null object, in this case also your app will force close
For your info
SimpleCursorAdapter constructor was deprecated in API level 11.
This option is discouraged, as it results in Cursor queries being performed on the application's UI thread and thus can cause poor responsiveness or even Application Not Responding errors. As an alternative, use LoaderManager with a CursorLoader.
Related
hope you could help me with this problem. i want to get the rowId of a selected item in a listview from sqlite so that i can pass the value to another activity.
i already fed the listview with info from my sqlite table and use onClickedItem in the listview and use pos + 1 to get the id, but i dont want this solution because whenever i delete an item from the listview i wont be able to get the correct rowId from the database itself... this is my code :
in my DBhelper:
public List<String> getSYAList() {
List<String> List = new ArrayList<String>();
try {
// Select All Query
String selectQuery = "SELECT * FROM " + TABLE_SYA ;
Cursor c = ourDatabase.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (c.moveToFirst()) {
do {
List.add((c.getString(0)) + " " +(c.getString(1)) + " "+ (c.getString(2)));
} while (c.moveToNext());
}
} catch (Exception e) {
Toast.makeText(ourContext, "Error encountered.",
Toast.LENGTH_LONG).show();
}
return List;
}
in my activity:
private void loadSYA() {
// TODO Auto-generated method stub
final DBhelper entry = new DBhelper(this);
entry.open();
final List<String> sya = entry.getSYAList();
if(sya.size()>0) // check if list contains items.
{
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(SYA.this,android.R.layout.simple_dropdown_item_1line, sya);
arrayAdapter.setDropDownViewResource(android.R.layout.simple_dropdown_item_1line);
sqlSYA.setAdapter(arrayAdapter);
sqlSYA.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Intent i = new Intent(SYA.this,SYAInfo.class);
Bundle b = new Bundle();
b.putInt("id", (int)position + 1);
i.putExtras(b);
startActivity(i);
}
}); }
else
{
Toast.makeText(SYA.this,"No items to display",1000).show();
}
entry.close();
}
i really hope you anyone could help me to find a solution for this one. thanks in advance guys !!!
Hi I have searched through various questions related to this but i am unable to resolve the issue.
I am new to Android and i am developing an application for cricket. Here i am displaying a team from database whichcontains TeamId and TeamName.TeamId is a autogenerated Value. when i click on particular team i want to get the selected TeamId from database and i want to pass this TeamID as bundle to handle next function. But i am not getting the Team Id from database.
And below is the code what i am trying so far,
Intent intent = getIntent();
teamName=(ArrayList<String>)getIntent().getSerializableExtra("Teams");
ArrayAdapter<String> adapter=new ArrayAdapter<String>(getApplicationContext(),
android.R.layout.simple_list_item_1,teamName);
teamList.setAdapter(adapter);
ListView OnITEMCLICk
teamList.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View v, int id,long position) {
// TODO Auto-generated method stub
textOfSelectedItem =((TextView) v).getText().toString();
Log.v("Clicked item id", " "+ id);
Toast.makeText(getApplicationContext(), "Clicked is " + id, Toast.LENGTH_SHORT).show();
oncreated = false;
Intent intent=new Intent(TeamOneActivity.this,TeamPlayersTeamOne.class);
intent.putExtra("selected teamname", textOfSelectedItem);
startActivity(intent);
///g.setSelectedTeamOne(textOfSelectedItem);
}
});
And this is my database
public ArrayList<String> getTeamID() {
// TODO Auto-generated method stub
ArrayList<String> TeamList=new ArrayList<String>();
String selectQuery="SELECT * FROM " + TABLE_NAME;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor=db.rawQuery(selectQuery, null);
if(cursor.moveToFirst())
{
do
{
//String TeamName=cursor.getString(cursor.getColumnIndex("TeamName"));
String TeamID=cursor.getString(cursor.getColumnIndex("TeamID"));
//TeamList.add(TeamName);
TeamList.add(TeamID);
}while(cursor.moveToNext());
cursor.close();
}
return TeamList;
}
Can any one help how to getId from Database
As I look at your code I see that you are passing to the intent the value of textOfSelectedItem, but your variable is filled with the text that you get from the TextView, which is in no way the ID that you need. You should just write a function to extract the teamID from the database based on the teamName (if that's what you want). So you could use a similar function but instead make the query something lile "SELECT ID FROM"+TABLE_NAME+"WHERE teamName="+nameOfTeam; And then just pass that result to your new intent.
This question already has an answer here:
attempt to re-open an already-closed object: SQLiteDatabase
(1 answer)
Closed 8 years ago.
I know there are several questions like this one, but all of them seem to have a different approach to solve the problem and none have solved mine.
I have my main activity working just fine, loading the db and populating the listview. Then I call a second activity and the problem shows up when I try to load the listview.
I have tried using start/stop managingcursor(cursor) even though it is deprecated, but it didn't fix the problem. Also I tried cloasing the cursor and db in my main activity before firing the next one but that didn't help either.
Both classes extend from ListActivity and follow the same sequence:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Open db in writing mode
MySQLiteHelper.init(this);
MySQLiteHelper tpdbh =
new MySQLiteHelper(this, "DB", null, 1);
SQLiteDatabase db = tpdbh.getWritableDatabase();
checkLocationAndDownloadData(); //this fires a Asynctask that calls method parseNearbyBranches shown bellow
//I load the data to the ListView in the postExecute method of the asynctask by calling:
/*
Cursor cursor = MysSQLiteHelper.getBranchesNames();
adapter = new SimpleCursorAdapter(this,
R.layout.row, cursor, fields, new int[] { R.id.item_text },0);
setListAdapter(adapter);
*/
ListView lv = getListView();
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> listView, View view,
int position, long id) {
// Get the cursor, positioned to the corresponding row in the result set
Cursor cursor = (Cursor) listView.getItemAtPosition(position);
// Get the state's capital from this row in the database.
String branch_id = cursor.getString(cursor.getColumnIndexOrThrow("branch_id"));
cursor.close();
openNextActivity(Integer.parseInt(branch_id));
}
});
}
//In another file:
private void parseNearbyBranches(JSONObject jo) throws JSONException
{
if ( jo.has(jsonTitle) &&
jo.has("company_id") &&
jo.has("id")
) {
String branch = jo.getString(jsonTitle);
MySQLiteHelper tpdbh = MySQLiteHelper.instance;
SQLiteDatabase db = tpdbh.getWritableDatabase();
db.execSQL("INSERT INTO Branches (branch_id, name, company_id) " +
"VALUES ('" +jo.getInt("id")+"', '" + branch +"', '" +jo.getInt("company_id")+"' )");
db.close(); //no difference is I comment or uncomment this line
}
}
In MySQLiteHelper.java:
public static Cursor getBranchesNames() {
// TODO Auto-generated method stub
String[] columns = new String[] { "_id", "branch_id", "name", "company_id" };
Cursor c = getReadDb().query(branchesTable, columns, null, null, null, null,
null);
return c;
}
My other activity does basically the same:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_branch_surveys);
//Read branch data from DB
int companyID = -1;
MySQLiteHelper.init(this);
String [] columns = new String [] {"company_id"};
String [] args = {Integer.toString(branchID)};
Cursor c = MySQLiteHelper.getReadDb().query(MySQLiteHelper.branchesTable, columns, "branch_id=?", args, null, null, null); //THIS QUERY WORKS JUST FINE
if (c.moveToFirst())
companyID = Integer.parseInt(c.getString(0));
c.close();
if( companyID != -1)
{
new DownloadTask().execute(Integer.toString(companyID) );
//where the Async task calls something just like NearByBranches shown above(but with different objects of course)
//And the postExecute sets the listView:
/* cursor = MySQLiteHelper.getAll();
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
R.layout.row, cursor, fields, new int[] { R.id.item_text },0);
setListAdapter(adapter);
*/
}
}
}
In MySQLiteHelper.java:
public static Cursor getAll() {
// TODO Auto-generated method stub
String[] columns = new String[] { "_id","title", "points" };
//********IT IS IN THIS LINE WHERE I GET THE ERROR:********************
Cursor c = getReadDb().query(theTable, columns, null, null, null, null,
null);
return c;
}
public static SQLiteDatabase getReadDb() {
if (null == db) {
db = instance.getReadableDatabase();
}
return db;
}
I hope you can help me out. Thanks!
I just tried commenting the db.close in the similar method of parseNeabyBranches and the problem was solved. Yet I dont get the same error having db.close() in parseNearbyBranches(), can you explain me why?
In parseNearbyBranches() you create a separate SQLiteDatabase object with:
SQLiteDatabase db = tpdbh.getWritableDatabase();
Since this is a different object than the one returned by getReadDb(), you can (and should) close it. The basic rule is each time you call getWritableDatabase() and getReadableDatable() you must have a matching close() statement.
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.
I have developed some sms application and I can't figure out how to solve this issue... in one layout I am displaying two textviews to display the number and the date of the sms... that works fine...
But now I am implementing the onListItemClick and I want that when list item is clicked the whole messages from the database should load into the new view.... How can I accomplish that...
protected void onListItemClick(ListView l, View v, int position, long id) {
// TODO Auto-generated method stub
super.onListItemClick(l, v, position, id);
dba.open();
Cursor c=dba.executeQuery("select rowid _id,* from messages where rowid="+position+";");
Log.v(tag, "value count"+ c.getCount());
if(c.getCount()>0)
{
Log.v(tag, "value count"+c.getCount());
c.moveToPosition(position);
Intent intent = new Intent();
String mesage = c.getString(c.getColumnIndex("msg"));
Log.v("Value passed to class", mesage);
intent.putExtra(name, mesage);
intent.setClass(this, NewInterface.class);
startActivity(intent);
}
}
And here is the code of the other class to which I am passing data.
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.messages);
tv4 = (TextView) findViewById(R.id.tvMessages);
Bundle bundle=getIntent().getExtras();
if(bundle!=null)
{
Log.v("Value got from class", bundle.getString("name"));
tv4.setText(bundle.getString("name"));
}
The list view is populated via this method from database containing the phone numbers....
private void openAndQueryDatabase() {
newDB=new DBAdapter(this);
try {
newDB.open();
Cursor c = newDB.executeQuery("select distinct nm,rowid _id from messages");
if (c != null ) {
if (c.moveToFirst())
Log.v(tag, "Stage 1");{
do {
String firstName = c.getString(c.getColumnIndex("nm"));
Log.v(tag, firstName);
// String date = c.getString(c.getColumnIndex("dt"));
results.add(firstName);
}while (c.moveToNext());
Log.v(tag, "Stage 1");
}
}
On click of List item you are opening a db to fetch data based on position clicked. Instead of trying to read the whole datain your first Activity, why don't you just pass the int position to the next Activity using Intent and then make the database query there. It would be easier and make more sense. If you still want to pass the wholde data , use a code similar to the one below (replacing your if(c.getCount>0) block):
ArrayList<String> arrayList ;
Cursor c=null;
if(c.moveToFirst()){
int x= c.getCount();
int y =c.getColumnIndex("msg");
arrayList = new ArrayList<String>(x);
for(int a=0;a<x;a++){
c.moveToPosition(a);
arrayList.add(c.getString(y));
}
Intent intent = new Intent(this,NewInterface.class);
intent.putStringArrayListExtra("msgs",arrayList );
startActivity(intent);
}
To get the number from one of the textViews of your clicked row of ListView:
TextView tv1=(TextView)v.findViewbyId(R.id.number)//Replace this with id of tv displaying numbers
String number = tv1.getText().toString();
Add these lines in your onListItemClick and then use this number in your query.