Это довольно просто. Вам нужно добавить следующее разрешение на использование в манифесте 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