How to know the call state in android - android

i know from Phonestatelistener we will get to know, the call type like its incoming, or ringing or picked etc.. But once call ends i.e once phone reaches idle state, i want to know what was the state of call, was it picked, missed or rejected
lets take, +91123456789 is an incoming call, after call ends, the number will be stored in phone call log as missed call,
is there a way to fetch the recent state from call log for the particular number +91123456789, is it possible?

Here is code that can query the call log for a missed call. Basically, you will have to trigger this and make sure that you give the call log some time ( a few seconds should do it) to write the information otherwise if you check the call log too soon you will not find the most recent call.
int MISSED_CALL_TYPE = android.provider.CallLog.Calls.MISSED_TYPE
final String[] projection = null;
final String selection = null;
final String[] selectionArgs = null;
final String sortOrder = android.provider.CallLog.Calls.DATE + " DESC";
Cursor cursor = null;
try{
// cursor = context.getContentResolver().query(
// Uri.parse("content://call_log/calls"),
// projection,
// selection,
// selectionArgs,
// sortOrder);
cursor = getContentResolver().query(CallLog.Calls.CONTENT_URI, null, CallLog.Calls.NUMBER + "=? ", yourNumber, sortOrder);
while (cursor.moveToNext()) {
String callLogID = cursor.getString(cursor.getColumnIndex(android.provider.CallLog.Calls._ID));
String callNumber = cursor.getString(cursor.getColumnIndex(android.provider.CallLog.Calls.NUMBER));
String callDate = cursor.getString(cursor.getColumnIndex(android.provider.CallLog.Calls.DATE));
String callType = cursor.getString(cursor.getColumnIndex(android.provider.CallLog.Calls.TYPE));
String isCallNew = cursor.getString(cursor.getColumnIndex(android.provider.CallLog.Calls.NEW));
if(Integer.parseInt(callType) == MISSED_CALL_TYPE && Integer.parseInt(isCallNew) > 0){
if (_debug) Log.v("Missed Call Found: " + callNumber);
break ;
}
}
}catch(Exception ex){
if (_debug) Log.e("ERROR: " + ex.toString());
}finally{
cursor.close();
}
I hope you find this useful, in the same way you can get other states.
Do add this permission in manifest
android.permission.READ_CONTACTS

Related

recyclerView custom adapter binditem gets called when inserting into database

My app displays playlists where for each playlist I show albumart in recyclerview.
A custom adapter displays the rows. It all works fine but when I add another playlist, using an asynctask, the display gets redrawn several times. I have checked that there are no adapter.notifydatasetchanged() calls. Stepping through the code I have discovered that it happens when there is a resolver.insert
In this example, the routine creates a new playlist, either for whole albums or tracks.
public void addTracksToPlaylist(Context context, String music_id,
long playlist_id, String nmode, int base) {
// feed it the album_id or track_id
Uri mediauri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
ContentResolver resolver = context.getContentResolver();
Uri exturi = MediaStore.Audio.Playlists.Members.getContentUri(
"external", playlist_id);
String[] projection = {MediaStore.Audio.Media._ID, MediaStore.Audio.Media.ALBUM, MediaStore.Audio.Media.TRACK};
String where = MediaStore.Audio.Media.ALBUM_ID + " =?";
String orderBy = null;
if (nmode.equals(context.getString(R.string.track_mode))) {
where = MediaStore.Audio.Media._ID + "=?";
}
orderBy = MediaStore.Audio.Media.ARTIST + " ASC, "
+ MediaStore.Audio.Media.ALBUM + " ASC , " +
"CAST(" + (MediaStore.Audio.Media.TRACK) + " AS INTEGER) ASC";
String[] whereVal = {music_id};
Cursor c = resolver.query(mediauri, projection, where, whereVal,
orderBy);
if (c != null && c.moveToFirst()) {
int idColumn = c.getColumnIndex(MediaStore.Audio.Media._ID);
ContentValues values = new ContentValues();
boolean stamp = prefs.getstampSelected(context);
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
String audio_id = c.getString(idColumn);
values.put(MediaStore.Audio.Playlists.Members.PLAY_ORDER, base);
values.put(MediaStore.Audio.Playlists.Members.AUDIO_ID, audio_id);
try {
resolver.insert(exturi, values);
} catch (Exception e) {
e.printStackTrace();
}
// String thistrack= track.getfullPathfromAudioId(context,audio_id);
// Log.i(TAG,"position : "+base +" Inserted track = "+ audio_id + " track "+thistrack+ " Album_id = "+ music_id);
base++;
if (stamp) {
try {
track.updateTrackModifiedDate(audio_id, context);
} catch (Exception e) {
e.printStackTrace();
}
}
}
c.close();
}
}
What can I do to prevent these actions, which happen in the background, affect the display of playlists. Or in other words, why/how is my recyclerView "active" as it appears to be aware of changes in the database.
Update:
From the Android Developers website:
The Loader will monitor for changes to the data, and report them to you through new calls here. You should not monitor the data yourself. For example, if the data is a Cursor and you place it in a CursorAdapter, use the CursorAdapter(android.content.Context, android.database.Cursor, int) constructor without passing in either FLAG_AUTO_REQUERY or FLAG_REGISTER_CONTENT_OBSERVER (that is, use 0 for the flags argument). This prevents the CursorAdapter from doing its own observing of the Cursor, which is not needed since when a change happens you will get a new Cursor throw another call here.
the monitoring and reporting back by the loader manifests itself in onLoadFinished calls which in my case reset the adapter.
As was stated in the comments, the Loader monitors changes in the underlying data. The solution was simple in the end.
I declare a boolean variable
private boolean processing=false;
Set the variable to true in the onPreExecute() and to false in onPostExecute() of the AsyncTask.
As a change fires the OnLoadFinished call I test for the value of processing and skip the code. Once completed, I call getLoaderManager().restartLoader etc

