編輯:Android開發教程
android如何使用BroadcastReceiver後台實現來電通話記錄的監聽並存取到sqllite數據庫通過Contentprovilder實現接口
BroadcastReceiver 是android四大組件的一個,本質上是一種全局的監聽器 ,用於監聽全局的廣播消息。下面實現了後台監聽android手機通話記錄。本demo 分兩個程序,第一個程序是設置監聽器,然後模擬器重啟後就會有一個全局的 service在後台監聽你的來電顯示,大多數通話管理軟件都是這麼干的,第二個項 目是獲取通話記錄的,由於只是做一個小實驗,所以是根據某個項目改的,裡面 涉及到一些ContentPrivler的知識,還有sqllite數據庫,裡面定義名稱並非其意 思。

第一個程序代碼配置文件
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android"
android:versionCode="1"
android:versionName="1.0" >
<application android:icon="@drawable/ic_launcher" android:label="@string/app_name">
<service android:name=".TtActivity">
</service>
<!-- 定義一個BroadcastReceiver,監聽系統開機廣播 -->
<receiver android:name=".LaunchReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<provider android:name=".DictProvider" android:authorities="org.crazyit.providers.dictprovider"/>
</application>
<!-- 授予應用程序訪問系統開機事件的權限 -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
</manifest>
/**
*
*/
package com.android;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class LaunchReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
{
Intent tIntent = new Intent(context , TtActivity.class);
// 啟動指定Service
context.startService(tIntent);
}
}
/**
*
*/
package com.android;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class MyDatabaseHelper extends SQLiteOpenHelper
{
final String CREATE_TABLE_SQL =
"create table dict(_id integer primary key autoincrement , word , detail)";
/**
* @param context
* @param name
* @param version
*/
public MyDatabaseHelper(Context context, String name, int version)
{
super(context, name, null, version);
}
@Override
public void onCreate(SQLiteDatabase db)
{
// 第一個使用數據庫時自動建表
db.execSQL(CREATE_TABLE_SQL);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
System.out.println("--------onUpdate Called--------"
+ oldVersion + "--->" + newVersion);
}
}
package com.android;
import java.io.FileNotFoundException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.os.IBinder;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
public class TtActivity extends Service
{ MyDatabaseHelper dbHelper;
TelephonyManager tManager;
SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String word=format.format(new Date());
@Override
public IBinder onBind(Intent intent)
{
return null;
}
@Override
public void onCreate()
{
tManager = (TelephonyManager) getSystemService
(Context.TELEPHONY_SERVICE);
dbHelper = new MyDatabaseHelper(this
, "myDict.db3" , 1);
// 創建一個通話狀態監聽器
PhoneStateListener listener = new PhoneStateListener()
{
@Override
public void onCallStateChanged(int state
, String detail)
{
switch (state)
{
// 無任何狀態
case TelephonyManager.CALL_STATE_IDLE:
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
break;
// 來電鈴響時
case TelephonyManager.CALL_STATE_RINGING:
OutputStream os = null;
try
{
os = openFileOutput("phoneList", MODE_APPEND);
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
insertData(dbHelper.getReadableDatabase() , word , detail);
// PrintStream ps = new PrintStream(os);
// // 將來電號碼記錄到文件中
// ps.println(new Date() + " 來電:" + incomingNumber);
// ps.close();
break;
default:
break;
}
super.onCallStateChanged(state, detail);
}
};
//監聽電話通話狀態的改變
tManager.listen(listener
, PhoneStateListener.LISTEN_CALL_STATE);
}
private void insertData(SQLiteDatabase db
, String word , String detail)
{
//執行插入語句
db.execSQL("insert into dict values(null , ? , ?)"
, new String[]{word , detail});
}
@Override
public void onDestroy()
{
super.onDestroy();
//退出程序時關閉MyDataBaseHelper裡的SQLiteDatabase
if (dbHelper != null)
{
dbHelper.close();
}
}
}
/**
*
*/
package com.android;
import android.net.Uri;
import android.provider.BaseColumns;
/**
* @version 1.0
*/
public final class Words
{
// 定義該ContentProvider的Authority
public static final String AUTHORITY
= "org.crazyit.providers.dictprovider";
//定義一個靜態內部類
public static final class Word implements BaseColumns
{
// 定義Content所允許操作的3個數據列
public final static String _ID = "_id";
public final static String WORD = "word";
public final static String DETAIL = "detail";
// 定義該Content提供服務的兩個Uri
public final static Uri DICT_CONTENT_URI =
Uri.parse("content://" + AUTHORITY + "/words");
public final static Uri WORD_CONTENT_URI =
Uri.parse("content://" + AUTHORITY + "/word");
}
}
/**
*
*/
package com.android;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
/**
* @version 1.0
*/
public class DictProvider extends ContentProvider
{
private static UriMatcher matcher
= new UriMatcher(UriMatcher.NO_MATCH);
private static final int WORDS = 1;
private static final int WORD = 2;
private MyDatabaseHelper dbOpenHelper;
static
{
// 為UriMatcher注冊兩個Uri
matcher.addURI(Words.AUTHORITY, "words", WORDS);
matcher.addURI(Words.AUTHORITY, "word/#", WORD);
}
// 第一次調用該DictProvider時,系統先創建DictProvider對象,並回調該方法
@Override
public boolean onCreate()
{
dbOpenHelper = new MyDatabaseHelper(this.getContext(), "myDict.db3", 1);
return true;
}
// 插入數據方法
@Override
public Uri insert(Uri uri, ContentValues values)
{
// 獲得數據庫實例
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
// 插入數據,返回行ID
long rowId = db.insert("dict", Words.Word._ID, values);
// 如果插入成功返回uri
if (rowId > 0)
{
// 在已有的 Uri的後面追加ID數據
Uri wordUri = ContentUris.withAppendedId(uri, rowId);
// 通知數據已經改變
getContext().getContentResolver().notifyChange(wordUri, null);
return wordUri;
}
return null;
}
// 刪除數據的方法
@Override
public int delete(Uri uri, String selection, String[] selectionArgs)
{
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
// 記錄所刪除的記錄數
int num = 0;
// 對於uri進行匹配。
switch (matcher.match(uri))
{
case WORDS:
num = db.delete("dict", selection, selectionArgs);
break;
case WORD:
// 解析出所需要刪除的記錄ID
long id = ContentUris.parseId(uri);
String where = Words.Word._ID + "=" + id;
// 如果原來的where子句存在,拼接where子句
if (selection != null && !selection.equals(""))
{
where = where + " and " + selection;
}
num = db.delete("dict", where, selectionArgs);
break;
default:
throw new IllegalArgumentException("未知Uri:" + uri);
}
// 通知數據已經改變
getContext().getContentResolver().notifyChange(uri, null);
return num;
}
// 修改數據的方法
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs)
{
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
// 記錄所修改的記錄數
int num = 0;
switch (matcher.match(uri))
{
case WORDS:
num = db.update("dict", values, selection, selectionArgs);
break;
case WORD:
// 解析出想修改的記錄ID
long id = ContentUris.parseId(uri);
String where = Words.Word._ID + "=" + id;
// 如果原來的where子句存在,拼接where子句
if (selection != null && !selection.equals(""))
{
where = where + " and " + selection;
}
num = db.update("dict", values, where, selectionArgs);
break;
default:
throw new IllegalArgumentException("未知Uri:" + uri);
}
// 通知數據已經改變
getContext().getContentResolver().notifyChange(uri, null);
return num;
}
// 查詢數據的方法
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder)
{
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
switch (matcher.match(uri))
{
case WORDS:
// 執行查詢
return db.query("dict", projection, selection, selectionArgs,
null, null, sortOrder);
case WORD:
// 解析出想查詢的記錄ID
long id = ContentUris.parseId(uri);
String where = Words.Word._ID + "=" + id;
// 如果原來的where子句存在,拼接where子句
if (selection != null && !"".equals(selection))
{
where = where + " and " + selection;
}
return db.query("dict", projection, where, selectionArgs, null,
null, sortOrder);
default:
throw new IllegalArgumentException("未知Uri:" + uri);
}
}
// 返回指定uri參數對應的數據的MIME類型
@Override
public String getType(Uri uri)
{
switch (matcher.match(uri))
{
// 如果操作的數據是多項記錄
case WORDS:
return "vnd.android.cursor.dir/org.crazyit.dict";
// 如果操作的數據是單項記錄
case WORD:
return "vnd.android.cursor.item/org.crazyit.dict";
default:
throw new IllegalArgumentException("未知Uri:" + uri);
}
}
}
Android系統修改版:CyanogenMod 10穩定版現已推出
CyanogenMod 10(CM10),最新基於Android 4.1果凍豆版本的ROM,在今天對少數設備推出。版本10已經在過去的數月經歷了無數個夜晚的beta開發,
Android測試教程(9):ApplicationTestCase示例
前面介紹了Android測試的一些理論知識,從本篇開始的幾篇將結合ApiDemoTest示例來介紹Android測試的實例。在此之前可 以參照Android測試教程(3)
Android ApiDemos示例解析(4) App->Activity->Custom Dialog
App->Activity->Custom Dialog 例子使用Activity 來實現自定義對話框。 類CustomDialogActivity本身無任何
Android 4.2 OTA帶來鎖屏小工具和多用戶支持
Google已經提供了你正在使用的三個Nexus設備之一的系統更新,我們高興的是,Nexus 4和10的Android 4.2 OTA更新也開始推出了。此次的升級包括了&