ฉันจะเข้าถึงบันทึกการโทรสำหรับ Android ได้อย่างไร


97

ฉันต้องการรับบันทึกการโทร ตัวอย่างเช่นจำนวนการโทรของผู้ใช้จำนวนนาทีที่โทรเป็นต้น

ฉันจะบรรลุสิ่งนี้ใน Android ได้อย่างไร


อาจเป็นโซลูชันสำหรับ U developer.android.com/reference/android/database/…
Nikunj Patel

ฉันจำได้ว่ามันเป็นตัวแก้ไขเนื้อหา แต่ฉันไม่รู้ว่าจะเริ่มต้นอย่างไร
3cross

คำตอบ:


70

นี่คือการเข้าถึงประวัติการโทร:

สำหรับ Jellybean (4.1) คุณต้องได้รับอนุญาตดังต่อไปนี้:
<uses-permission android:name="android.permission.READ_CALL_LOG" />

รหัส:

 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.

11
อย่าลืมเปิดใช้การอนุญาตนี้: <ใช้ - อนุญาต android: name = "android.permission.READ_CALL_LOG" /> นี่คือวิธีรับบันทึกการโทร:
Aziz

ฉันไม่รู้ แต่ในทางทฤษฎีฉันสามารถพูดได้ว่าข้อความทั้งหมดถูกเก็บไว้ในฐานข้อมูลเดียวกัน ใช่มันสามารถเข้าถึงข้อความทั้งหมดของอุปกรณ์โดยไม่คำนึงถึงซิมคู่หรือซิมเดียว ตรวจสอบรหัสนี้และแจ้งให้เราทราบหากไม่ทำงานกับซิมคู่ ฉันจะทำการวิจัยและพัฒนาและให้รหัสแก่คุณ
Abhinav Singh Maurya

1
ได้รับชื่อจะคืนค่าว่างเสมอระวัง
vuhung3990

@Abhinav Singh Maurya คุณสามารถช่วยฉันรับบันทึกการโทร photo_uri จากบันทึกการโทรเพราะฉันไม่สามารถรับ photo_uri จากบันทึกการโทร
Sagar

1
ManagedQuery () เลิกใช้แล้วให้ใช้สิ่งนี้แทน Cursor cursor = context.getContentResolver (). query (CallLog.Calls.CONTENT_URI, null, null, null, CallLog.Calls.DATE + "DESC");
Sai Gopi Me

67

เป็นวิธีที่ใช้ในการรับบันทึกการโทร เพียงใส่วิธีนี้ในชั้นเรียนของคุณและรับรายการบันทึกการโทร

ตรวจสอบสิ่งนี้

private String getCallDetails() {

        StringBuffer sb = new StringBuffer();
        Cursor managedCursor = managedQuery(CallLog.Calls.CONTENT_URI, 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()) {
            String phNumber = managedCursor.getString(number);
            String callType = managedCursor.getString(type);
            String callDate = managedCursor.getString(date);
            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 = "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----------------------------------");
        }
        managedCursor.close();
        return sb.toString();

    }

ผลลัพธ์มีลักษณะ

ป้อนคำอธิบายภาพที่นี่


ฉันได้รับข้อผิดพลาดที่agedQuery (CallLog.Calls.CONTENT_URI, null, null, null, null);
Sunil Parmar

5
ฉันใช้ contentResolver.query (CallLog.Calls.CONTENT_URI, null, null, null, null);
Sunil Parmar

@Dwivedi Ji - มันเป็นโพสต์เก่าไปหน่อย - วิธีการของคุณใช้ได้ผล แต่ใช้เวลาอย่างน้อย 10 วินาทีในการโหลดบันทึกการโทรทั้งหมด
TheDevMan

@TheDevMan ขออภัยในความไม่สะดวกใช่คุณพูดถูกฉันจะอัปเดตคำตอบของฉันเร็ว ๆ นี้
Dwivedi Ji

ขอบคุณฉันจะรอการตอบกลับของคุณ!
TheDevMan

48

ใช้วิธีนี้จากทุกที่ที่มีบริบท

private static String getCallDetails(Context context) {
    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();
    return stringBuffer.toString();
}

7
เนื่องจากตอนนี้ ManagedQuery เลิกใช้งานแล้วดังนั้นคำตอบนี้จึงมีความเกี่ยวข้องมากที่สุด
abhi

16

โพสต์นี้เก่าไปหน่อย แต่นี่เป็นอีกวิธีง่ายๆในการรับข้อมูลที่เกี่ยวข้องกับCallผู้ให้บริการเนื้อหาบันทึกใน Android:

ใช้ lib นี้: https://github.com/EverythingMe/easy-content-providers

รับทุกสาย:

CallsProvider callsProvider = new CallsProvider(context);
List<Call> calls = callsProvider.getCalls().getList();

การโทรแต่ละครั้งมีฟิลด์ทั้งหมดดังนั้นคุณจะได้รับข้อมูลที่คุณต้องการ:
callDate, ระยะเวลา, หมายเลข, ประเภท (INCOMING, OUTGOING, MISSED), isRead, ...

มันทำงานร่วมกับListหรือCursorและมีแอพตัวอย่างเพื่อดูว่ามันมีลักษณะและการทำงานอย่างไร

ในความเป็นจริงมีการสนับสนุนสำหรับผู้ให้บริการเนื้อหา Android ทั้งหมดเช่นรายชื่อติดต่อ SMS ปฏิทิน ... เอกสารฉบับเต็มพร้อมตัวเลือกทั้งหมด: https://github.com/EverythingMe/easy-content-providers/wiki/Android-providers

หวังว่ามันจะช่วยได้ :)


เฮ้ฉันตรวจสอบโซลูชันของคุณแล้วก็ดี ปัญหาเดียวที่ฉันพบคือจะเพิ่มการพึ่งพาในโปรเจ็กต์คราสของฉันได้อย่างไร?
Aradhna

@aradhna ไลบรารีใช้ gradle และสร้างจาก Android Studio ฉันคิดว่าคุณจะต้องแก้ไขเล็กน้อยเพื่อให้มันทำงานบน Eclipse
sromku

9

ในโครงการของฉันฉันได้รับข้อผิดพลาดอุปกรณ์ htc int ตอนนี้รหัสนี้เป็นสากล ฉันคิดว่านี่เป็นความช่วยเหลือสำหรับคุณ

    public class CustomContentObserver extends ContentObserver {        
    public CustomContentObserver(Handler handler) {
        super(handler);
        System.out.println("Content obser");
    }     

    public void onChange(boolean selfChange) {
         super.onChange(selfChange);
         String lastCallnumber;

         currentDate = sdfcur.format(calender.getTime());
         System.out.println("Content obser onChange()");
         Log.d("PhoneService", "custom StringsContentObserver.onChange( " + selfChange + ")");
        //if(!callFlag){                   
         String[] projection = new String[]{CallLog.Calls.NUMBER,
                    CallLog.Calls.TYPE,
                    CallLog.Calls.DURATION,
                    CallLog.Calls.CACHED_NAME,
                    CallLog.Calls._ID};

            Cursor c;   
            c=mContext.getContentResolver().query(CallLog.Calls.CONTENT_URI, projection, null, null, CallLog.Calls._ID + " DESC");
            if(c.getCount()!=0){
                c.moveToFirst();
                 lastCallnumber = c.getString(0);
                 String type=c.getString(1);
                 String duration=c.getString(2);
                 String name=c.getString(3);
                 String id=c.getString(4);
                 System.out.println("CALLLLing:"+lastCallnumber+"Type:"+type);

                 Database db=new Database(mContext);
                 Cursor cur =db.getFirstRecord(lastCallnumber);
                 final String endCall=lastCallnumber;
                 //checking incoming/outgoing call
                 if(type.equals("3")){
                    //missed call
                    }else if(type.equals("1")){
                    //incoming call

                 }else if(type.equals("2")){
                    //outgoing call
                 }                  

            }
            c.close();
    }

}

3

หากต้องการรับประวัติการโทรเข้าขาออกและสายที่ไม่ได้รับหวังว่ารหัสนี้จะช่วยคุณได้ :)

เรียกรหัสนี้บนเธรดพื้นหลังของคุณ

StringBuffer sb = new StringBuffer();

String[] projection = new String[] {
    CallLog.Calls.CACHED_NAME,
    CallLog.Calls.NUMBER,
    CallLog.Calls.TYPE,
    CallLog.Calls.DATE,
    CallLog.Calls.DURATION
};

sb.append("Call Details :");

// String strOrder = android.provider.CallLog.Calls.DATE + " DESC";

Cursor managedCursor =  getApplicationContext().getContentResolver().query(CallLog.Calls.CONTENT_URI, projection, null, null, null);
while (managedCursor.moveToNext()) {
    String name = managedCursor.getString(0); //name
    String number = managedCursor.getString(1); // number
    String type = managedCursor.getString(2); // type 
    String date = managedCursor.getString(3); // time 
    @SuppressLint("SimpleDateFormat") 
    SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm");
    String dateString = formatter.format(new Date(Long.parseLong(date)));

    String duration = managedCursor.getString(4); // duration

    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;
    }

sb.append("\nPhone Name :-- "+name+"  Number:--- " + number + " \nCall Type:--- " + dir + " \nCall Date:--- " + dateString + " \nCall duration in sec :--- " + duration);
sb.append("\n----------------------------------");

2

หากต้องการรับเฉพาะประวัติการโทรเข้ารหัสด้านล่างจะช่วยคุณได้ :)

private void getCallDetailsAgil() {

    StringBuffer sb = new StringBuffer();
    Cursor managedCursor = managedQuery(CallLog.Calls.CONTENT_URI, 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()) {
        String phNumber = managedCursor.getString(number);
        String callType = managedCursor.getString(type);
        String callDate = managedCursor.getString(date);
        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 = "INCOMING";
                sb.append("\nPhone Number:--- " + phNumber + " \nCall Type:--- " + dir + " \nCall Date:--- " + callDayTime + " \nCall duration in sec :--- " + callDuration);
                sb.append("\n----------------------------------");
                miss_cal.setText(sb);
                break;

            case CallLog.Calls.MISSED_TYPE:
                dir = "MISSED";
                break;
        }
    }

    managedCursor.close();
} 

1

ใช้รหัสด้านล่าง:

private void getCallDeatils() {
    StringBuffer stringBuffer = new StringBuffer();
    Cursor managedCursor = getActivity().managedQuery(CallLog.Calls.CONTENT_URI, 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);
    stringBuffer.append("Call Deatils");
    while (managedCursor.moveToNext()) {
        String phNumber = managedCursor.getString(number);
        String callType = managedCursor.getString(type);
        String callDate = managedCursor.getString(date);
        Date callDayTime = new Date(Long.valueOf(callDate));
        DateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
        String reportDate = df.format(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;

        }
        stringBuffer.append("\nPhone Number:--- " + phNumber + " \nCall Type:--- " + dir + " \nCall Date:--- " +callDate + " \nCall duration in sec :--- " + callDuration);
        stringBuffer.append("\n----------------------------------");

        logs.add(new LogClass(phNumber,dir,reportDate,callDuration));




    }

0

ถ้าเราใช้ Kotlin มันจะสั้นกว่า ตัวอย่างคลาสที่ตอบสนองสำหรับบันทึกการโทร:

import android.content.Context
import android.database.Cursor
import android.provider.CallLog.Calls.*

class CallsLoader {

    fun getCallLogs(context: Context): List<List<String?>> {
        val c = context.applicationContext
        val projection = arrayOf(CACHED_NAME, NUMBER, TYPE, DATE, DURATION)

        val cursor = c.contentResolver.query(
             CONTENT_URI,
             projection,
             null,
             null,
             null,
             null
          )

         return cursorToMatrix(cursor)
     }

    private fun cursorToMatrix(cursor: Cursor?): List<List<String?>> {
        val matrix = mutableListOf<List<String?>>()
        cursor?.use {
             while (it.moveToNext()) {
                 val list = listOf(
                    it.getStringFromColumn(CACHED_NAME),
                    it.getStringFromColumn(NUMBER),
                    it.getStringFromColumn(TYPE),
                    it.getStringFromColumn(DATE),
                    it.getStringFromColumn(DURATION)
                 )

                 matrix.add(list.toList())
             }
          }

          return matrix
      }

     private fun Cursor.getStringFromColumn(columnName: String) =
        getString(getColumnIndex(columnName))
}

เรายังสามารถแปลงเคอร์เซอร์เป็นแผนที่:

fun getCallLogs(context: Context): Map<String, Array<String?>> {
    val c = context.applicationContext
    val projection = arrayOf(CACHED_NAME, NUMBER, TYPE, DATE, DURATION)

    val cursor = c.contentResolver.query(
        CONTENT_URI,
        projection,
        null,
        null,
        null,
        null
    )

    return cursorToMap(cursor)
}

private fun cursorToMap(cursor: Cursor?): Map<String, Array<String?>> {
    val arraySize = cursor?.count ?: 0
    val map = mapOf(
        CACHED_NAME to Array<String?>(arraySize) { "" },
        NUMBER to Array<String?>(arraySize) { "" },
        TYPE to Array<String?>(arraySize) { "" },
        DATE to Array<String?>(arraySize) { "" },
        DURATION to Array<String?>(arraySize) { "" }
    )

    cursor?.use {
        for (i in 0 until arraySize) {
            it.moveToNext()

            map[CACHED_NAME]?.set(i, it.getStringFromColumn(CACHED_NAME))
            map[NUMBER]?.set(i, it.getStringFromColumn(NUMBER))
            map[TYPE]?.set(i, it.getStringFromColumn(TYPE))
            map[DATE]?.set(i, it.getStringFromColumn(DATE))
            map[DURATION]?.set(i, it.getStringFromColumn(DURATION))
        }
    }

    return map
}

0

ก่อนที่จะพิจารณาให้สิทธิ์ในการอ่านบันทึกการโทรหรืออ่าน SMS เป็นส่วนหนึ่งของแอปพลิเคชันของคุณเราขอแนะนำอย่างยิ่งให้คุณดูนโยบายของ Google Play Market นี้: https://support.google.com/googleplay/android-developer/answer/9047303 ? hl = th

สิทธิ์เหล่านั้นมีความละเอียดอ่อนมากและคุณจะต้องพิสูจน์ว่าแอปพลิเคชันของคุณต้องการ แต่แม้ว่าจะต้องการจริงๆก็ตามทีมสนับสนุน Google Play ก็อาจปฏิเสธคำขอของคุณได้อย่างง่ายดายโดยไม่มีคำอธิบายที่เหมาะสม

นี่คือสิ่งที่เกิดขึ้นกับฉัน หลังจากให้ข้อมูลที่จำเป็นทั้งหมดพร้อมกับวิดีโอสาธิตการใช้งานแอปพลิเคชันของฉันถูกปฏิเสธพร้อมคำอธิบายว่า"บัญชีของฉันไม่ได้รับอนุญาตให้จัดหาโซลูชันกรณีการใช้งานบางอย่างในแอปพลิเคชันของฉัน" (รายการกรณีการใช้งานที่อาจพิจารณาว่าเป็นข้อยกเว้น แสดงอยู่ในหน้านโยบายนั้น) ไม่มีการเชื่อมโยงไปยังคำแถลงนโยบายใด ๆ เพื่ออธิบายความหมายทั้งหมด โดยพื้นฐานแล้วพวกเขาตัดสินแอปของฉันว่าจะไม่ไปโดยไม่มีคำอธิบายที่เหมาะสม

ขอให้คุณโชคดีกับแอพพลิเคชั่นของคุณ แต่ระวัง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.