Mehul Kanzariya
Mehul Kanzariya

Reputation: 1348

Get last call details from Call Log

I am using below code to get last call details from call log.

public static CallDetails getLastCallDetails(Context context) {

    CallDetails callDetails = new CallDetails();

    Uri contacts = CallLog.Calls.CONTENT_URI;
    try {

        Cursor managedCursor = context.getContentResolver().query(contacts, null, null, null, android.provider.CallLog.Calls.DATE + " DESC limit 1;");

        int number = managedCursor.getColumnIndex(CallLog.Calls.NUMBER);
        int duration = managedCursor.getColumnIndex(CallLog.Calls.DURATION);
        int date = managedCursor.getColumnIndex(CallLog.Calls.DATE);
        int incomingtype = managedCursor.getColumnIndex(String.valueOf(CallLog.Calls.INCOMING_TYPE));


        while (managedCursor.moveToNext()) {
            String callType;
            String phNumber = managedCursor.getString(number);
            String callerName = getContactName(context, phNumber);
            if(incomingtype == -1){
                callType = "incoming";
            }
            else {
                callType = "outgoing";
            }
            String callDate = managedCursor.getString(date);
            String callDayTime = new      Date(Long.valueOf(callDate)).toString();

            String callDuration = managedCursor.getString(duration);

            callDetails.setCallerName(callerName);
            callDetails.setCallerNumber(phNumber);
            callDetails.setCallDuration(callDuration);
            callDetails.setCallType(callType);
            callDetails.setCallTimeStamp(callDayTime);

        }
        managedCursor.close();

    } catch (SecurityException e) {
        Log.e("Security Exception", "User denied call log permission");

    }

    return callDetails;

}

The problem is that it returns the last second call and not the last call. I need to return the last call. I googled it but I am not able to get the perfect solution. Please help. Thanks in advance.

Upvotes: 6

Views: 10856

Answers (2)

Anand Nishad
Anand Nishad

Reputation: 126

    I faced the same issue with my code-
    check this situation - suppose I call client 1 and the duration is 50 seconds and it fetched correctly now I call client 2 its duration is 2 minutes which also fetched successfully now when I again call client 1 he doesn't pick up the call and duration is fetched here wrong 50 seconds which is the last second call duration and not the last call which is 0 - 
    
    
     @SuppressLint("Range")
        private suspend fun lastCallDetail(): String {
            val delayDuration = if (Build.VERSION.SDK_INT > Build.VERSION_CODES.TIRAMISU) 3000L else 2000L
            delay(delayDuration)
            var callDuration = "0"
            try {
                val cur: Cursor? = contentResolver.query(
                    CallLog.Calls.CONTENT_URI,
                    null, null, null, CallLog.Calls.DATE + " DESC limit 1;"
                )
                if (cur != null) {
                    while (cur.moveToNext()) {
                        callDuration = cur.getString(cur.getColumnIndex(CallLog.Calls.DURATION))
                                break
    
                    }
                    cur.close()
                }
            } catch (e : Exception) {
                e.printStackTrace()
            }
            return callDuration
        }
    
    
    
      private suspend fun lastCallIncoming(): String {
             delay(3000)
             var callDuration = "00:00:00"
             try {
                 val cur = applicationContext.contentResolver.query(
                     CallLog.Calls.CONTENT_URI,
                     null,
                     null,
                     null,
                     CallLog.Calls.DATE + " DESC"
                 )
                 val duration = cur!!.getColumnIndex(CallLog.Calls.DURATION)
                 while (cur.moveToNext()) {
                     callDuration = cur.getString(duration)
                     Log.d("callTracking", callDuration)
                     break
                 }
                 cur.close()
                 val timeSec = callDuration.toInt() // Json output
                 callDuration = timeSec.toString() //hh:mm:ss formatted string
                 Log.d("callTracking", callDuration)
             } catch (e: java.lang.Exception) {
                 e.printStackTrace()
             }
             return callDuration
         }
    
    
      private fun secToTime(second: Int): String {
            var sec = second
            val hours = sec / 3600
            val minutes = sec % 3600/ 60
            sec %= 60
            return String.format("%02d:%02d:%02d", hours, minutes, sec)
        }

I also try this solution that returns the last-second call duration and not the last call but in some devices, it works fine where the devices have ToptoBottom call records. -

    @SuppressLint("Range")
      private suspend fun lastCallDetail(): String {
          val delayDuration = if (Build.VERSION.SDK_INT > Build.VERSION_CODES.TIRAMISU) 3000L else 2000L
          delay(delayDuration)
          var callDuration = "0"
          try {
              val callLogCursor: Cursor? = contentResolver.query(
                  CallLog.Calls.CONTENT_URI,
                  null, null, null, CallLog.Calls.DATE + " DESC limit 1;"
              )

              if (callLogCursor != null) {
                  // Check the order of the call logs
                  val isOrderTopToBottom = determineCallLogOrder(callLogCursor)

                  // Move accoreding to the determined order
                  callLogCursor.moveToFirst()
                  val durationIndex = callLogCursor.getColumnIndex(CallLog.Calls.DURATION)
                  if (durationIndex != -1) {
                      if (isOrderTopToBottom) {
                          callDuration = callLogCursor.getString(durationIndex)
                      } else {
                          callLogCursor.moveToLast()
                          callDuration = callLogCursor.getString(durationIndex)
                      }
                  }
                  callLogCursor.close()
              }
          } catch (e: Exception) {
              e.printStackTrace()
          }
          return callDuration
      }

  @SuppressLint("Range")
      private suspend fun lastCallIncoming(): String {
          delay(3000)
          var callDuration = "00:00:00"
          try {
              val callLogCursor = applicationContext.contentResolver.query(
                  CallLog.Calls.CONTENT_URI,
                  null,
                  null,
                  null,
                  CallLog.Calls.DATE + " DESC"
              )

              if (callLogCursor != null) {
                  // Check the order of the call logs
                  val isOrderTopToBottom = determineCallLogOrder(callLogCursor)
                  callLogCursor.moveToFirst()
                  val durationIndex = callLogCursor.getColumnIndex(CallLog.Calls.DURATION)

                  // Move according to the determined order
                  if (durationIndex != -1) {
                      if (isOrderTopToBottom) {
                          callDuration = callLogCursor.getString(durationIndex)
                      } else {
                          callLogCursor.moveToLast()
                          callDuration = callLogCursor.getString(durationIndex)
                      }

                      val timeSec = callDuration.toInt()
                      callDuration = secToTime(timeSec)
                      Log.d("callTracking", callDuration)
                  }
                  callLogCursor.close()
              }
          } catch (e: Exception) {
              e.printStackTrace()
          }
          return callDuration
      }



 private fun determineCallLogOrder(cursor: Cursor): Boolean {
         var isOrderTopToBottom = true
         if (cursor.moveToFirst()) {
             val dateColumnIndex = cursor.getColumnIndex(CallLog.Calls.DATE)
             if (dateColumnIndex != -1) {
                 val firstTimestamp = cursor.getLong(dateColumnIndex)
                 if (cursor.moveToNext()) {
                     val secondTimestamp = cursor.getLong(dateColumnIndex)
                     isOrderTopToBottom = firstTimestamp > secondTimestamp
                 }
             }
         }
         return isOrderTopToBottom
     }



   private fun secToTime(second: Int): String {
        var sec = second
        val hours = sec / 3600
        val minutes = sec % 3600/ 60
        sec %= 60
        return String.format("%02d:%02d:%02d", hours, minutes, sec)
    }

Upvotes: 0

ak sacha
ak sacha

Reputation: 2179

Add this line managedCursor.moveToFirst()

 public static CallDetails getLastCallDetails(Context context) {

        CallDetails callDetails = new CallDetails();

        Uri contacts = CallLog.Calls.CONTENT_URI;
        try {

            Cursor managedCursor = context.getContentResolver().query(contacts, null, null, null, android.provider.CallLog.Calls.DATE + " DESC limit 1;");

            int number = managedCursor.getColumnIndex(CallLog.Calls.NUMBER);
            int duration = managedCursor.getColumnIndex(CallLog.Calls.DURATION);
            int date = managedCursor.getColumnIndex(CallLog.Calls.DATE);
            int incomingtype = managedCursor.getColumnIndex(String.valueOf(CallLog.Calls.INCOMING_TYPE));

           if(managedCursor.moveToFirst()){ // added line

            while (managedCursor.moveToNext()) { 
                String callType;
                String phNumber = managedCursor.getString(number);
                String callerName = getContactName(context, phNumber);
                if(incomingtype == -1){
                    callType = "incoming";
                }
                else {
                    callType = "outgoing";
                }
                String callDate = managedCursor.getString(date);
                String callDayTime = new      Date(Long.valueOf(callDate)).toString();

                String callDuration = managedCursor.getString(duration);

                callDetails.setCallerName(callerName);
                callDetails.setCallerNumber(phNumber);
                callDetails.setCallDuration(callDuration);
                callDetails.setCallType(callType);
                callDetails.setCallTimeStamp(callDayTime);

          }
        }
            managedCursor.close();

        } catch (SecurityException e) {
            Log.e("Security Exception", "User denied call log permission");

        }

        return callDetails;

    }

Upvotes: 7

Related Questions