public class callLogs extends BroadcastReceiver {
String phNumber, callType, callDate, callDuration, dir;
Date callDayTime;
List<calls> data = new ArrayList<>();
SharedPreferences pref;
SharedPreferences.Editor edit;
ConnectionDetector cd;
private callsData callsData;
private callsDb callsDb;
private static final String DATABASE_NAME = "callsData";
#Override
public void onReceive(final Context context, Intent intent) {
pref = context.getSharedPreferences("pref", Context.MODE_PRIVATE);
edit = pref.edit();
callsData = Room.databaseBuilder(context.getApplicationContext(),
callsData.class, DATABASE_NAME).fallbackToDestructiveMigration().build();
// cd = new ConnectionDetector(context.getApplicationContext());
CountDownTimer countDownTimer = new CountDownTimer(500 , 1000) {
#Override
public void onTick(long l) {
}
#Override
public void onFinish() {
StringBuffer sb = new StringBuffer();
String strOrder = android.provider.CallLog.Calls.DATE + " DESC";
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
Cursor managedCursor = context.getContentResolver().query(CallLog.Calls.CONTENT_URI, null, null, null, strOrder);
int name = managedCursor.getColumnIndex(CallLog.Calls.CACHED_NAME);
int number = managedCursor.getColumnIndex(CallLog.Calls.NUMBER);
int type = managedCursor.getColumnIndex(CallLog.Calls.TYPE);
int date = managedCursor.getColumnIndex(CallLog.Calls.DATE);
int duration = managedCursor.getColumnIndex(CallLog.Calls.DURATION);
sb.append("Call Details :");
managedCursor.moveToFirst();
// while (managedCursor.moveToNext()) {
String pName = managedCursor.getString(name);
phNumber = managedCursor.getString(number); // mobile number
callType = managedCursor.getString(type); // call type
callDate = managedCursor.getString(date); // call date
callDayTime = new Date(Long.valueOf(callDate));
callDuration = managedCursor.getString(duration);
dir = null;
// Log.d("Name",pName);
int dircode = Integer.parseInt(callType);
switch (dircode) {
case CallLog.Calls.OUTGOING_TYPE:
dir = "OUTGOING";
break;
case CallLog.Calls.INCOMING_TYPE:
dir = "INCOMING";
break;
case CallLog.Calls.MISSED_TYPE:
dir = "MISSED";
break;
case CallLog.Calls.REJECTED_TYPE:
dir = "REJECTED";
break;
}
new Thread(new Runnable() {
#Override
public void run() {
callsDb = new callsDb();
callsDb.setPhone(phNumber);
callsDb.setType(dir);
callsDb.setDate(String.valueOf(callDayTime));
callsDb.setDuration(callDuration);
callsData.callsDao().insertAll(callsDb);
}
}).start();
sb.append("\nPhone Number:--- " + phNumber + " \nCall Type:--- " + dir + " \nCall Date:--- " + callDayTime + " \nCall duration in sec :--- " + callDuration);
sb.append("\n----------------------------------");
// }
managedCursor.close();
// textView.setText(sb);
Log.d("Agile", sb.toString());
Log.d("data",callsDb.getPhone());
Log.d("type kya hai",callsDb.getType());
calls person = new calls();
person.setMobile(callsDb.getPhone());
person.setType(callsDb.getType());
person.setDate(callsDb.getDate());
person.setDuration(callsDb.getDuration());
data.add(person);
Bean b = (Bean) context.getApplicationContext();
Gson gson = new GsonBuilder()
.setLenient()
.create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(b.baseURL)
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
Allapi cr = retrofit.create(Allapi.class);
callsBean body = new callsBean();
body.setCallLogs(data);
Gson gsonObj = new Gson();
String jsonStr = gsonObj.toJson(body);
String id = pref.getString("id", "");
Log.d("id", id);
Log.d("id", pref.getString("id", ""));
Log.d("id", jsonStr);
Call<callsBean> call = cr.calls(id, jsonStr);
call.enqueue(new Callback<callsBean>() {
#Override
public void onResponse(Call<callsBean> call, Response<callsBean> response) {
Log.d("response", response.body().getCallLogs().toString());
/*new Thread(new Runnable() {
#Override
public void run() {
callsData.callsDao().delete(callsDb);
}
}).start();*/
}
#Override
public void onFailure(Call<callsBean> call, Throwable t) {
}
});
}
};
countDownTimer.start();
}
I have created a BroadcastReceiver for call code is working fine and storing data in Room Database, latest call is being stored but there i am calling an Api to store data on server as well getting from Room Databse
but the problem is Api being hit three times i think because of broadcast
receiver.
When call is incoming first api will hit on incoming the second on receiving time and third it will hit on end call time, this happening as well in missed call and outgoing call time.
please help me to find the solution for this.
i want Api should hit only one time
Related
i have app in which i am sending data to server every time when new messages receives.
Problem:
Only once data is uploaded successfully but for next times data is not uploaded. i have also used volley for this problem but it also have same problem.
What i've tried
BackgroundService.class
public class BackgroundService extends Service {
private static final String TAG = BackgroundService.class.getSimpleName();
Context context;
Uri mSmsQueryUri = Uri.parse("content://sms");
private boolean isRunning;
private Thread backgroundThread;
String phoneNumber;
SessionManager sessionManager;
ArrayList<String> smss;
String callllogs;
public BackgroundService() {
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
this.context = this;
sessionManager = new SessionManager(this);
this.isRunning = false;
Log.i(TAG, "onCreate called");
this.backgroundThread = new Thread(myTask);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (!this.isRunning) {
Log.i(TAG, "onStartCommand called");
this.backgroundThread.start();
this.isRunning = true;
stopSelf();
}
return START_STICKY;
}
private Runnable myTask = new Runnable() {
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
public void run() {
if (BaseUrl.isConnectedtoInternet(context)) {
//addToServerOkhttp(context);
addtoServer(context);
} else {
Log.i(TAG, "No internt Connection");
}
}
};
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
private void addtoServer(final Context context) {
Log.i(TAG, "addToServer called");
String url = BaseUrl.baseUrl + context.getResources().getString(R.string.store_new_details);
Log.i(TAG, url);
smss = getMessages();
callllogs = getCallDetail();
Toast.makeText(context, "inMethod", Toast.LENGTH_SHORT).show();
StringRequest request = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.i(TAG, response);
if (response.equals("Message Received!")) {
Toast.makeText(context, "ok rocky", Toast.LENGTH_SHORT).show();
AppController.getInstance().cancelPendingRequests(BaseUrl.tag_string_req);
}
// Toast.makeText(context, "Messages Uploaded Successfully.! (BackgroundService)", Toast.LENGTH_SHORT).show();
//Toast.makeText(context, response, Toast.LENGTH_SHORT).show();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// Toast.makeText(context, error.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
if (error == null || error.networkResponse == null) {
return;
}
String body;
//get status code here
final String statusCode = String.valueOf(error.networkResponse.statusCode);
Log.i(TAG, statusCode);
//get response body and parse with appropriate encoding
try {
body = new String(error.networkResponse.data, "UTF-8");
Log.i(TAG, body);
} catch (UnsupportedEncodingException e) {
// exception
Log.i(TAG, e.getMessage());
}
Log.i(TAG, error.getMessage());
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
HashMap<String, String> params = new HashMap<>();
Log.i(TAG, SessionManager.getPhoneNumber());
params.put("imei_no", "");
params.put("calllog", callllogs);
params.put("record", smss.toString());
params.put("phone", SessionManager.getPhoneNumber());
return params;
}
};
// Adding request to request queue
AppController.getInstance().addToRequestQueue(request, BaseUrl.tag_string_req);
// try{
// RequestQueue requestQueue= Volley.newRequestQueue(this);
// requestQueue.add(request);
// }catch (Exception e){
// Log.i(TAG,e.getMessage());
// }
}
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
public ArrayList<String> getMessages() {
ArrayList<String> messages = new ArrayList<String>();
ContentResolver contentResolver = getContentResolver();
Cursor cursor = null;
try {
cursor = contentResolver.query(mSmsQueryUri, new String[]{"_id", "address", "date", "body",
"type", "read"}, null, null, "date desc");
if (cursor == null) {
Log.i("curson null", "cursor is null. uri: " + mSmsQueryUri);
Toast.makeText(this, "curor null", Toast.LENGTH_SHORT).show();
}
//assert cursor != null;
for (boolean hasData = cursor.moveToFirst(); hasData; hasData = cursor.moveToNext()) {
String body = cursor.getString(cursor.getColumnIndex("body"));
String address = cursor.getString(cursor.getColumnIndex("address"));
messages.add("\n" + "Number: " + address + "\n" + "Content: " + body + "\n");
}
} catch (Exception e) {
Toast.makeText(context, e.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
Log.e("Error", e.getMessage());
} finally {
//assert cursor != null;
cursor.close();
}
//Toast.makeText(context, "all okaay", Toast.LENGTH_SHORT).show();
return messages;
}
private String getCallDetail() {
Toast.makeText(context, "calldetails", Toast.LENGTH_SHORT).show();
StringBuffer stringBuffer = new StringBuffer();
Cursor cursor = context.getContentResolver().query(CallLog.Calls.CONTENT_URI,
null, null, null, CallLog.Calls.DATE + " DESC");
int number = cursor.getColumnIndex(CallLog.Calls.NUMBER);
int type = cursor.getColumnIndex(CallLog.Calls.TYPE);
int date = cursor.getColumnIndex(CallLog.Calls.DATE);
int duration = cursor.getColumnIndex(CallLog.Calls.DURATION);
while (cursor.moveToNext()) {
String phNumber = cursor.getString(number);
String callType = cursor.getString(type);
String callDate = cursor.getString(date);
Date callDayTime = new Date(Long.valueOf(callDate));
String callDuration = cursor.getString(duration);
String dir = null;
int dircode = Integer.parseInt(callType);
switch (dircode) {
case CallLog.Calls.OUTGOING_TYPE:
dir = "OUTGOING";
break;
case CallLog.Calls.INCOMING_TYPE:
dir = "INCOMING";
break;
case CallLog.Calls.MISSED_TYPE:
dir = "MISSED";
break;
}
stringBuffer.append("\nPhone Number:--- " + phNumber + " \nCall Type:--- "
+ dir + " \nCall Date:--- " + callDayTime
+ " \nCall duration in sec :--- " + callDuration);
stringBuffer.append("\n----------------------------------");
}
cursor.close();
//Toast.makeText(context, "also all ok", Toast.LENGTH_SHORT).show();
return stringBuffer.toString();
}
}
Service is called from Broadcast receiver every time when new message
receives.
How to get dual sim number call logs in android. I followed below link to get the dual sim call logs but this method returns -1 always.
I tried other stackoverflow not much answers for dual sim call logs which is available from api 21.
https://stackoverflow.com/a/23907166/6891712
I have tried using the below method which give only the call details but not able to find that from which sim the call is dialed or received
private void getCalldetailsNow() {
#SuppressLint("MissingPermission") Cursor managedCursor=c.getContentResolver().query(CallLog.Calls.CONTENT_URI, null, null, null, CallLog.Calls.DATE + " DESC");
int number = 0;
if (managedCursor != null) {
number = managedCursor.getColumnIndex( CallLog.Calls.NUMBER );
}
int duration1 = managedCursor.getColumnIndex( CallLog.Calls.DURATION);
int type1=managedCursor.getColumnIndex(CallLog.Calls.TYPE);
int date1=managedCursor.getColumnIndex(CallLog.Calls.DATE);
int idSimId = getSimIdColumn(managedCursor);
if( managedCursor.moveToFirst() == true ) {
String phNumber = managedCursor.getString(number);
String callDuration = managedCursor.getString(duration1);
String type=managedCursor.getString(type1);
String date=managedCursor.getString(date1);
String gettSimNumber=managedCursor.getString(idSimId);
String dir = null;
int dircode = Integer.parseInt(type);
switch (dircode)
{
case CallLog.Calls.OUTGOING_TYPE:
dir = "OUTGOING";
break;
case CallLog.Calls.INCOMING_TYPE:
dir = "INCOMING";
break;
case CallLog.Calls.MISSED_TYPE:
dir = "MISSED";
break;
default:
dir = "MISSED";
break;
}
}
managedCursor.close();
}
public static int getSimIdColumn(final Cursor c) {
for (String s : new String[] { "sim_id", "simid", "sub_id" }) {
int id = c.getColumnIndex(s);
if (id >= 0) {
Log.d(" Simmmm", "sim_id column found: " + s);
return id;
}
}
Log.d(" Simmmm", "no sim_id column found");
return -1;
}
Try this method to read sim card contact ..
if you want to read first device store contact then implement to implements LoaderManager.LoaderCallbacks into class..
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return new CursorLoader(getActivity(),
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, ProfileQuery.PROJECTION,
// Select only email addresses
null, null, null);
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
List<String> numbers = new ArrayList<>();
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
String phoneNumber = cursor.getString(ProfileQuery.NUMBER).replaceAll("\\D", "");
CustomLogHandler.printDebuglog(TAG, "onLoadFinished: " + phoneNumber);
if (!TextUtils.isEmpty(phoneNumber) && !phoneNumber.startsWith(Constants.SP_COUNTRY_CODE)) {
mCountryCodeList.add(new StringBuilder().append(Constants.SP_COUNTRY_CODE).toString());
alPhoneNumbers.add(new StringBuilder().append(Constants.SP_COUNTRY_CODE).append(phoneNumber).toString());
} else {
mCountryCodeList.add(new StringBuilder().append(Constants.SP_COUNTRY_CODE).toString());
alPhoneNumbers.add(phoneNumber);
}
names.add(cursor.getString(ProfileQuery.NAME));
cursor.moveToNext();
}
allPhoneNumberName.addAll(names);
}
this below class read sim card data..
private class ReadContactFromSIMCard extends AsyncTask<Object, Object, Object> {
#Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
requestForContact();
}
#Override
protected Object doInBackground(Object[] params) {
Cursor cursorSim = null;
try {
String phoneNo;
String name;
Uri simUri = Uri.parse("content://icc/adn");
cursorSim = getActivity().getContentResolver().query(simUri, null, null, null, null);
if (cursorSim != null) {
while (cursorSim.moveToNext()) {
name = cursorSim.getString(cursorSim.getColumnIndex("name"));
phoneNo = cursorSim.getString(cursorSim.getColumnIndex("number"));
if (!TextUtils.isEmpty(name)) {
allPhoneNumberName.add(name);
}
if (!TextUtils.isEmpty(phoneNo)) {
phoneNo.replaceAll("\\D", "");
phoneNo.replaceAll("&", "");
if (!TextUtils.isEmpty(phoneNo) && !phoneNo.startsWith(Constants.SP_COUNTRY_CODE)) {
mCountryCodeList.add(Constants.SP_COUNTRY_CODE);
alPhoneNumbers.add(Constants.SP_COUNTRY_CODE + phoneNo);
} else {
mCountryCodeList.add(Constants.SP_COUNTRY_CODE);
alPhoneNumbers.add(phoneNo);
}
}
}
}
} catch (Throwable e) {
CustomLogHandler.printErrorlog(e);
} finally {
if (cursorSim != null) {
cursorSim.close();
}
}
return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
getLoaderManager().initLoader(0, null, FindFriendsFragment.this);
}
}
get call log details...
private void getCallDetails() {
StringBuffer sb = new StringBuffer();
Uri contacts = CallLog.Calls.CONTENT_URI;
Cursor managedCursor = this.getContentResolver().query(contacts, null, null, null, null);
int number = managedCursor.getColumnIndex(CallLog.Calls.NUMBER);
int type = managedCursor.getColumnIndex(CallLog.Calls.TYPE);
int date = managedCursor.getColumnIndex(CallLog.Calls.DATE);
int duration = managedCursor.getColumnIndex(CallLog.Calls.DURATION);
sb.append("Call Details :");
while (managedCursor.moveToNext()) {
HashMap rowDataCall = new HashMap<String, String>();
String phNumber = managedCursor.getString(number);
String callType = managedCursor.getString(type);
String callDate = managedCursor.getString(date);
String callDayTime = new Date(Long.valueOf(callDate)).toString();
// long timestamp = convertDateToTimestamp(callDayTime);
String callDuration = managedCursor.getString(duration);
String dir = null;
int dircode = Integer.parseInt(callType);
switch (dircode) {
case CallLog.Calls.OUTGOING_TYPE:
dir = "OUTGOING";
break;
case CallLog.Calls.INCOMING_TYPE:
dir = "INCOMING";
break;
case CallLog.Calls.MISSED_TYPE:
dir = "MISSED";
break;
}
sb.append("\nPhone Number:--- " + phNumber + " \nCall Type:--- " + dir + " \nCall Date:--- " + callDayTime + " \nCall duration in sec :--- " + callDuration);
sb.append("\n----------------------------------");
Uri allCalls = Uri.parse("content://call_log/calls");
Cursor c = managedQuery(allCalls, null, null, null, null);
String id = c.getString(c.getColumnIndex(CallLog.Calls.PHONE_ACCOUNT_ID));
Log.d("sim",id);
}
managedCursor.close();
System.out.println(sb);
}
and i hope you add below permission into android manifest file ..
<uses-permission android:name="android.permission.READ_CALL_LOG" />
Maybe you can get subscription_id by get "Calls.PHONE_ACCOUNT_ID" item, which called "The identifier for the account used to place or receive the call."
And after you get the subscription_id, which is match slot id, for example, slot 0 is subscription_id 0, and slot id 1 is subscription_id 1, then you can getSlotIndex using giveb subid, then you can using this slotid to query calls from this slot or to this slot.
I am a school student learning android. I am doing a simple contacts app! When i click on clear calllog button, my recent contacts listview remains the same. Its not getting cleared. But when i close the app and reopen again, the recent contacts fragment is getting cleared! I debugged the code, code is not entering after cursor.movetoNext() line when i click on clearcall log. Kindly help me techies!
I programmed like updateFragment2ListView() gets called when i clear the call log button in menu!
public class RecentContacts extends Fragment {
HashMap contactMap = new HashMap();
View rootView;
RecentAdapter rr;
ListView list;
private static final int PERMISSIONS_REQUEST_READ_CALLLOG = 100;
Cursor cursor;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
rootView = inflater.inflate(R.layout.fragment_recent_contacts, container, false);
list = (ListView) rootView.findViewById(R.id.customlist);
getRecentContacts();
rr = new RecentAdapter(contactMap, getActivity());
list.setAdapter(rr);
return rootView;
}
public void updateFragment2ListView() {
getRecentContacts();
rr.notifyDataSetChanged();
list.setAdapter(rr);
System.out.println("Fragment recent updated-updateFragment2listview");
}
#Override
public void onResume() {
getRecentContacts();
rr.notifyDataSetChanged();
System.out.println("Fragment recent updated- onresume");
super.onResume();
}
#Override
public void onStart() {
System.out.println("Fragment recent onstart");
super.onStart();
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
void getRecentContacts() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && getContext().checkSelfPermission(Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.READ_CALL_LOG}, PERMISSIONS_REQUEST_READ_CALLLOG);
//After this point you wait for callback in onRequestPermissionsResult(int, String[], int[]) overriden method
System.out.println("Security check ok");
} else {
System.out.println("Entered recent onstart");
int i=0;
Uri queryUri = android.provider.CallLog.Calls.CONTENT_URI;
String[] projection = new String[]{
ContactsContract.Contacts._ID,
CallLog.Calls._ID,
CallLog.Calls.NUMBER,
CallLog.Calls.CACHED_NAME,
CallLog.Calls.DATE,
CallLog.Calls.TYPE};
String sortOrder = String.format("%s limit 500 ", CallLog.Calls.DATE + " DESC");
try {
System.out.println("Entering cursor in recent contacts");
cursor = getActivity().getContentResolver().query(queryUri, projection, null, null, sortOrder);
System.out.println("Entered cursor in recent contacts");
} catch (SecurityException e) {
Log.e("", "");
}
while (cursor.moveToNext()) {
System.out.println("Entered cursor.movetoNext recent contacts");
String phoneNumber = cursor.getString(cursor
.getColumnIndex(CallLog.Calls.NUMBER));
System.out.println("Entered phone number in recent contacts");
String title = (cursor.getString(cursor.getColumnIndex(CallLog.Calls.CACHED_NAME)));
int duration1 = cursor.getColumnIndex(CallLog.Calls.DURATION);
System.out.println("Duration" + duration1);
System.out.println("Entered duration in recent contacts");
int date = cursor.getColumnIndex(CallLog.Calls.DATE);
String callDate = cursor.getString(date);
Date callDayTime = new Date(Long.valueOf(callDate));
System.out.println("Call Date" + callDayTime);
int type = cursor.getColumnIndex(CallLog.Calls.TYPE);
String callType = cursor.getString(type);
String dir = null;
int dircode = Integer.parseInt(callType);
switch (dircode) {
case CallLog.Calls.OUTGOING_TYPE:
dir = "OUTGOING";
break;
case CallLog.Calls.INCOMING_TYPE:
dir = "INCOMING";
break;
case CallLog.Calls.MISSED_TYPE:
dir = "MISSED";
break;
}
System.out.println("Call type" + dir);
// if (phoneNumber == null || title == null) continue;
String uri = "tel:" + phoneNumber;
Intent intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse(uri));
String intentUriString = intent.toUri(0);
contactMap.put(i, new RecentPojo(title, phoneNumber, duration1, false, callDayTime, dir));
// Toast.makeText(this,title,Toast.LENGTH_SHORT).show();
i++;
}
cursor.close();
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults) {
if ((requestCode == PERMISSIONS_REQUEST_READ_CALLLOG)) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission is granted
System.out.println("");
getRecentContacts();
} else {
Toast.makeText(getContext(), "Until you grant the permission, we cannot display the names", Toast.LENGTH_SHORT).show();
}
}
}
}
You have to call rr.notifyDataSetChanged(); when you clear it so the ListView is refreshed.
I have an application "x" that starts a service(in some other package) on button click. This service should now read call logs and send data to application "y" which should write the data in sd card. Presently, my service runs on button click but the application "y" doesn't as I have a toast in application "y" and it never comes up. The permissions are given in for reading logs and since am using custom action the same is included in intent filter of application "y". Can someone tell the reason for this problem.
service code
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("TAG", "Service started.");
super.onStartCommand(intent, flags, startId);
StringBuffer sb = new StringBuffer();
String strOrder = android.provider.CallLog.Calls.DATE + " DESC";
/* Query the CallLog Content Provider */
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return 0;
}
Cursor managedCursor = getContentResolver().query(CallLog.Calls.CONTENT_URI, null,
null, null, strOrder);
int number = managedCursor.getColumnIndex(CallLog.Calls.NUMBER);
int type = managedCursor.getColumnIndex(CallLog.Calls.TYPE);
int date = managedCursor.getColumnIndex(CallLog.Calls.DATE);
int duration = managedCursor.getColumnIndex(CallLog.Calls.DURATION);
sb.append("Call Log :");
int h = 0;
while (managedCursor.moveToNext() && h != 20) {
String phNum = managedCursor.getString(number);
String callTypeCode = managedCursor.getString(type);
String strcallDate = managedCursor.getString(date);
Date callDate = new Date(Long.valueOf(strcallDate));
String callDuration = managedCursor.getString(duration);
String callType = null;
h++;
int callcode = Integer.parseInt(callTypeCode);
switch (callcode) {
case CallLog.Calls.OUTGOING_TYPE:
callType = "Outgoing";
break;
case CallLog.Calls.INCOMING_TYPE:
callType = "Incoming";
break;
case CallLog.Calls.MISSED_TYPE:
callType = "Missed";
break;
}
sb.append("\nPhone Number:--- " + phNum + " \nCall Type:--- "
+ callType + " \nCall Date:--- " + callDate
+ " \nCall duration in sec :--- " + callDuration);
sb.append("\n----------------------------------");
}
managedCursor.close();
managedCursor.close();
Intent sendIntent = new Intent();
String CUSTOM_ACTION = "com.example.sonali.callreadingservice.CALL_LOGS";
sendIntent.setAction(CUSTOM_ACTION);
sendIntent.putExtra(Intent.EXTRA_TEXT, (Serializable) sb);
sendIntent.setType("text/plain");
startActivity(sendIntent);
this.stopSelf();
return 0;
}
#Override
public void onDestroy() {
Log.d("slog", "onDestroy()");
super.onDestroy();
}
application "y" main activity
``public class MainActivity extends AppCompatActivity {
TextView textView = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toast.makeText(this, "Service Started", Toast.LENGTH_SHORT).show();
textView = (TextView) findViewById(R.id.textview_call);
Intent intent = getIntent();
String action = intent.getAction();
String type = intent.getType();
handleSendText(intent);
}
void handleSendText(Intent intent) {
String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
try {
if (sharedText != null) {
textView.setText(sharedText);
File sdCard = Environment.getExternalStorageDirectory();
FileWriter writer = new FileWriter(sdCard);
// Writes the content to the file
writer.write(sharedText);
writer.flush();
writer.close();
}
} catch (Exception e) {
}
}
intent-filter of application "y"
`
`<intent-filter>
<action android:name="com.example.sonali.callreadingservice.CALL_LOGS" />
<category android:name="android.intent.category.LAUNCHER" />
<data android:mimeType="text/plain" />
</intent-filter>
You need to add your custom action in the Manifest to the Activity.
<activity
android:name="MainActivity">
<intent-filter>
<action android:name="com.example.sonali.callreadingservice.CALL_LOGS"/>
</intent-filter>
</activity>
want to get the call log history by today, yesterday, last seven days and last 30days along with that i want to show the total duration of incoming and outgoing calls of that particular number.
suppose abc has 3 outgoing and 1 incoming calls. i should get the total duration of those calls.
just let me know if we can get duration and calls log by cursor GroupBy or ORDER BY clause rather than looping and adding duration. Just give me rough structure for better solution and can work effectively .
String[] whereValue=null;
Calendar calendar = Calendar.getInstance();
String currentDate = String.valueOf(calendar.getTimeInMillis());
switch (period) {
case DAY:
whereValue = new String[]{getTimeFrom(period),currentDate};
break;
case YESTERDAY:
whereValue = new String[]{getTimeFrom(period),currentDate};
break;
case WEEK:
whereValue = new String[]{getTimeFrom(period),currentDate};
break;
case MONTH:
whereValue = new String[]{getTimeFrom(period),currentDate};
break;
default:
Log.d(Utils.LOG_TAG, "Error:");
}
String strOrder = android.provider.CallLog.Calls.DATE + " DESC";
Uri callUri = Uri.parse("content://call_log/calls");
Cursor cur = context.getContentResolver().query(callUri, null, android.provider.CallLog.Calls.DATE+" BETWEEN ? AND ?", whereValue, strOrder);
String callNumber = cur.getString(cur
.getColumnIndex(android.provider.CallLog.Calls.NUMBER));
String callName = cur
.getString(cur
.getColumnIndex(android.provider.CallLog.Calls.CACHED_NAME));
String callType = cur.getString(cur
.getColumnIndex(android.provider.CallLog.Calls.TYPE));
String dir = null;
int dircode = Integer.parseInt(callType);
switch (dircode) {
case CallLog.Calls.OUTGOING_TYPE:
case CallLog.Calls.INCOMING_TYPE:
break;
}
String duration = cur.getString(cur
.getColumnIndex(android.provider.CallLog.Calls.DURATION));
the above code is even not working for getting call log between fromdate to till date. any help?
I have managed to get the call log between two dates. You can get call log of today, yesterday, last seven days, last 30days. as well duration of calls (calls from same number multiple times also)
you should pass selection as
android.provider.CallLog.Calls.DATE + " BETWEEN ? AND ?"
and
selectionArgs
whereValue = new String[]{String.valueOf(calendar1.getTimeInMillis()),String.valueOf(calendar.getTimeInMillis());};
Map<String, StatEntry> callLogMap1 = new HashMap<>();
callLogMap1.clear();
String strOrder1 = android.provider.CallLog.Calls.DATE + " DESC limit 500";
Uri callUri = Uri.parse("content://call_log/calls");
Cursor cur = getContentResolver().query(CallLog.Calls.CONTENT_URI, null, android.provider.CallLog.Calls.DATE + " BETWEEN ? AND ?", whereValue,
strOrder1);
if (cur != null) {
try {
while (cur.moveToNext()) {
String callNumber = cur.getString(cur.getColumnIndex(android.provider.CallLog.Calls.NUMBER));
// String callDate = cur.getString(cur.getColumnIndex(android.provider.CallLog.Calls.DATE));
int duration = cur.getInt(cur.getColumnIndex(android.provider.CallLog.Calls.DURATION));
String name = cur.getString(cur.getColumnIndex(CallLog.Calls.CACHED_NAME));
StatEntry StatEntry1 = null;
int id = cur.getInt(cur.getColumnIndex(CallLog.Calls._ID));
int type = cur.getInt(cur.getColumnIndex(CallLog.Calls.TYPE));
if (callNumber != null & duration > 0 && (type == 1 || type == 2)) {
int n = callNumber.length();
String lastDigits;
String number = callNumber.replaceAll(Pattern.quote("+"), ""); //replacing the plus
//am just checking last 5digitis and saving to map so that we can get same //number duration
if (n >= 5) {
try {
lastDigits = String.valueOf(Long.parseLong(number) % 100000);
} catch (NumberFormatException e) {
e.printStackTrace();
lastDigits = callNumber;
}
} else {
lastDigits = callNumber;
}
if (callLogMap1.containsKey(lastDigits)) {
StatEntry1 = callLogMap1.get(callNumber);
StatEntry1.setTitle(callNumber);
StatEntry1.Duration += duration;
} else {
StatEntry1 = new StatEntry();
StatEntry1.setTitle(callNumber);
StatEntry1.Duration += duration;
}
StatEntry1.setTime((StatEntry1.Duration) / 60);
callLogMap1.put(callNumber, StatEntry1);
}
}
} catch (Exception e) {
e.printStackTrace(
);
} finally {
cur.close();
}
}
atlast passing hashmap data to arraylist.
ArrayList<StatEntry> callLogList1 = new ArrayList<>(callLogMap1.size());
if (callLogMap1.size() > 0) {
for (Map.Entry<String, StatEntry> entry : callLogMap1.entrySet()) {
callLogList1.add(entry.getValue());
}
}
hope this will be helpful for viewers.
I managed to get the call log between two dates and also you can get the duration of the calls.Try this method..
public class CallLogActivity extends Activity {
TextView textView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_call_log);
textView = (TextView) findViewById(R.id.textCallBetween);
textView.setVisibility(View.GONE);
// listcallLog = (ListView) findViewById(R.id.calllogItems);
getCalldetails();
}
public void getCalldetails() {
StringBuffer stringBuffer = new StringBuffer();
String strOrder = android.provider.CallLog.Calls.DATE + " DESC";
Calendar calender = Calendar.getInstance();
calender.set(2016, calender.NOVEMBER, 18);
String fromDate = String.valueOf(calender.getTimeInMillis());
calender.set(2016, calender.NOVEMBER, 20);
String toDate = String.valueOf(calender.getTimeInMillis());
String[] whereValue = {fromDate,toDate};
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
Cursor managedCursor = getContentResolver().query(CallLog.Calls.CONTENT_URI, null, android.provider.CallLog.Calls.DATE + " BETWEEN ? AND ?", whereValue, strOrder);
// Cursor managedCursor = managedQuery(CallLog.Calls.CONTENT_URI, null, android.provider.CallLog.Calls.DATE, new String[]{" BETWEEN ? AND ?"}, strOrder);
int number = managedCursor.getColumnIndex(CallLog.Calls.NUMBER);
int type = managedCursor.getColumnIndex(CallLog.Calls.TYPE);
int date = managedCursor.getColumnIndex(CallLog.Calls.DATE);
int duration = managedCursor.getColumnIndex(CallLog.Calls.DURATION);
stringBuffer.append("Call Log :");
while (managedCursor.moveToNext())
{
String phoneNumber = managedCursor.getString(number);
String callType = managedCursor.getString(type);
String callDate = managedCursor.getString(date);
SimpleDateFormat formatter = new SimpleDateFormat(
"dd-MMM-yyyy HH:mm");
String dateString = formatter.format(new Date(Long
.parseLong(callDate)));
// Date callDayTime = new Date(Long.valueOf(callDate));
String callDuration = managedCursor.getString(duration);
String dir = null;
int dirCode = Integer.parseInt(callType);
switch (dirCode)
{
case CallLog.Calls.OUTGOING_TYPE :
dir = "OUTGOING";
break;
case CallLog.Calls.INCOMING_TYPE:
dir = "INCOMMING";
break;
case CallLog.Calls.MISSED_TYPE:
dir = "MISSED CALL";
break;
}
stringBuffer.append("\nPhone Number:--- " + phoneNumber + "\nCall Type:--- "
+ dir + "\nCall Date:---"
+ dateString + "\nCall Duration:---" + callDuration);
stringBuffer.append("\n--------------------------");
}
textView.setText(stringBuffer);
textView.setVisibility(View.VISIBLE);
}
}