통화 기록을 받고 싶습니다. 예를 들어 사용자의 통화 수, 통화 시간 (분) 등이 있습니다.
Android에서 어떻게 이것을 달성합니까?
답변:
이것은 전화 통화 내역에 액세스하기위한 것입니다.
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.
통화 기록을 가져 오는 데 사용되는 방법입니다. 이 메소드를 수업에 넣고 통화 기록 목록을 얻으십시오.
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();
}
출력이 보인다

컨텍스트가있는 모든 곳에서이 방법을 사용하십시오.
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();
}
이 게시물은 조금 오래되었지만 CallAndroid에서 로그 콘텐츠 제공 업체 와 관련된 데이터를 가져 오는 또 다른 쉬운 솔루션입니다 .
이 lib 사용 : https://github.com/EverythingMe/easy-content-providers
모든 전화 받기 :
CallsProvider callsProvider = new CallsProvider(context);
List<Call> calls = callsProvider.getCalls().getList();
각 Call 에는 모든 필드가 있으므로 callDate, duration, number, type (INCOMING, OUTGOING, MISSED), isRead 등 필요한 정보를 얻을 수 있습니다
.
그것은 작동 List또는 Cursor그것을보고 어떻게 작동하는지 볼 수있는 샘플 애플리케이션이있다.
실제로 연락처, SMS, 캘린더 등 모든 Android 콘텐츠 제공 업체에 대한 지원이 있습니다. 모든 옵션이 포함 된 전체 문서 : https://github.com/EverythingMe/easy-content-providers/wiki/Android-providers
도움이 되었기를 바랍니다. :)
내 프로젝트에서 오류 int htc device.now이 코드가 보편적입니다. 나는 이것이 당신을위한 도움이라고 생각합니다.
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();
}
}
수신 통화 내역 만 가져 오려면 아래 코드가 도움이 될 것입니다.
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();
}
수신, 발신 및 부재 중 전화 기록을 얻으려면이 코드가 도움이되기를 바랍니다.)
백그라운드 스레드에서이 코드를 호출하십시오.
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----------------------------------");
아래 코드를 사용하십시오.
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));
}
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
}
통화 기록 읽기 또는 SMS 읽기 권한을 애플리케이션의 일부로 만들기 전에 Google Play 마켓의이 정책을 살펴볼 것을 적극 권장합니다. https://support.google.com/googleplay/android-developer/answer/9047303 ? hl = en
이러한 권한은 매우 민감하므로 응용 프로그램에 필요함을 증명해야합니다. 그러나 실제로 필요한 경우에도 Google Play 지원팀은 적절한 설명없이 요청을 쉽게 거부 할 수 있습니다.
이것은 나에게 일어난 일입니다. 내 애플리케이션의 데모 비디오와 함께 필요한 모든 정보를 제공 한 후 내 "계정이 내 애플리케이션에서 특정 사용 사례 솔루션을 제공 할 권한이 없습니다" 라는 설명과 함께 거부되었습니다 (예외로 간주 할 수있는 사용 사례 목록). 해당 정책 페이지에 나열되어 있습니다). 이것이 의미하는 바를 설명하기 위해 정책 설명에 대한 링크가 제공되지 않았습니다. 기본적으로 그들은 내 앱이 적절한 설명 없이는 가지 않는 것으로 판단했습니다.
나는 당신의 응용 프로그램들과 함께 행운을 빕니다. 그러나 조심하십시오.