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

下面貼出第二個程序的代碼,調用第一個程序ContentProvidler的接口

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="org.crazyit.resolver"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".DictResolver"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".ResultActivity" 
            android:theme="@android:style/Theme.Dialog"
            android:label="找到的來電記錄">
        </activity>
    </application>
</manifest> 
/**
 * 
 */
package org.crazyit.content;
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 org.crazyit.resolver;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import org.crazyit.content.Words;
import org.crazyit.resolver.R;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

/**
 * @author  Yeeku.H.Lee kongyeeku@163.com
 * @version  1.0
 */
public class DictResolver extends Activity
{
    ContentResolver contentResolver;
    Button search = null;
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        // 獲取系統的ContentResolver對象
        contentResolver = getContentResolver();
        search = (Button)findViewById(R.id.search);    
        // 為insert按鈕的單擊事件綁定事件監聽器
        search.setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View source)
            {
                // 獲取用戶輸入
                String key = "";
                // 執行查詢
                Cursor cursor = getContentResolver().query(
                    Words.Word.DICT_CONTENT_URI, null 
                    , null
                    , null 
                    , null);
                //創建一個Bundle對象
                Bundle data = new Bundle();
                data.putSerializable("data", converCursorToList(cursor));
                //創建一個Intent
                Intent intent = new Intent(DictResolver.this
                    , ResultActivity.class);
                intent.putExtras(data);
                //啟動Activity
                startActivity(intent);
            }
        });
    }

    private ArrayList<Map<String, String>> converCursorToList(
        Cursor cursor)
    {
        ArrayList<Map<String, String>> result 
            = new ArrayList<Map<String, String>>();
        // 遍歷Cursor結果集
        while (cursor.moveToNext())
        {
            // 將結果集中的數據存入ArrayList中
            Map<String, String> map = new HashMap<String, String>();
            // 取出查詢記錄中第2列、第3列的值
            map.put(Words.Word.WORD, cursor.getString(1));
            map.put(Words.Word.DETAIL, cursor.getString(2));
            result.add(map);
        }
        return result;
    }
}
/**
 * 
 */
package org.crazyit.resolver;

import java.util.List;
import java.util.Map;

import org.crazyit.content.Words;
import org.crazyit.resolver.R;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.ListView;
import android.widget.SimpleAdapter;

/**
 * @version  1.0
 */
public class ResultActivity extends Activity
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.popup);
        ListView listView = (ListView)findViewById(R.id.show);
        Intent intent = getIntent();
        //獲取該intent所攜帶的數據
        Bundle data = intent.getExtras();
        //從Bundle數據包中取出數據
        @SuppressWarnings("unchecked")
        List<Map<String , String>> list = 
            (List<Map<String , String>>)data.getSerializable("data");
        //將List封裝成SimpleAdapter
        SimpleAdapter adapter = new SimpleAdapter(
            ResultActivity.this , list
            , R.layout.line , new String[]{Words.Word.WORD  
            , Words.Word.DETAIL}
            , new int[]{R.id.word , R.id.detail});
        //填充ListView
        listView.setAdapter(adapter);
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM