AlertDialog and Intent - android

I'm trying to create a contact application so far so good,(I'm new to Android Developing) but I struggle with this part of the code where I have an AlertDialog, that I want from the elements that displays (infos of the contact, selected), to take me to my Activity, (ActivitySMS.class to be exact), but although it seems to be fine, running the app, and selecting the number from the AlertDialog that appears, it ends. Log doesn't show something worthy of exploring and understanding where lies the problem.
public class AgendaActivity extends ListActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_agenta);
ContentResolver resolver = getContentResolver();
Cursor mCursor = resolver.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
String[] contacts = {
ContactsContract.Contacts.DISPLAY_NAME_PRIMARY,
ContactsContract.Contacts.LOOKUP_KEY,
ContactsContract.Contacts._ID,
};
int[] views = new int[]{
android.R.id.text1
};
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_2,
mCursor,
contacts,
views,
0);
// Bind to our new adapter.
setListAdapter(adapter);
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
final Cursor phoneCursor = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=?",
new String[]{"" + id},
null);
assert phoneCursor != null;
final int nTelephones = phoneCursor.getCount();
final String[] telephones = new String[nTelephones];
int x = 0;
while (phoneCursor.moveToNext()) {
int col = phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
telephones[x++] = phoneCursor.getString(col);
}
//Cursor Close
phoneCursor.close();
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Telephone Selection");
builder.setItems(telephones, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int item) {
String currentNumber = "smsto: " + (telephones[item]);
Intent sentIntent = new Intent(AgendaActivity.this, ActivitySMS.class);
sentIntent.setData(Uri.parse(currentNumber));
startActivity(sentIntent);
}
});
AlertDialog alert = builder.create();
alert.show();
}
Is there a way to overcome this obstacle?

Replace the line sendIntent.setData(Uri.parse(currentNumber)); by
public static final String EXTRA_CURRENT_NUMBER = "EXTRA_CURRENT_NUMBER"; //just a string constant, it can be whatever you want
...
sendIntent.putExtra(EXTRA_CURRENT_NUMBER, currentNumber);
You can read that value later in your activity like this
//ActivitySMS.class
getIntent().getExtras().getString(MyDialogClass.EXTRA_CURRENT_NUMBER, "some default value...");

Related

Retrieving a List of Contacts android

