Bagaimana cara mengakses log panggilan untuk android?

95

Saya ingin menerima log panggilan. Misalnya jumlah panggilan yang dilakukan oleh pengguna, jumlah menit panggilan, dll.

Bagaimana cara mencapai ini di android?

3cross
sumber
mungkin ini adalah solusi untuk pengembang
U.android.com/reference/android/database/…
Saya ingat itu menjadi pemecah konten, namun saya tidak tahu bagaimana memulainya.
melintasi

Jawaban:

69

Ini untuk mengakses riwayat panggilan telepon:

Pada Jellybean (4.1) Anda memerlukan izin berikut:
<uses-permission android:name="android.permission.READ_CALL_LOG" />

Kode:

 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.
Abhinav Singh Maurya
sumber
11
Jangan lupa untuk mengaktifkan izin ini: <using-permission android: name = "android.permission.READ_CALL_LOG" /> ini adalah metode untuk mendapatkan log panggilan:
Aziz
Saya tidak tahu itu tetapi secara teoritis saya dapat mengatakan bahwa semua pesan disimpan dalam database yang sama. Jadi ya itu bisa mengakses semua pesan perangkat terlepas dari dual sim atau single sim. Periksa kode ini dan beri tahu saya jika tidak berfungsi dengan dual sim. Saya akan melakukan beberapa R&D dan memberi Anda kode untuk itu.
Abhinav Singh Maurya
1
mendapatkan nama akan selalu mengembalikan null, hati
vuhung3990
@Abhinav Singh Maurya dapatkah Anda membantu saya mendapatkan log panggilan photo_uri dari log panggilan karena saya tidak bisa mendapatkan photo_uri dari log panggilan
Sagar
1
managedQuery () tidak lagi digunakan sebagai gantinya Cursor cursor = context.getContentResolver (). query (CallLog.Calls.CONTENT_URI, null, null, null, CallLog.Calls.DATE + "DESC");
Sai Gopi Me
67

Ini adalah metode yang digunakan untuk mendapatkan log Panggilan. Letakkan saja metode ini di kelas Anda dan dapatkan Daftar Log Panggilan.

Lihat ini

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();

    }

keluarannya terlihat

masukkan deskripsi gambar di sini

Dwivedi Ji
sumber
Saya mendapatkan kesalahan di managedQuery (CallLog.Calls.CONTENT_URI, null, null, null, null);
Sunil Parmar
5
Saya menggunakan contentResolver.query (CallLog.Calls.CONTENT_URI, null, null, null, null);
Sunil Parmar
@Dwivedi Ji - Ini agak posting lama - Metode Anda berfungsi tetapi membutuhkan setidaknya 10 detik untuk memuat semua log panggilan saya.
TheDevMan
@TheDevMan, maaf atas ketidaknyamanan Anda, Ya Anda benar, saya akan segera memperbarui jawaban saya,
Dwivedi Ji
Terima kasih saya akan menunggu balasan Anda!
TheDevMan
48

gunakan metode ini dari mana saja dengan konteks

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();
}
ingyesid
sumber
7
Karena managedQuery sekarang sudah tidak digunakan lagi, jadi jawaban ini paling relevan.
abhi
16

Posting ini agak lama, tetapi berikut adalah solusi mudah lainnya untuk mendapatkan data yang terkait dengan Callpenyedia konten log di Android:

Gunakan lib ini: https://github.com/EverythingMe/easy-content-providers

Dapatkan semua panggilan:

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

Setiap Panggilan memiliki semua bidang, sehingga Anda bisa mendapatkan info apa pun yang Anda butuhkan:
callDate, durasi, nomor, jenis (MASUK, KELUAR, MISSED), isRead, ...

Ia bekerja dengan Listatau Cursordan ada aplikasi contoh untuk melihat tampilannya dan bekerja.

Faktanya, ada dukungan untuk semua penyedia konten Android seperti: Kontak, SMS, Kalender, ... Dokumen lengkap dengan semua opsi: https://github.com/EverythingMe/easy-content-providers/wiki/Android-providers

Semoga ini juga membantu :)

sromku
sumber
Hei, saya sudah memeriksa solusi Anda, itu bagus. Satu-satunya masalah yang saya hadapi adalah bagaimana menambahkan ketergantungan pada proyek eclipse saya?
Aradhna
@aradhna perpustakaan tersebut menggunakan gradle dan dibangun dari Android Studio. Saya rasa, Anda perlu sedikit memodifikasinya agar dapat berjalan di Eclipse
sromku
9

dalam proyek saya, saya mendapatkan error int htc device. sekarang kode ini bersifat universal. Saya pikir ini membantu Anda.

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

}
Harshid
sumber
2

Untuk mendapatkan Hanya riwayat Panggilan Masuk, kode di bawah ini akan membantu Anda :)

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();
} 
Agilanbu
sumber
2

Untuk mendapatkan riwayat Panggilan Masuk, Keluar dan Tidak Terjawab, semoga kode ini membantu Anda :)

Panggil kode ini di utas latar belakang Anda.

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----------------------------------");
Saurabh Gaddelpalliwar
sumber
1

Gunakan kode Di Bawah Ini:

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




    }
Rohan Lodhi
sumber
0

Jika kita menggunakan Kotlin itu lebih pendek. Contoh kelas yang merespon untuk memberikan log panggilan:

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

Kami juga dapat mengubah kursor ke peta:

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
}
Artem Botnev
sumber
0

Sebelum mempertimbangkan menjadikan izin Baca Log Panggilan atau Baca SMS sebagai bagian dari aplikasi Anda, saya sangat menyarankan Anda untuk melihat kebijakan Google Play Market ini: https://support.google.com/googleplay/android-developer/answer/9047303 ? hl = en

Izin tersebut sangat sensitif dan Anda harus membuktikan bahwa aplikasi Anda membutuhkannya. Tetapi bahkan jika itu benar-benar membutuhkannya, tim Dukungan Google Play dapat dengan mudah menolak permintaan Anda tanpa penjelasan yang tepat.

Inilah yang terjadi pada saya. Setelah memberikan semua informasi yang diperlukan bersama dengan video Demonstrasi aplikasi saya, itu ditolak dengan penjelasan bahwa "akun saya tidak diizinkan untuk memberikan solusi kasus penggunaan tertentu dalam aplikasi saya" (daftar kasus penggunaan yang mungkin mereka anggap sebagai pengecualian terdaftar di halaman Kebijakan itu). Tidak ada tautan ke pernyataan kebijakan apa pun yang diberikan untuk menjelaskan apa artinya semua itu. Pada dasarnya mereka hanya menilai aplikasi saya tidak berjalan tanpa penjelasan yang tepat.

Saya berharap semoga sukses dengan aplikasi Anda, tapi hati-hati.

dpetruha
sumber