Làm cách nào để truy cập nhật ký cuộc gọi cho android?


95

Tôi muốn nhận nhật ký cuộc gọi. Ví dụ: số lượng cuộc gọi của người dùng, số phút đã gọi, v.v.

Làm cách nào để đạt được điều này trong Android?


có thể đây là giải pháp cho U developer.android.com/reference/android/database/...
Nikunj Patel

Tôi nhớ nó là trình phân giải nội dung, tuy nhiên tôi không biết phải bắt đầu như thế nào.
3

Câu trả lời:


69

Điều này là để truy cập lịch sử cuộc gọi điện thoại:

Kể từ Jellybean (4.1), bạn cần có quyền sau:
<uses-permission android:name="android.permission.READ_CALL_LOG" />

Mã:

 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
Đừng quên bật quyền này: <use-allow android: name = "android.permission.READ_CALL_LOG" /> đây là phương pháp để lấy nhật ký cuộc gọi:
Aziz

Tôi không biết điều đó nhưng về mặt lý thuyết, tôi có thể nói rằng tất cả các tin nhắn được lưu trữ trong cùng một cơ sở dữ liệu. Vì vậy, nó có thể truy cập tất cả các tin nhắn của thiết bị bất kể sim kép hay sim đơn. Kiểm tra mã này và cho tôi biết nếu nó không hoạt động với sim kép. Tôi sẽ thực hiện một số nghiên cứu và phát triển và cung cấp cho bạn mã cho việc đó.
Abhinav Singh Maurya,

1
get name sẽ luôn trả về null, hãy cẩn thận
vuhung3990 02/02

@Abhinav Singh Maurya bạn có thể giúp tôi lấy photo_uri nhật ký cuộc gọi từ nhật ký cuộc gọi không vì tôi không thể lấy photo_uri từ nhật ký cuộc gọi
Sagar

1
ManagedQuery () không được dùng nữa thay vào đó sử dụng Cursor cursor = context.getContentResolver (). query (CallLog.Calls.CONTENT_URI, null, null, null, CallLog.Calls.DATE + "DESC");
Sai Gopi Me

67

Đây là phương pháp được sử dụng để lấy Nhật ký cuộc gọi. Chỉ cần đặt phương thức này trong lớp của bạn và nhận Danh sách Nhật ký cuộc gọi.

Kiểm tra cái này

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

    }

đầu ra trông

nhập mô tả hình ảnh ở đây


Tôi đang gặp lỗi tại ManagedQuery (CallLog.Calls.CONTENT_URI, null, null, null, null);
Sunil Parmar

5
Tôi đã sử dụng contentResolver.query (CallLog.Calls.CONTENT_URI, null, null, null, null);
Sunil Parmar

@Dwivedi Ji - Bài này hơi cũ - Phương pháp của bạn hoạt động nhưng phải mất ít nhất 10 giây để tải tất cả nhật ký cuộc gọi của tôi.
TheDevMan

@TheDevMan, xin lỗi vì sự bất tiện của bạn, Có bạn là đúng, tôi sẽ cập nhật câu trả lời của tôi sớm,
Dwivedi Ji

Cảm ơn tôi sẽ chờ đợi câu trả lời của bạn!
TheDevMan

48

sử dụng phương pháp này từ mọi nơi với một ngữ cảnh

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
Vì ManagedQuery hiện không được dùng nữa nên câu trả lời này phù hợp nhất.
abhi

16

Bài đăng này hơi cũ, nhưng đây là một giải pháp dễ dàng khác để lấy dữ liệu liên quan đến Callnhà cung cấp nội dung nhật ký trong Android:

Sử dụng lib này: https://github.com/EverythingMe/easy-content-providers

Nhận tất cả các cuộc gọi:

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

Mỗi Cuộc gọi có tất cả các trường, vì vậy bạn có thể nhận được bất kỳ thông tin nào bạn cần: ngày
gọi, thời lượng, số điện thoại, loại (THU NHẬP, XUẤT XỨ, ĐÃ BỎ LỠ), isRead, ...

Nó hoạt động với Listhoặc Cursorvà có một ứng dụng mẫu để xem nó trông như thế nào và hoạt động như thế nào.

Trên thực tế, có một hỗ trợ cho tất cả các nhà cung cấp nội dung Android như: Danh bạ, SMS, Lịch, ... Tài liệu đầy đủ với tất cả các tùy chọn: https://github.com/EverythingMe/easy-content-providers/wiki/Android-providers

Hy vọng nó cũng giúp ích :)


Này, tôi đã kiểm tra giải pháp của bạn, nó là tốt. Vấn đề duy nhất mà tôi đang phải đối mặt là làm thế nào để thêm phần phụ thuộc vào dự án nhật thực của tôi?
Aradhna

@aradhna thư viện đang sử dụng gradle và được xây dựng từ Android Studio. Tôi nghĩ rằng, bạn sẽ cần phải sửa đổi nó một chút để làm cho nó chạy trên Eclipse
sromku

9

trong dự án của tôi, tôi gặp lỗi int htc device. biết mã này là phổ biến. Tôi nghĩ rằng đây là sự giúp đỡ cho bạn.

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

}

2

Để chỉ có lịch sử cuộc gọi đến, mã bên dưới sẽ giúp bạn :)

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

2

Để nhận lịch sử Cuộc gọi Đến, Đi và Nhỡ, hy vọng mã này sẽ giúp bạn :)

Gọi mã này trên chuỗi nền của bạn.

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

1

Sử dụng mã dưới đây:

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

Nếu chúng ta sử dụng Kotlin thì nó ngắn hơn. Ví dụ về lớp phản hồi để cung cấp nhật ký cuộc gọi:

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

Chúng tôi cũng có thể chuyển đổi con trỏ sang bản đồ:

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

Trước khi cân nhắc đặt quyền Đọc Nhật ký cuộc gọi hoặc Đọc SMS trở thành một phần trong ứng dụng của bạn, tôi thực sự khuyên bạn nên xem chính sách này của Google Play Market: https://support.google.com/googleplay/android-developer/answer/9047303 ? hl = vi

Những quyền đó rất nhạy cảm và bạn sẽ phải chứng minh rằng ứng dụng của bạn cần chúng. Nhưng ngay cả khi thực sự cần, Nhóm hỗ trợ của Google Play có thể dễ dàng từ chối yêu cầu của bạn mà không có lời giải thích thích hợp.

Đây là những gì xảy ra với tôi. Sau khi cung cấp tất cả các thông tin cần thiết cùng với video Trình diễn về ứng dụng của tôi, ứng dụng của tôi đã bị từ chối với giải thích rằng "tài khoản của tôi không được phép cung cấp giải pháp trường hợp sử dụng nhất định trong ứng dụng của tôi" (danh sách các trường hợp sử dụng mà họ có thể coi là ngoại lệ được liệt kê trên trang Chính sách đó). Không có liên kết đến bất kỳ tuyên bố chính sách nào được cung cấp để giải thích tất cả ý nghĩa của nó. Về cơ bản, họ chỉ đánh giá ứng dụng của tôi là không hoạt động mà không có lời giải thích thích hợp.

Tôi chúc bạn may mắn vì các ứng dụng của bạn, nhưng hãy cẩn thận.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.