I want to display the Contact List using Fragment. The number will show on toast when the user selects names from the list.The list will show only name.How can I get the numbers form contact. I went through the android developer training for retrieving a contact list, but the tutorial is incomplete and even downloading the sample code doesn't help because the sample code is for more advanced contact list manipulation (search, etc.)
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Context context = getActivity();
int layout = android.R.layout.simple_list_item_1;
Cursor c = null; // there is no cursor yet
int flags = 0; // no auto-requery! Loader requeries.
mAdapter = new SimpleCursorAdapter(context, layout, c, FROM, TO, flags);
}
#Override
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
final ListView lv = getListView();
lv.setTextFilterEnabled(true);
lv.setOnItemClickListener(new OnItemClickListener()
{
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
Toast.makeText(getActivity(), " Clicked!"
, Toast.LENGTH_SHORT).show();
}
});
// each time we are started use our listadapter
setListAdapter(mAdapter);
// and tell loader manager to start loading
getLoaderManager().initLoader(0, null, this);
}
#SuppressLint("InlinedApi")
private static final String SELECTION = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ? Contacts.DISPLAY_NAME_PRIMARY + " LIKE ?" : Contacts.DISPLAY_NAME + " LIKE ?";
private String mSearchString;
private String[] mSelectionArgs = { mSearchString };
private static final String[] PROJECTION =
{
Contacts._ID,
Contacts.LOOKUP_KEY,
Build.VERSION.SDK_INT
>= Build.VERSION_CODES.HONEYCOMB ?
Contacts.DISPLAY_NAME_PRIMARY :
Contacts.DISPLAY_NAME
};
private static final String[] FROM = { Contacts.DISPLAY_NAME_PRIMARY };
private static final int[] TO = { android.R.id.text1 };
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args)
{
Uri contentUri = Contacts.CONTENT_URI;
return new CursorLoader(getActivity(), Contacts.CONTENT_URI, PROJECTION, null, null, Contacts.DISPLAY_NAME+" ASC");
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data)
{
mAdapter.swapCursor(data);
}
#Override
public void onLoaderReset(Loader<Cursor> loader)
{
mAdapter.swapCursor(null);
}
How can I get the numbers form contact
I'd start with editing your PROJECTION array and adding HAS_PHONE_NUMBER column to not proceed if there's no phone number associated.
If there's is, then using your contact's ID you can do something like this (note the type constrain, so edit according to your needs):
Cursor cursorPhone = getContentResolver()
.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
new String[]{ ContactsContract.CommonDataKinds.Phone.NUMBER },
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ? AND " +
ContactsContract.CommonDataKinds.Phone.TYPE + " = " +
ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE,
new String[]{ contactId },
null);
if (cursorPhone.moveToFirst()) {
contactNumber = cursorPhone.getString(cursorPhone
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
}
cursorPhone.close();

Get and select contacts in android

I'm trying get all contacts and select it.
I completed get all contacts in my phone. But when i try to select a few contacts and get their names or numbers, I faced nullpointer error.
public class ContactListFragment extends ListFragment implements LoaderCallbacks<Cursor> {
private CursorAdapter mAdapter;
final HashMap<String,String> hashMap = new HashMap<String,String>();
Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
private Uri uriContact;
private String contactID;
String[] projection = new String[] {ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// create adapter once
Context context = getActivity();
int layout = android.R.layout.simple_list_item_multiple_choice;
Cursor c = null; // there is no cursor yet
int flags = 0; // no auto-requery! Loader requeries.
mAdapter = new SimpleCursorAdapter(context, layout, c, FROM, TO, flags);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// each time we are started use our listadapter
setListAdapter(mAdapter);
getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
// and tell loader manager to start loading
getLoaderManager().initLoader(0, null, this);
***getListView().setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Cursor cursorID = getActivity().getContentResolver().query(uriContact,
new String[]{ContactsContract.Contacts._ID},
null, null, null);
contactID = cursorID.getString(cursorID.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
System.out.println(contactID);
}
});
}***
// columns requested from the database
private static final String[] PROJECTION = {
Contacts._ID, // _ID is always required
Contacts.DISPLAY_NAME_PRIMARY // that's what we want to display
};
// and name should be displayed in the text1 textview in item layout
private static final String[] FROM = { Contacts.DISPLAY_NAME_PRIMARY };
private static final int[] TO = { android.R.id.text1 };
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
// load from the "Contacts table"
Uri contentUri = Contacts.CONTENT_URI;
// no sub-selection, no sort order, simply every row
// projection says we want just the _id and the name column
return new CursorLoader(getActivity(),
contentUri,
PROJECTION,
null,
null,
null);
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
// Once cursor is loaded, give it to adapter
mAdapter.swapCursor(data);
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
// on reset take any old cursor away
mAdapter.swapCursor(null);
}
I think problem is my onItemClickListener.
How can i fix this?
Thanks from now :)
The main problem is that uriContact is null when you make the query.
The other problem is that you are only using ContactsContract.Contacts._ID as the projection, so the ID is the only thing returned.
I got it working by using null for the projection so that it returns all rows.
I also added functionality to find the currently selected contact, and display a Toast with their phone number.
This is not optimal code, since it just queries all rows and then iterates through them until it finds the currently selected contact, but it works:
getListView().setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Cursor cur = mAdapter.getCursor();
cur.moveToPosition(position);
String curName = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME_PRIMARY));
System.out.println(curName);
uriContact = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
Cursor cursorID = getContentResolver().query(uriContact,
null,
null, null, null);
for (cursorID.moveToFirst(); !cursorID.isAfterLast(); cursorID.moveToNext() ) {
String testName = cursorID.getString(cursorID.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME_PRIMARY));
if (testName != null && testName.equals(curName)) {
contactID = cursorID.getString(cursorID.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
}
}
if (contactID != null) {
System.out.println(contactID);
Toast.makeText(MainActivity.this, "contact Phone: " + contactID, Toast.LENGTH_LONG).show();
}
}
});
Edit: I got a more optimized version working, which uses the selection and selectionArgs in the query to return just the current contact info:
getListView().setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Cursor cur = mAdapter.getCursor();
cur.moveToPosition(position);
String curName = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME_PRIMARY));
System.out.println(curName);
uriContact = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
Cursor cursorID = getContentResolver().query(uriContact,
null,
ContactsContract.Contacts.DISPLAY_NAME_PRIMARY + " = ?", new String[]{curName}, null);
if (cursorID.moveToFirst()) {
contactID = cursorID.getString(cursorID.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
}
if (contactID != null) {
System.out.println(contactID);
Toast.makeText(MainActivity.this, "contact Phone: " + contactID, Toast.LENGTH_LONG).show();
}
}
});

Delete a row from SQLite DataBase doesn't work

I'm showing data from a database in a list view and I want to delete one entry when the user do a longclick in one row and then selects "yes" in a Dialog. I have all the code and it compiles but it isn't deleting anything. Any suggestion? Thanks
That's the code of the listview:
public class Consult extends FragmentActivity {
private ListView list;
private SQLiteDatabase db;
private int id = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.consult);
list = (ListView)findViewById(R.id.list);
this.getIntent();
ApeironsSQLiteHelper apeironsdb = new ApeironsSQLiteHelper(this, "DBApeirons.DB", null, 1);
db = apeironsdb.getWritableDatabase();
String[] campos = new String[]{"_id", "name", "kind_place", "score"};
Cursor c = db.query("Apeirons", campos, null, null, null, null, null);
c.moveToFirst();
String[] from = new String[]{"name", "kind_place", "score"};
int [] to = new int[] {R.id.Titulo, R.id.SubTitulo};
//#SuppressWarnings("deprecation")
MyListAdapter myadapter = new MyListAdapter (this,
R.layout.entrys, c, from, to);
list.setAdapter(myadapter);
list.setLongClickable(true);
list.setOnItemLongClickListener(new OnItemLongClickListener(){
public boolean onItemLongClick(AdapterView<?> arg0, View v,
int index, long arg3) {
saveID(index);
//db.delete("Apeirons", "_id=" + String.valueOf(index), null);
Log.d("ONCLICK", String.valueOf(index));
Log.d("ONCLICK", String.valueOf(id));
callDialog();
return false;
}
});
}
public void callDialog(){
Log.d("DIALOG", String.valueOf(id));
FragmentManager fragmentmanager = getSupportFragmentManager();
SimpleDialog dialog = new SimpleDialog();
dialog.saveIndex(id);
//SimpleDialog.newInstance(id);
dialog.show(fragmentmanager, "tag");
Log.d("erase", "salgo del callDialog");
}
public void saveID(int ID){
id = ID;
}
And that's the code of the Dialog:
public class SimpleDialog extends DialogFragment {
private SQLiteDatabase dbs;
int ID;
#Override
public Dialog onCreateDialog (Bundle savedInstanceState){
//ID = getArguments().getInt("id");
ApeironsSQLiteHelper apeironsdbs = new ApeironsSQLiteHelper(getActivity(),
"DBApeirons.DB", null, 1);
dbs = apeironsdbs.getWritableDatabase();
AlertDialog.Builder builder =
new AlertDialog.Builder(getActivity());
builder.setMessage(R.string.EraseDialogMessage);
builder.setTitle(R.string.app_name);
builder.setPositiveButton(R.string.EraseDialogPButton, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
String args = String.valueOf(ID);
Log.d("Yes BUTTON", args);
/*String sql = "DELETE FROM Apeirons WHERE _id=" + args;
dbs.execSQL(sql);*/
//int prueba = dbs.delete("Apeirons", " _id = ?" + args, null);
int prueba = dbs.delete("Apeirons", "_id = ?", new String[] { "" + args });
Log.d("RETORNO DELETE", String.valueOf(prueba));
}
});
builder.setNegativeButton(R.string.EraseDialogNButton, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
return builder.create();
}
public void saveIndex(int index){
ID = index;
}
}
I fixed!!! The problem was that I was using the id of the listview and it isn't the same in the database. Now I recover first the _id of the database and works perfect. Thank you for all the answers. The code to recover the _id of database below (maybe is useful to someone):
list.setLongClickable(true);
list.setOnItemLongClickListener(new OnItemLongClickListener(){
public boolean onItemLongClick(AdapterView<?> arg0, View v,
int index, long arg3) {
c.moveToPosition(index);
int id = c.getInt(c.getColumnIndex("_id"));
saveID(id);
Log.d("ONCLICK", String.valueOf(index));
Log.d("ONCLICK", String.valueOf(id));
callDialog();
return false;
}
});
You can try
private SQLiteDatabase dbs;
String args = String.valueOf(ID);
Delete query:
Method 1:
dbs = apeironsdbs.getWritableDatabase();
String deleteQuery = "DELETE FROM Apeirons where _id='"+ args +"'";
dbs .execSQL(deleteQuery);
Or you can use
Method 2:
ApeironsSQLiteHelper apeironsdb = new ApeironsSQLiteHelper(this, "DBApeirons.DB", null, 1);
apeironsdb .delete(Apeirons, _id+"="+ID, null); // ID is int value
Try change this line:
int prueba = dbs.delete("Apeirons", " _id = ?" + args, null);
into
int prueba = dbs.delete("Apeirons", " _id = \"" + args + "\"", null);

ListView with CursorLoader and SimpleCursorAdapter isn't displaying data

I'm trying to populate a ListView with data from a query using a CursorLoader. I'm new to CursorLoaders and I'm using code I purloined from Beginning Android 4 Application Development. As you can see, I'm getting data from an Intent. The data in the Intent is what I want; I've verified that in the debugger. However, when I query my database, nothing displays in the ListView. Can anyone help?
public class MyList extends ListActivity implements LoaderManager.LoaderCallbacks<Cursor> {
private static final String TABLE_BASEPATH = "tbl";
private static final String AUTHORITY = "SQLData";
public static final Uri MY_URI = Uri.parse("content://" + AUTHORITY + "/" + TABLE_BASEPATH);
#SuppressWarnings("deprecation")
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent myData = getIntent();
Bundle info = myData.getExtras();
if (info != null){
Cursor c;
String[] dataColumns = { "mycolumn" };
String selection = "level = '" + info.getString("Level") + "'";
if (android.os.Build.VERSION.SDK_INT < 11)
c = managedQuery(MY_URI, dataColumns, selection, null, "ORDER BY mycolumn");
else
{
CursorLoader cursorloader = new CursorLoader(this, MY_URI, dataColumns, selection, null, "ORDER BY mycolumn");
c = cursorloader.loadInBackground();
}
int[] viewIDs = { R.id.mylist1 };
SimpleCursorAdapter adapter;
if (android.os.Build.VERSION.SDK_INT < 11)
adapter = new SimpleCursorAdapter(this, R.layout.mylist, c, dataColumns, viewIDs);
else
adapter = new SimpleCursorAdapter(this, R.layout.mylist, c, dataColumns, viewIDs, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
this.setListAdapter(adapter);
}
}
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return new CursorLoader(this, MY_URI,
PROJECTION, null, null, null);
}
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
switch (loader.getId()) {
case LOADER_ID:
mAdapter.swapCursor(cursor);
break;
}
}
public void onLoaderReset(Loader<Cursor> loader) {
mAdapter.swapCursor(null);
}
It doesn't matter if I'm using the cursor or the CursorLoader. If my version is < 11 (cursor), I get no data; if it's > 11 (CursorLoader) I still get no data.
You need to put in the id column in the projection when working with ContentProviders, otherwise they "won't work". Which I think you are doing > api level 11...
String[] dataColumns = { "mycolumn" };
The above code should include the id field. If the id field is "_id" (like Sams answer):
String[] dataColumns = { "mycolumn", "_id" };