How to obtain the contact Uri directly with contact creation

my app creates new contacts with ContentProviderOperation. The problem is, I need a reference to the new contact because I need some information of it to display it in a listview and go with intent into the contact app to the contact.
The best thing would be the ID, but I´ve read that it might change during operations on the database, which won´t be helpful to me.
Now I thought, the Uri might be the best thing, because I could later retrieve the contactID or lookup key.
How do I get the Uri directly after calling applyBatch() ?
EDIT:
Here is a solution, but not really a good one.
He is putting a randomly generated token into each contact, then he makes a new query with it.
I want neither put some extra data into the contacts, nor starting a second query. But if there is no other possibility I´ll do it that way.
simply call
private String retrieveContactId(String phoneNo) {
try {
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNo));
String[] projection = new String[] { ContactsContract.PhoneLookup._ID, ContactsContract.PhoneLookup.DISPLAY_NAME };
String selection = null;
String[] selectionArgs = null;
String sortOrder = ContactsContract.PhoneLookup.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
ContentResolver cr = getApplicationContext().getApplicationContext().getContentResolver();
String contactId = null;
if (cr != null) {
Cursor resultCur = cr.query(uri, projection, selection, selectionArgs, sortOrder);
if (resultCur != null) {
while (resultCur.moveToNext()) {
contactId = resultCur.getString(resultCur.getColumnIndex(ContactsContract.PhoneLookup._ID));
Log.e("Info Incoming", "Contact Id : " + contactId);
return contactId;
}
resultCur.close();
}
}
} catch (Exception sfg) {
Log.e("Error", "Error in loadContactRecord : " + sfg.toString());
}
return null;
}
and for the uri
Uri contactUri = Contacts.getLookupUri(
Integer.valueOf(rawContactId), clookup);

Get the missed call list and delete it from call log in android

I want to get the particular call type alone and delete it from the call log in android.
while (cursor.moveToNext()) {
String queryString1= "CallType=’" + CallLog.Calls.MISSED_TYPE + "‘";
Log.v("CallType", queryString1);
if(CallLog.Calls.TYPE.equals("missed")) {
sb.append("Number "+CallLog.Calls.NUMBER+"\nName "+CallLog.Calls.CACHED_NAME);
}
}
getContentResolver().delete(UriCalls, CallLog.Calls.MISSED_TYPE, null);
This is a code i ve tried for missed call,because of Missed_type is int, i got an error "The method delete(Uri, String, String[]) in the type ContentResolver is not applicable for the arguments (Uri, int, null)"
Give me some tips to delete the particular call type from log
you can use following code to fetch Missed call Alert
final String[] projection = null;
final String selection = null;
final String[] selectionArgs = null;
final String sortOrder = android.provider.CallLog.Calls.DATE + " DESC";
Cursor cursor = null;
try{
cursor = context.getContentResolver().query(
Uri.parse("content://call_log/calls"),
projection,
selection,
selectionArgs,
sortOrder);
while (cursor.moveToNext()) {
String callLogID = cursor.getString(cursor.getColumnIndex(android.provider.CallLog.Calls._ID));
String callNumber = cursor.getString(cursor.getColumnIndex(android.provider.CallLog.Calls.NUMBER));
String callDate = cursor.getString(cursor.getColumnIndex(android.provider.CallLog.Calls.DATE));
String callType = cursor.getString(cursor.getColumnIndex(android.provider.CallLog.Calls.TYPE));
String isCallNew = cursor.getString(cursor.getColumnIndex(android.provider.CallLog.Calls.NEW));
if(Integer.parseInt(callType) == MISSED_CALL_TYPE && Integer.parseInt(isCallNew) > 0){
if (_debug) Log.v("Missed Call Found: " + callNumber);
}
}
} catch(Exception ex){
if (_debug) Log.e("ERROR: " + ex.toString());
}finally{
cursor.close();
}
You can also use this link http://android2011dev.blogspot.in/2011/08/get-android-phone-call-historylog.html
<uses-permission android:name="android.permission.READ_LOGS"></uses-permission>
Give above permission in androidmanifest.xml
use following link to delete missed call list , you just need to pass number that u got from above code
http://www.mobisoftinfotech.com/blog/android/androidcalllogdeletion/

