Это довольно просто. Вам нужно добавить следующее разрешение на использование в манифесте Android, чтобы программно получать историю вызовов.
<uses-permission android:name="android.permission.READ_CONTACTS"
Это все здесь.
А затем создать деятельность и макет. Нам нужно запросить от ContentProvider. И для этого я использовал CursorClassLoader.
Читайте о CursorLoader здесь: http://developer.android.com/training/load-data-background/setup-loader.html
Я хочу загрузить 4 свойства, и они — номер телефона, тип вызова, например. Исходящий или входящий или пропущенный звонок, дата и время звонка и длительность звонка.
Поэтому сначала используйте интерфейс LoaderManager.LoaderCallbacks <Cursor> в своей деятельности. У него есть три метода.
abstract Loader onCreateLoader(int id, Bundle args) //Instantiate and return a new Loader for the given ID. abstract void onLoadFinished(Loader loader, D data) //Called when a previously created loader has finished its load. abstract void onLoaderReset(Loader loader) //Called when a previously created loader is being reset, and thus making its data unavailable.
Чтобы инициализировать запрос, нам нужно вызвать LoaderManager.initLoader () с самого начала.
Мы собираемся добавить кнопку и вызвать ее в событиях этой кнопки здесь и после того, как эта фоновая структура будет инициализирована Как только фоновая структура инициализируется, она вызывает вашу реализацию onCreateLoader () . Чтобы начать запрос, мы должны вернуть CursorLoader из этого метода.
@Override
public Loader onCreateLoader(int loaderID, Bundle args) {
Log.d(TAG, "onCreateLoader() >> loaderID : " + loaderID);
switch (loaderID) {
case URL_LOADER:
// Returns a new CursorLoader
return new CursorLoader(
this, // Parent activity context
CallLog.Calls.CONTENT_URI, // Table to query
null, // Projection to return
null, // No selection clause
null, // No selection arguments
null // Default sort order
);
default:
return null;
}
}
Мы собираемся получить доступ к нашим ожидаемым данным из курсора. И мы получим это в методе onLoadFinished () .
@Override
public void onLoadFinished(Loader loader, Cursor managedCursor) {
Log.d(TAG, "onLoadFinished()");
StringBuilder sb = new StringBuilder();
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("<h4>Call Log Details <h4>");
sb.append("\n");
sb.append("\n");
sb.append("<table>");
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 callTypeCode = Integer.parseInt(callType);
switch (callTypeCode) {
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("<tr>")
.append("<td>Phone Number: </td>")
.append("<td><strong>")
.append(phNumber)
.append("</strong></td>");
sb.append("</tr>");
sb.append("<br/>");
sb.append("<tr>")
.append("<td>Call Type:</td>")
.append("<td><strong>")
.append(dir)
.append("</strong></td>");
sb.append("</tr>");
sb.append("<br/>");
sb.append("<tr>")
.append("<td>Date & Time:</td>")
.append("<td><strong>")
.append(callDayTime)
.append("</strong></td>");
sb.append("</tr>");
sb.append("<br/>");
sb.append("<tr>")
.append("<td>Call Duration (Seconds):</td>")
.append("<td><strong>")
.append(callDuration)
.append("</strong></td>");
sb.append("</tr>");
sb.append("<br/>");
sb.append("<br/>");
}
sb.append("</table>");
managedCursor.close();
callLogsTextView.setText(Html.fromHtml(sb.toString()));
}
Выход:
Полный исходный код: https://github.com/rokon12/call-log
