When i was looking through my contacts in phone i see whatsapp number also for those who have whatsapp account.The thing which i want to do is filter my contact list and display numbers which are synced with whatsapp.I am successfully retrieving all the contact id,number and account associated with it but not displaying whatsappaccount.Only associated google account is getting displayed.Is there any way to get whatsapp contact from local phonebook itself? I used the following code:
ContentResolver cr1 = getContentResolver();
Cursor cur = cr1.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
if (cur.getCount() > 0)
{
while (cur.moveToNext())
{
String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
String name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0)
{
Cursor pCur = cr1.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[] { id }, null);
while (pCur.moveToNext())
{
//phoneContactList.add(name);
Log.i("Contact List", name);
Log.i("Contact List", id);
getContactAccount(id,cr1);
}
pCur.close();
}
}
}
public void getContactAccount(String id,ContentResolver contentResolver){
Cursor cursor = null;
try {
cursor = contentResolver.query(ContactsContract.RawContacts.CONTENT_URI,
new String[]{ContactsContract.RawContacts.ACCOUNT_NAME, ContactsContract.RawContacts.ACCOUNT_TYPE},
ContactsContract.RawContacts.CONTACT_ID +"=?",
new String[]{String.valueOf(id)},
null);
if (cursor != null && cursor.getCount() >0){
cursor.moveToFirst();
System.out.println("Account name is"+cursor.getString(cursor.getColumnIndex(ContactsContract.RawContacts.ACCOUNT_NAME)));
System.out.println("Account type is"+cursor.getString(cursor.getColumnIndex(ContactsContract.RawContacts.ACCOUNT_TYPE)));
cursor.close();
}
} catch (Exception e) {
System.out.println(""+this.getClass().getName()+","+ e.getMessage());
} finally{
cursor.close();
}
}
Use following code to get WhatsApp contacts from phonebook with associated WhatsApp number :
private void displayWhatsAppContacts() {
final String[] projection = {
ContactsContract.Data.CONTACT_ID,
ContactsContract.Data.DISPLAY_NAME,
ContactsContract.Data.MIMETYPE,
"account_type",
ContactsContract.Data.DATA3,
};
final String selection = ContactsContract.Data.MIMETYPE + " =? and account_type=?";
final String[] selectionArgs = {
"vnd.android.cursor.item/vnd.com.whatsapp.profile",
"com.whatsapp"
};
ContentResolver cr = getContentResolver();
Cursor c = cr.query(
ContactsContract.Data.CONTENT_URI,
projection,
selection,
selectionArgs,
null);
while (c.moveToNext()) {
String id = c.getString(c.getColumnIndex(ContactsContract.Data.CONTACT_ID));
String number = c.getString(c.getColumnIndex(ContactsContract.Data.DATA3));
String name = c.getString(c.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
Log.v("WhatsApp", "name " +name + " - number - "+number);
}
Log.v("WhatsApp", "Total WhatsApp Contacts: " + c.getCount());
c.close();
}
The MIME type for whatsapp is: "vnd.android.cursor.item/vnd.com.whatsapp.profile"
Use the following code`:
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment implements LoaderCallbacks<Cursor>,AdapterView.OnItemClickListener {
/*
* Defines an array that contains column names to move from
* the Cursor to the ListView.
*/
private final static String[] FROM_COLUMNS = {
Build.VERSION.SDK_INT
>= Build.VERSION_CODES.HONEYCOMB ?
Data.DISPLAY_NAME :
Data.DISPLAY_NAME
};
/*
* Defines an array that contains resource ids for the layout views
* that get the Cursor column contents. The id is pre-defined in
* the Android framework, so it is prefaced with "android.R.id"
*/
private final static int[] TO_IDS = {
android.R.id.text1
};
// Define global mutable variables
// Define a ListView object
ListView mContactsList;
// Define variables for the contact the user selects
// The contact's _ID value
long mContactId;
// The contact's LOOKUP_KEY
String mContactKey;
// A content URI for the selected contact
Uri mContactUri;
// The column index for the _ID column
private static final int CONTACT_ID_INDEX = 0;
// The column index for the LOOKUP_KEY column
private static final int LOOKUP_KEY_INDEX = 1;
// Defines the text expression
private static final String mime_type ="vnd.android.cursor.item/vnd.com.whatsapp.profile";
private static final String SELECTION =
Data.MIMETYPE + " = '" + mime_type + "'";
// Defines a variable for the search string
private String mSearchString="Gourav";
// Defines the array to hold values that replace the ?
private String[] mSelectionArgs = { mSearchString };
private static final String[] PROJECTION =
{
Contacts._ID,
Contacts.LOOKUP_KEY,
Data.DISPLAY_NAME,
Build.VERSION.SDK_INT
>= Build.VERSION_CODES.HONEYCOMB ?
Data.MIMETYPE :
Data.MIMETYPE
};
// An adapter that binds the result Cursor to the ListView
private SimpleCursorAdapter mCursorAdapter;
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container,
false);
return rootView;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
getLoaderManager().initLoader(0, null, this);
// Gets the ListView from the View list of the parent activity
mContactsList = (ListView) getActivity().findViewById(R.id.list);
// Gets a CursorAdapter
mCursorAdapter = new SimpleCursorAdapter(
getActivity(),
R.layout.contact_list,
null,
FROM_COLUMNS, TO_IDS,
0);
// Sets the adapter for the ListView
mContactsList.setAdapter(mCursorAdapter);
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
// TODO Auto-generated method stub
// Get the Cursor
Cursor cursor = (Cursor) parent.getAdapter().getItem(position);
// Move to the selected contact
cursor.moveToPosition(position);
// Get the _ID value
mContactId = cursor.getLong(CONTACT_ID_INDEX);
// Get the selected LOOKUP KEY
mContactKey = cursor.getString(LOOKUP_KEY_INDEX);
// Create the contact's content Uri
mContactUri = Contacts.getLookupUri(mContactId, mContactKey);
/*
* You can use mContactUri as the content URI for retrieving
* the details for a contact.
*/
}
#Override
public android.support.v4.content.Loader<Cursor> onCreateLoader(
int arg0, Bundle arg1) {
// TODO Auto-generated method stub
/*
* Makes search string into pattern and
* stores it in the selection array
*/
CursorLoader cursor = null;
mSelectionArgs[0] = "%" + mSearchString + "%";
Log.d("ON CREATE LOADER", "ONCLREATE LOADER CALLLEd");
try
{
cursor=new CursorLoader(
getActivity(),
Data.CONTENT_URI,
PROJECTION,
SELECTION,
null,
null
);
}
catch(Exception e)
{
e.printStackTrace();
}
// Starts the query
return cursor;
}
#Override
public void onLoadFinished(
android.support.v4.content.Loader<Cursor> arg0, Cursor cursor) {
// TODO Auto-generated method stub
Log.d("onLoadFinished", String.valueOf(cursor.getCount()));
mCursorAdapter.swapCursor(cursor);
}
#Override
public void onLoaderReset(android.support.v4.content.Loader<Cursor> arg0) {
// TODO Auto-generated method stub
mCursorAdapter.swapCursor(null);
}
}
}
Related
I'm having an Activity which handles a details Fragment for my Movie data & I want to implement favorite functionality. But the issue is that I can favorite only one movie at a time. Also, each time I try to add/favorite a movie, it'll show on the database that it's being saved but never being deleted on unfavorite.
Here's the code that I've:
MovieDetailsActivity
public class MovieDetailsActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/* Set the content of the activity to use the activity_tv_show_details.xml layout file */
setContentView(R.layout.activity_movie_details);
Bundle movieDetails = new Bundle();
/**get the movie's Object from the parent activity**/
Movie movie = getIntent().getParcelableExtra("movie");
movieDetails.putParcelable("movie", movie);
Intent intent = getIntent();
Uri mCurrentMovieUri = intent.getData();
movieDetails.putString("currentMovieUri", mCurrentMovieUri.toString());
/* Check for pre-existing instances of fragments(here explicitly check for savedInstance)
and then begin fragment transaction accordingly */
if (savedInstanceState == null) {
MovieDetailsFragment defaultMovieFragment = new MovieDetailsFragment();
defaultMovieFragment.setArguments(movieDetails);
getSupportFragmentManager().beginTransaction()
.add(R.id.containerMovieDetailActivity, defaultMovieFragment)
.commit();
}
}
}
MovieDetailsFragment
public class MovieDetailsFragment extends Fragment implements LoaderManager.LoaderCallbacks<MovieDetailsBundle> {
private static final int MOVIE_DETAIL_LOADER_ID = 2;
/* Arrays for holding movie details */
Movie movie;
public MovieDetailsFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_movie_detail, container, false);
Bundle bundle = getArguments();
position = bundle.getInt("position");
currentMovieUri = Uri.parse(bundle.getString("currentMovieUri"));
favoriteButton = (ImageButton) rootView.findViewById(R.id.favorite);
if (savedInstanceState == null) {
mReview = new ArrayList<>();
mVideo = new ArrayList<>();
mCredits = new ArrayList<>();
mMovieDetailsBundle = new MovieDetailsBundle();
}
if ((bundle != null)) {
movie = getArguments().getParcelable("movie");
movieDetailTitleTextView.setText(movie.getMovieTitle());
...
String[] projection = {
MoviesEntry._ID,
MoviesEntry.COLUMN_MOVIE_TITLE,
MoviesEntry.COLUMN_MOVIE_RELEASE_DATE,
MoviesEntry.COLUMN_MOVIE_OVERVIEW,
MoviesEntry.COLUMN_MOVIE_POSTER_URL,
MoviesEntry.COLUMN_MOVIE_BACKDROP_URL,
MoviesEntry.COLUMN_MOVIE_RATING};
// Perform a query on the provider using the ContentResolver.
// Use the {#link MoviesEntry#CONTENT_URI} to access the pet data.
Cursor cursor = getActivity().getContentResolver().query(
MoviesEntry.CONTENT_URI, // The content URI of the movies table
projection, // The columns to return for each row
null, // Selection criteria
null, // Selection criteria
null);
try {
// Figure out the index of each column
int idColumnIndex = cursor.getColumnIndex(MoviesEntry._ID);
int titleColumnIndex = cursor.getColumnIndex(MoviesEntry.COLUMN_MOVIE_TITLE);
int releaseDateColumnIndex = cursor.getColumnIndex(MoviesEntry.COLUMN_MOVIE_RELEASE_DATE);
int overviewColumnIndex = cursor.getColumnIndex(MoviesEntry.COLUMN_MOVIE_OVERVIEW);
int posterUrlColumnIndex = cursor.getColumnIndex(MoviesEntry.COLUMN_MOVIE_POSTER_URL);
int backdropUrlColumnIndex = cursor.getColumnIndex(MoviesEntry.COLUMN_MOVIE_BACKDROP_URL);
int ratingColumnIndex = cursor.getColumnIndex(MoviesEntry.COLUMN_MOVIE_RATING);
// Iterate through all the returned rows in the cursor
if (cursor.moveToFirst()){
// Use that index to extract the String or Int value of the word
// at the current row the cursor is on.
currentID = cursor.getInt(idColumnIndex);
currentTitle = cursor.getString(titleColumnIndex);
currentReleaseDate = cursor.getString(releaseDateColumnIndex);
currentOverview = cursor.getString(overviewColumnIndex);
currentposterUrl = cursor.getString(posterUrlColumnIndex);
currentBackdropUrl = cursor.getString(backdropUrlColumnIndex);
currentRatings = cursor.getFloat(ratingColumnIndex);
}
} finally {
// Always close the cursor when you're done reading from it. This releases all its
// resources and makes it invalid.
cursor.close();
}
if (currentTitle!=null) {
//currentTitle = movie.getMovieTitle();
if (currentTitle.equals(movie.getMovieTitle())) {
favoriteButton.setImageResource(R.drawable.starred);
favorite = true;
}
}else{
favoriteButton.setImageResource(R.drawable.unstarred);
favorite = false;
}
/*setting the ratingbar from #link: https://github.com/FlyingPumba/SimpleRatingBar*/
SimpleRatingBar simpleRatingBar = (SimpleRatingBar) rootView.findViewById(R.id.movieRatingInsideMovieDetailsFragment);
simpleRatingBar.setRating((float) (movie.getMovieVoteAverage()) / 2);
favoriteButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (favorite) {
// Only perform the delete if this is an existing movie.
if (currentMovieUri != null) {
// Call the ContentResolver to delete the movie at the given content URI.
// Pass in null for the selection and selection args because the mCurrentPetUri
// content URI already identifies the movie that we want.
int rowsDeleted = getActivity().getContentResolver().delete(currentMovieUri, null, null);
// Show a toast message depending on whether or not the delete was successful.
if (rowsDeleted == 0) {
// If no rows were deleted, then there was an error with the delete.
Toast.makeText(getContext(), getString(R.string.delete_movie_failed),
Toast.LENGTH_SHORT).show();
} else {
// Otherwise, the delete was successful and we can display a toast.
Toast.makeText(getContext(), getString(R.string.delete_movie_successful),
Toast.LENGTH_SHORT).show();
}
}
favoriteButton.setImageResource(R.drawable.unstarred);
} else {
// Create a ContentValues object where column names are the keys,
// and movie attributes from the editor are the values.
ContentValues values = new ContentValues();
values.put(MoviesEntry.COLUMN_MOVIE_TITLE, movie.getMovieTitle());
values.put(MoviesEntry.COLUMN_MOVIE_RELEASE_DATE, movie.getMovieReleaseDate());
values.put(MoviesEntry.COLUMN_MOVIE_OVERVIEW, movie.getMovieOverview());
values.put(MoviesEntry.COLUMN_MOVIE_POSTER_URL, movie.getMoviePosterPath());
values.put(MoviesEntry.COLUMN_MOVIE_BACKDROP_URL, movie.getMovieBackdropPath());
values.put(MoviesEntry.COLUMN_MOVIE_RATING, movie.getMovieVoteAverage() / 2);
// Insert a new movie into the provider, returning the content URI for the new movie.
Uri newUri = getActivity().getContentResolver().insert(MoviesEntry.CONTENT_URI, values);
// Show a toast message depending on whether or not the insertion was successful
if (newUri == null) {
// If the new content URI is null, then there was an error with insertion.
Toast.makeText(getContext(), getString(R.string.insert_movie_failed),
Toast.LENGTH_SHORT).show();
} else {
// Otherwise, the insertion was successful and we can display a toast.
Toast.makeText(getContext(), getString(R.string.insert_movie_successful),
Toast.LENGTH_SHORT).show();
}
favoriteButton.setImageResource(R.drawable.starred);
}
favorite = !favorite;
}
});
...
#Override
public Loader<MovieDetailsBundle> onCreateLoader(int id, Bundle args) {
Uri baseUri = Uri.parse((UrlsAndConstants.MovieDetailQuery.DEFAULT_URL) + movie.getMovieId());
Uri.Builder uriBuilder = baseUri.buildUpon();
uriBuilder.appendQueryParameter(API_KEY_PARAM, API_KEY_PARAM_VALUE);
uriBuilder.appendQueryParameter(APPEND_TO_RESPONSE, VIDEOS_AND_REVIEWS_AND_CREDITS);
return new DetailsMovieLoader(getActivity().getApplicationContext(), uriBuilder.toString());
}
#Override
public void onLoadFinished(Loader<MovieDetailsBundle> loader, )
...
}
public void updateDurationTextView(MovieDetailsBundle movieDetailsBundle) {
...
movieRunTimeDuration.setText(mMovieDurationString);
}
#Override
public void onLoaderReset(Loader<MovieDetailsBundle> loader) {
}
}
ContentProvider
public class MovieProvider extends ContentProvider {
/**
* URI matcher code for the content URI for the movies table
*/
private static final int MOVIES = 100;
/**
* URI matcher code for the content URI for a single movie in the movie table
*/
private static final int MOVIE_ID = 200;
/**
* UriMatcher object to match a content URI to a corresponding code.
* The input passed into the constructor represents the code to return for the root URI.
* It's common to use NO_MATCH as the input for this case.
*/
private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
// Static initializer. This is run the first time anything is called from this class.
static {
// The calls to addURI() go here, for all of the content URI patterns that the provider
// should recognize. All paths added to the UriMatcher have a corresponding code to return
// when a match is found.
// The content URI of the form "content://com.example.android.movie/movie" will map to the
// integer code {#link #MOVIES}. This URI is used to provide access to MULTIPLE rows
// of the movie table.
sUriMatcher.addURI(MovieContract.CONTENT_AUTHORITY, MovieContract.PATH_MOVIES, MOVIES);
// The content URI of the form "content://com.example.android.movie/movie/#" will map to the
// integer code {#link #MOVIES}. This URI is used to provide access to ONE single row
// of the movie table.
//
// In this case, the "#" wildcard is used where "#" can be substituted for an integer.
// For example, "content://com.example.android.movie/movie/3" matches, but
// "content://com.example.android.movie/movie" (without a number at the end) doesn't match.
sUriMatcher.addURI(MovieContract.CONTENT_AUTHORITY, MovieContract.PATH_MOVIES + "/#", MOVIE_ID);
}
/**
* Database helper object
*/
private MovieDbHelper mDbHelper;
#Override
public boolean onCreate() {
mDbHelper = new MovieDbHelper(getContext());
return true;
}
#Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
// Get readable database
SQLiteDatabase database = mDbHelper.getReadableDatabase();
// This cursor will hold the result of the query
Cursor cursor;
// Figure out if the URI matcher can match the URI to a specific code
int match = sUriMatcher.match(uri);
switch (match) {
case MOVIES:
// For the MOVIES code, query the movie table directly with the given
// projection, selection, selection arguments, and sort order. The cursor
// could contain multiple rows of the movie table.
cursor = database.query(MoviesEntry.TABLE_NAME, projection, selection, selectionArgs,
null, null, sortOrder);
break;
case MOVIE_ID:
// For the MOVIE_ID code, extract out the ID from the URI.
// For an example URI such as "content://com.example.android.movie/movie/3",
// the selection will be "_id=?" and the selection argument will be a
// String array containing the actual ID of 3 in this case.
//
// For every "?" in the selection, we need to have an element in the selection
// arguments that will fill in the "?". Since we have 1 question mark in the
// selection, we have 1 String in the selection arguments' String array.
selection = MoviesEntry._ID + "=?";
selectionArgs = new String[]{String.valueOf(ContentUris.parseId(uri))};
// This will perform a query on the movie table where the _id equals 3 to return a
// Cursor containing that row of the table.
cursor = database.query(MoviesEntry.TABLE_NAME, projection, selection, selectionArgs,
null, null, sortOrder);
break;
default:
throw new IllegalArgumentException("Cannot query unknown URI " + uri);
}
// Set notification URI on the Cursor,
// so we know what content URI the Cursor was created for.
// If the data at this URI changes, then we know we need to update the Cursor.
cursor.setNotificationUri(getContext().getContentResolver(), uri);
// Return the cursor
return cursor;
}
#Override
public Uri insert(Uri uri, ContentValues contentValues) {
final int match = sUriMatcher.match(uri);
switch (match) {
case MOVIES:
return insertMovie(uri, contentValues);
default:
throw new IllegalArgumentException("Insertion is not supported for " + uri);
}
}
/**
* Insert a movie into the database with the given content values. Return the new content URI
* for that specific row in the database.
*/
private Uri insertMovie(Uri uri, ContentValues values) {
// Log.v("my_tag", "Received Uri to be matched insert is :"+uri.toString());
Log.i("my_tag", "Received Uri to be matched insert is :"+uri.toString());
// Check that the product name is not null
String title = values.getAsString(MoviesEntry.COLUMN_MOVIE_TITLE);
if (title == null) {
throw new IllegalArgumentException("Product requires a name");
}
// Check that the product name is not null
String releaseDate = values.getAsString(MoviesEntry.COLUMN_MOVIE_RELEASE_DATE);
if (releaseDate == null) {
throw new IllegalArgumentException("Product requires a detail");
}
// If the price is provided, check that it's greater than or equal to 0
String overview = values.getAsString(MoviesEntry.COLUMN_MOVIE_OVERVIEW);
if (overview == null) {
throw new IllegalArgumentException("Product requires valid price");
}
String posterUrl = values.getAsString(MoviesEntry.COLUMN_MOVIE_POSTER_URL);
if (posterUrl == null) {
throw new IllegalArgumentException("Product requires valid quantity");
}
String backdropUrl = values.getAsString(MoviesEntry.COLUMN_MOVIE_BACKDROP_URL);
if (backdropUrl == null) {
throw new IllegalArgumentException("Product requires valid quantity");
}
Integer ratings = values.getAsInteger(MoviesEntry.COLUMN_MOVIE_RATING);
if (ratings != null && ratings < 0) {
throw new IllegalArgumentException("Product requires valid quantity");
}
// Get writeable database
SQLiteDatabase database = mDbHelper.getWritableDatabase();
// Insert the new product with the given values
long id = database.insert(MoviesEntry.TABLE_NAME, null, values);
Log.i("my_tag", "values is :"+values.toString());
// Log.e("my_tag", "values is :"+values.toString());
// Log.v("my_tag", "values is :"+values.toString());
if (id == -1) {
return null;
}
// Notify all listeners that the data has changed for the product content URI
getContext().getContentResolver().notifyChange(uri, null);
// Return the new URI with the ID (of the newly inserted row) appended at the end
return ContentUris.withAppendedId(uri, id);
}
#Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// Get writeable database
SQLiteDatabase database = mDbHelper.getWritableDatabase();
// Track the number of rows that were deleted
int rowsDeleted;
final int match = sUriMatcher.match(uri);
case MOVIES:
// Delete all rows that match the selection and selection args
rowsDeleted = database.delete(MoviesEntry.TABLE_NAME, selection, selectionArgs);
break;
case MOVIE_ID:
// Delete a single row given by the ID in the URI
selection = MoviesEntry._ID + "=?";
selectionArgs = new String[]{String.valueOf(ContentUris.parseId(uri))};
Log.i("my_tag", "selection is :"+selection);
// Log.e("my_tag", "selection is :"+selection);
// Log.v("my_tag", "selection is :"+selection);
Log.i("my_tag", "selectionArgs is :"+selectionArgs[0]);
// Log.e("my_tag", "selectionArgs is :"+selectionArgs[0]);
// Log.v("my_tag", "selectionArgs is :"+selectionArgs[0]);
rowsDeleted = database.delete(MoviesEntry.TABLE_NAME, selection, selectionArgs);
break;
default:
throw new IllegalArgumentException("Deletion is not supported for " + uri);
}
// If 1 or more rows were deleted, then notify all listeners that the data at the
// given URI has changed
if (rowsDeleted != 0) {
getContext().getContentResolver().notifyChange(uri, null);
}
// Return the number of rows deleted
return rowsDeleted;
}
#Override
public int update(Uri uri, ContentValues contentValues, String selection,
String[] selectionArgs) {
...
}
#Override
public String getType(Uri uri) {
final int match = sUriMatcher.match(uri);
switch (match) {
case MOVIES:
return MoviesEntry.CONTENT_LIST_TYPE;
case MOVIE_ID:
return MoviesEntry.CONTENT_ITEM_TYPE;
default:
throw new IllegalStateException("Unknown URI " + uri + " with match " + match);
}
}
}
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();
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();
}
}
});
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 what i have done, to retrieve the id but it says that getIndexColumn is not defined in the cursor... what i'm doing wrong?
protected void onListItemClick(ListView l, View v, int position, long id) {
Cursor data = (Cursor)l.getItemAtPosition(position);
String cat = Cursor.getString(Cursor.getIndexColumn(MySQLiteHelper.COLUMN_ID));
Intent myIntent = new Intent(MainActivity.this, sondaggioActivity.class);
myIntent.putExtra("categoriaId", cat);
MainActivity.this.startActivity(myIntent);
}
this is the category class:
public class categorie {
private long id;
private String nome;
private long preferita;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public long getPreferita() {
return preferita;
}
public void setPreferita(long preferita) {
this.preferita = preferita;
}
// Will be used by the ArrayAdapter in the ListView
#Override
public String toString() {
return nome;
}
}
and this is the datasource:
public class pollDataSource {
// Database fields
private SQLiteDatabase database;
private MySQLiteHelper dbHelper;
private String[] allCategorieColumns = { MySQLiteHelper.COLUMN_ID,
MySQLiteHelper.COLUMN_PREF, MySQLiteHelper.COLUMN_NOME };
private String[] allSondaggiColumns = { MySQLiteHelper.COLUMN_ID,
MySQLiteHelper.COLUMN_CATID, MySQLiteHelper.COLUMN_DOMANDA };
private String[] allRisposteColumns = { MySQLiteHelper.COLUMN_ID,
MySQLiteHelper.COLUMN_SONDID, MySQLiteHelper.COLUMN_RISPOSTA,
MySQLiteHelper.COLUMN_SELEZIONATA };
public pollDataSource(Context context) {
dbHelper = new MySQLiteHelper(context);
}
public void open() throws SQLException {
database = dbHelper.getWritableDatabase();
}
public void close() {
dbHelper.close();
}
public categorie createCategoria(String categoria) {
ContentValues values = new ContentValues();
values.put(MySQLiteHelper.COLUMN_NOME, categoria);
values.put(MySQLiteHelper.COLUMN_PREF, 0);
long insertId = database.insert(MySQLiteHelper.TABLE_CATEGORIE, null,
values);
Cursor cursor = database.query(MySQLiteHelper.TABLE_CATEGORIE,
allCategorieColumns, MySQLiteHelper.COLUMN_ID + " = " + insertId, null,
null, null, null);
cursor.moveToFirst();
categorie newCategoria = cursorToCategorie(cursor);
cursor.close();
return newCategoria;
}
public void deleteCategoria(categorie categoria) {
long id = categoria.getId();
System.out.println("Categoria cancellata, id: " + id);
database.delete(MySQLiteHelper.TABLE_CATEGORIE, MySQLiteHelper.COLUMN_ID
+ " = " + id, null);
}
public sondaggi createSondaggio(String domanda, int catid) {
ContentValues values = new ContentValues();
values.put(MySQLiteHelper.COLUMN_DOMANDA, domanda);
values.put(MySQLiteHelper.COLUMN_CATID, catid);
long insertId = database.insert(MySQLiteHelper.TABLE_SONDAGGI, null,
values);
Cursor cursor = database.query(MySQLiteHelper.TABLE_SONDAGGI,
allSondaggiColumns, MySQLiteHelper.COLUMN_ID + " = " + insertId, null,
null, null, null);
cursor.moveToFirst();
sondaggi newSondaggio = cursorToSondaggi(cursor);
cursor.close();
return newSondaggio;
}
public void deleteSondaggio(sondaggi sondaggio) {
long id = sondaggio.getId();
System.out.println("Sondaggio cancellato, id: " + id);
database.delete(MySQLiteHelper.TABLE_SONDAGGI, MySQLiteHelper.COLUMN_ID
+ " = " + id, null);
}
public Cursor getAllCategorie() {
List<categorie> categorie = new ArrayList<categorie>();
Cursor cursor = database.query(MySQLiteHelper.TABLE_CATEGORIE,
allCategorieColumns, null, null, null, null, null);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
categorie categoria = cursorToCategorie(cursor);
categorie.add(categoria);
cursor.moveToNext();
}
// Make sure to close the cursor
// cursor.close();
return cursor;
}
private categorie cursorToCategorie(Cursor cursor) {
categorie categorie = new categorie();
categorie.setId(cursor.getLong(0));
categorie.setPreferita(cursor.getLong(1));
categorie.setNome(cursor.getString(2));
return categorie;
}
private sondaggi cursorToSondaggi(Cursor cursor) {
sondaggi sondaggi = new sondaggi();
sondaggi.setId(cursor.getLong(0));
sondaggi.setDomanda(cursor.getString(1));
sondaggi.setCatid(cursor.getLong(2));
return sondaggi;
}
}
the main activity:
public class MainActivity extends ListActivity {
private pollDataSource datasource;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
datasource = new pollDataSource(this);
datasource.open();
Cursor values = datasource.getAllCategorie();
String[] categorieColumns =
{
MySQLiteHelper.COLUMN_NOME // Contract class constant containing the word column name
};
int[] mWordListItems = { R.id.categoria_label };
SimpleCursorAdapter adapter = new SimpleCursorAdapter(
getApplicationContext(), // The application's Context object
R.layout.single_list_item, // A layout in XML for one row in the ListView
values, // The result from the query
categorieColumns, // A string array of column names in the cursor
mWordListItems, // An integer array of view IDs in the row layout
0); // Flags (usually none are needed)
setListAdapter(adapter);
}
public void onClick(View view) {
switch (view.getId()) {
case R.id.add:
datasource.createCategoria("peppe");
break;
}
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
Intent myIntent = new Intent(MainActivity.this, sondaggioActivity.class);
myIntent.putExtra("categoriaId", id);
MainActivity.this.startActivity(myIntent);
//Toast.makeText(this, selection, Toast.LENGTH_LONG).show();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
I assume you have an activity with a list of categories, and onClick of a particular item you want to launch new activity with details of that Item.
I suggest you when you launch the listScreen, query all/some items and maintaine an arrayList of items and save that in some singleton class, then onClick of a particular item pass that index to detail screen via intent.putExtra("index", position) and on detail Screen get that index via getIntent().getIntExtra("index", -1) .now get details of that particular index from arraylist saved in singleton class.
This approach will reduce cost of querying every time from database and data will be available easily.
Change
Cursor data = (Cursor)l.getItemAtPosition(position);
String cat = Cursor.getString(Cursor.getIndexColumn(MySQLiteHelper.COLUMN_ID));
to
Cursor data = (Cursor)l.getItemAtPosition(position);
Long clid = data.getLong(data.getIndexColumn(MySQLiteHelper.COLUMN_ID));
String cat=Long.toString(clid);
those two lines:
Cursor data = (Cursor)l.getItemAtPosition(position);
String cat = Cursor.getString(Cursor.getIndexColumn(MySQLiteHelper.COLUMN_ID));
makes absolutely no sense at all! If you're using a CursorAdapter why are you creating an array of objects? If you're using a ArrayAdapter why are you getting data from cursor?
Also, Cursor don't have any static methods to be called like that. That shouldn't even compile.
If you're using a CursorAdater (or some class that extend it) you the id is passed to you long id here protected void onListItemClick(ListView l, View v, int position, long id)