send sms for a missed calls

i would like to develop an app that send a message when ever that receives a missed
call.but i have a problem when ever i start that activity that send the sms to previous
ones how to solve this problem,i have a small idea a set that particular missed call as
read or delete it other wise my app has to access the missed the missed calls i a
specific peroid of time
try{
cursor = getContentResolver().query(
Uri.parse("content://call_log/calls"),
projection,
selection,
selectionArgs,
sortOrder);
// cursor.getString(cursor.getColumnIndex(android.provider.CallLog.Calls.MISSED_TYPE));
while (cursor.moveToNext()) {
String callLogID = cursor.getString(cursor.getColumnIndex(android.provider.CallLog.Calls._ID));
String callNumber = cursor.getString(cursor.getColumnIndex(android.provider.CallLog.Calls.NUMBER));
String callDate = cursor.getString(cursor.getColumnIndex(android.provider.CallLog.Calls.DATE));
String callType = cursor.getString(cursor.getColumnIndex(android.provider.CallLog.Calls.TYPE));
String isCallNew = cursor.getString(cursor.getColumnIndex(android.provider.CallLog.Calls.NEW));
//String missedcall= cursor.getString(cursor.getColumnIndex(android.provider.CallLog.Calls.MISSED_TYPE));
/*if(Integer.parseInt(callType) == android.provider.CallLog.Calls.MISSED_TYPE && Integer.parseInt(isCallNew) > 0){
tv.append("hai");
//if (_debug) Log.v("Missed Call Found: " + callNumber);
}*/
if(cursor.getString(cursor.getColumnIndexOrThrow(android.provider.CallLog.Calls.TYPE)).equalsIgnoreCase("3") && Integer.parseInt(isCallNew)>0)
{
tv.append("ok"+callNumber+"\n");
sm.sendTextMessage(callNumber, null, " iam in work i will call you later", null, null);
}
}
}catch(Exception ex){
//if (_debug) Log.e("ERROR: " + ex.toString());
I guess you should make a broadcastreceiver that listenens to the phone state like this one:
broadcast receiver for missed call in android

How to retrieve missed calls on Android SDK 2.2

in my app I should do some action when a call comes but not answered by the user.
I have searched in the android.telephony and the NotificationManager, but I haven't found a method to solve this problem.
Does someone have an idea of how to get to know if there is a missed call on the phone or not ?
Here is code that can query the call log for a missed call. Basically, you will have to trigger this somehow and make sure that you give the call log some time ( a few seconds should do it) to write the information otherwise if you check the call log too soon you will not find the most recent call.
final String[] projection = null;
final String selection = null;
final String[] selectionArgs = null;
final String sortOrder = android.provider.CallLog.Calls.DATE + " DESC";
Cursor cursor = null;
try{
cursor = context.getContentResolver().query(
Uri.parse("content://call_log/calls"),
projection,
selection,
selectionArgs,
sortOrder);
while (cursor.moveToNext()) {
String callLogID = cursor.getString(cursor.getColumnIndex(android.provider.CallLog.Calls._ID));
String callNumber = cursor.getString(cursor.getColumnIndex(android.provider.CallLog.Calls.NUMBER));
String callDate = cursor.getString(cursor.getColumnIndex(android.provider.CallLog.Calls.DATE));
String callType = cursor.getString(cursor.getColumnIndex(android.provider.CallLog.Calls.TYPE));
String isCallNew = cursor.getString(cursor.getColumnIndex(android.provider.CallLog.Calls.NEW));
if(Integer.parseInt(callType) == MISSED_CALL_TYPE && Integer.parseInt(isCallNew) > 0){
if (_debug) Log.v("Missed Call Found: " + callNumber);
}
}
}catch(Exception ex){
if (_debug) Log.e("ERROR: " + ex.toString());
}finally{
cursor.close();
}
I hope you find this useful.
From what I understand, you need to query the CallLog provider (or maybe CallLog.Calls), and this page explains how to query content provider: http://developer.android.com/guide/topics/providers/content-providers.html#basics
I'd be happy to see the code if you can make this work !
I suppose you have content providers to access call logs.
http://www.anddev.org/video-tut_-_querying_and_displaying_the_calllog-t169.html
http://www.devx.com/wireless/Article/41133
If this code works you just need to run this query at the right time. I mean check some samples that can notify you when you get a call in your device
http://groups.google.com/group/android-developers/browse_thread/thread/d97a759a3708cbe3
Once you get this notification put a timer or use some built in Intents to find that the phone is back to normal state and access the call logs...
Possible duplicate
broadcast receiver for missed call in android
Show Toast on Missed Call in android application

Categories

Resources