How to display an alertdialog on top of other alertdialog? And when one in foreground is closed, then the one in background should be visible

This is my code to edit/update which I am doing throgh a custom alertdialog which contains the data fetched frm database. Now when the inputs provided are incorrect I want to show other alertdialog on top of this providing some message to user. When the user dismisses this message alertdialog, the previous one which is used for update should be visible. How can I do that?
public class CountryEdit extends ListActivity{
private Long mRowId;
private CountryDbAdapter mDbHelper;
public static final String PROVIDER_NAME = "assignment2.demos.MyCountriesCP";
public static final String uriString = "content://"+ PROVIDER_NAME +"/countries";
public static final Uri CONTENT_URI = Uri.parse(uriString);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ContentResolver contentResolver = getContentResolver();
Cursor c = contentResolver.query(CONTENT_URI, null, null, null, getIntent().getExtras().getString("SORT_ORDER"));
String[] from = new String[] { "year", "country" };
int[] to = new int[] { R.id.year, R.id.country };
SimpleCursorAdapter sca = new SimpleCursorAdapter(this, R.layout.country_row,
c, from, to);
setListAdapter(sca);
mRowId = savedInstanceState != null ? savedInstanceState.getLong(assignment2.demos.MyCountriesActivity.KEY_ROWID)
: null;
if (mRowId == null) {
Bundle extras = getIntent().getExtras();
mRowId = extras != null ? extras.getLong(assignment2.demos.MyCountriesActivity.KEY_ROWID)
: null;
}
populateFields();
}
private void populateFields() {
LayoutInflater inflater=LayoutInflater.from(this);
final View addView=inflater.inflate(R.layout.add_country, null);
Cursor c = getContentResolver().query(CONTENT_URI.buildUpon().
appendPath(String.valueOf(mRowId)).build(), null, null, null, null);
/* Read alert input */
final EditText editCountry =(EditText)addView.findViewById(R.id.editCountry);
final EditText editYear =(EditText)addView.findViewById(R.id.editYear);
editCountry.setText(c.getString(c.getColumnIndex("country")));
editYear.setText(c.getString(c.getColumnIndex("year")));
new AlertDialog.Builder(this)
.setTitle("Edit country/year")
.setView(addView)
.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int whichButton) {
String country = editCountry.getText().toString();
if(country.trim().length()>0 && editYear.getText().toString().trim().length()>0){
int year = Integer.parseInt(editYear.getText().toString());
ContentValues updateValues = new ContentValues();
updateValues.put(mDbHelper.COUNTRY, country);
updateValues.put(mDbHelper.YEAR, year);
getContentResolver().update(
CONTENT_URI.buildUpon().appendPath(String.valueOf(mRowId)).build(), updateValues, null, null);
finish();
}
else{
new AlertDialog.Builder(CountryEdit.this)
.setTitle("Invalid Inputs!")
.setMessage("You need to enter Country AND Year.")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// here you can add functions
finish();
}
}).show();
// Toast.makeText(CountryEdit.this,
// "You need to enter Country AND Year.", Toast.LENGTH_LONG).show();
//finish();
}
}
})
.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int whichButton) {
// ignore, just dismiss
finish();
}
})
.show();
}
}
The first alert dialog is dismissing itself when the second is about to show (when the click listener finishes). You can't avoid that.
There's a dirty hack where you can override the click listener created by the builder like this:
create().getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener( ... }
But I don't recommend to do that if you don't know what you're doing (it might break the internet ;-).
You would have to dismiss the dialog yourself. If you don't do that it will never close, the user will see it forever and would have to kill your app to get it started again.

Categories

Resources