1. 程式人生 > >Android監聽系統來電,彈出提示視窗

Android監聽系統來電,彈出提示視窗

1.問題

專案中有自己企業的通訊錄,但是在應用中撥打公司通訊錄的聯絡人,由於手機通訊錄中沒有相應的資訊,只顯示一串電話號

2 .目的

監聽系統來電,獲取到電話號碼,通過呼叫介面,查詢出來相應電話號碼的詳細資訊,並彈出系統懸浮框,給使用者提示。

3.實現

首先 註冊廣播監聽系統來電。監聽系統來電需要、註冊相應的許可權

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE"
/>

自定義廣播去監聽系統來電

 public class PhoneReceiver extends BroadcastReceiver {

    private Context mcontext;


    @Override
    public void onReceive(Context context, Intent intent){
        mcontext=context;
        System.out.println("action"+intent.getAction());
        if(intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)){
            //如果是去電(撥出)
Log.e("TAG","撥出"); }else{ Log.e("TAG","來電"); TelephonyManager tm = (TelephonyManager)context.getSystemService(Service.TELEPHONY_SERVICE); tm.listen(listener, PhoneStateListener.LISTEN_CALL_STATE); //設定一個監聽器 } } private
PhoneStateListener listener=new PhoneStateListener(){ @Override public void onCallStateChanged(int state, final String incomingNumber) { // TODO Auto-generated method stub //state 當前狀態 incomingNumber,貌似沒有去電的API super.onCallStateChanged(state, incomingNumber); switch(state){ case TelephonyManager.CALL_STATE_IDLE: Log.e("TAG","結束通話"); break; case TelephonyManager.CALL_STATE_OFFHOOK: Log.e("TAG","接聽"); break; case TelephonyManager.CALL_STATE_RINGING: //輸出來電號碼 Log.e("TAG","響鈴:來電號碼"+incomingNumber); Log.e("TAG","響鈴:======"+Thread.currentThread().getName()); break; } } }; };

需要靜態註冊廣播

 <receiver android:name="com.cloud.adapter.myview.PhoneReceiver">
            <intent-filter>
                <action android:name="android.intent.action.PHONE_STATE"/>
                <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
                <action android:name="android.intent.action.NEW_OUTGOING_CALL" />
            </intent-filter>
        </receiver>

其次在註冊完,廣播之後我們需要在監聽到系統的來電之後,後獲取到電話號之後去請求介面,獲取資料。並彈出系統懸浮框。

注意:在彈出系統懸浮框的時候需要註冊許可權,並且檢查應用的允許彈出懸浮框許可權是否開啟。

 <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />

在監聽中的 TelephonyManager.CALL_STATE_RINGING中操作

        inflate= LayoutInflater.from(mcontext);
                            wm = (WindowManager)mcontext.getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
                            WindowManager.LayoutParams params = new WindowManager.LayoutParams();
                            params.type = WindowManager.LayoutParams.TYPE_PHONE;
                            params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
                            params.gravity= Gravity.CENTER;
                            params.width = WindowManager.LayoutParams.MATCH_PARENT;
                            params.height = 600;
                            params.format = PixelFormat.RGBA_8888;
                            phoneView=inflate.inflate(R.layout.phone_alert,null);
                            wm.addView(phoneView, params);

自定義一個佈局檔案,作為要新增的View,佈局檔案如下

 <?xml version="1.0" encoding="utf-8"?>
    <com.cloud.adapter.myview.MyLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="300dp"
    android:layout_height="200dp"
    android:orientation="vertical"
    android:layout_gravity="center"
    android:id="@+id/rootview"

    >
    <LinearLayout
    android:background="@drawable/top_background"
    android:layout_width="300dp"
    android:layout_height="100dp"
    android:orientation="vertical"
    android:layout_gravity="center"
    android:gravity="center"

    >
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="陸XX"
        android:textSize="26sp"
        />
    <TextView
        android:layout_marginTop="5dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="16sp"
        android:text="系統執行科科長"
        />
    </LinearLayout>
    <LinearLayout
        android:background="@drawable/bottom_background"
        android:layout_width="300dp"
        android:layout_height="100dp"
        android:orientation="vertical"
        android:layout_gravity="center"
        android:gravity="center"
        >
        <TextView
            android:textColor="#fff"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="公司本部-資訊中心-系統運營科"
            android:textSize="20sp"
            />
        <TextView
            android:layout_marginTop="10dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="20sp"
            android:textColor="#fff"
            android:text="XXX有限公司"
            android:layout_marginBottom="10dp"
            />
    </LinearLayout>

    </com.cloud.adapter.myview.MyLinearLayout>

使用到兩個背景shape

 <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners android:topLeftRadius="20dp"
        android:topRightRadius="20dp"
        />
    <solid android:color="@color/colorPrimary"/>
    </shape>

------------------------------------------

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners android:bottomLeftRadius="20dp"
        android:bottomRightRadius="20dp"
        />
    <solid android:color="#f44"/>
    </shape>

廣播中完整程式碼

 package com.cloud.adapter.myview;

    import android.app.Activity;
    import android.app.Service;
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.graphics.PixelFormat;
    import android.os.Handler;
    import android.os.Looper;
    import android.telephony.PhoneStateListener;
    import android.telephony.TelephonyManager;
    import android.util.Log;
    import android.view.Gravity;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.WindowManager;
    import android.widget.TextView;

    /**
     * Created by zhang on 2017/10/10.
     */

    public class PhoneReceiver extends BroadcastReceiver {

    private Context mcontext;
    private WindowManager wm;

    @Override
    public void onReceive(Context context, Intent intent){
        mcontext=context;
        System.out.println("action"+intent.getAction());
        if(intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)){
            //如果是去電(撥出)
            Log.e("TAG","撥出");
        }else{
            //查了下android文件,貌似沒有專門用於接收來電的action,所以,非去電即來電
            Log.e("TAG","來電");
            TelephonyManager tm = (TelephonyManager)context.getSystemService(Service.TELEPHONY_SERVICE);
            tm.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
            //設定一個監聽器
        }
    }

    private TextView tv;
    private LayoutInflater inflate;
    private View phoneView;
    private PhoneStateListener listener=new PhoneStateListener(){

        @Override
        public void onCallStateChanged(int state, final String incomingNumber) {
            // TODO Auto-generated method stub
            //state 當前狀態 incomingNumber,貌似沒有去電的API
            super.onCallStateChanged(state, incomingNumber);
            switch(state){
                case TelephonyManager.CALL_STATE_IDLE:
                    Log.e("TAG","結束通話");
                    wm.removeView(tv);
                    break;
                case TelephonyManager.CALL_STATE_OFFHOOK:
                    Log.e("TAG","接聽");
                    wm.removeView(tv);
                    break;
                case TelephonyManager.CALL_STATE_RINGING:

                    inflate= LayoutInflater.from(mcontext);
                    wm = (WindowManager)mcontext.getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
                    WindowManager.LayoutParams params = new WindowManager.LayoutParams();
                    params.type = WindowManager.LayoutParams.TYPE_PHONE;
                    params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
                    params.gravity= Gravity.CENTER;
                    params.width = WindowManager.LayoutParams.MATCH_PARENT;
                    params.height = 600;
                    params.format = PixelFormat.RGBA_8888;
                    phoneView=inflate.inflate(R.layout.phone_alert,null);
                    wm.addView(phoneView, params);
                    Log.e("TAG","響鈴:來電號碼"+incomingNumber);
                    Log.e("TAG","響鈴:======"+Thread.currentThread().getName());
                    //輸出來電號碼
                    break;
            }
        }
    };
    };

效果圖
這裡寫圖片描述

相關推薦

Android系統來電提示視窗

1.問題 專案中有自己企業的通訊錄,但是在應用中撥打公司通訊錄的聯絡人,由於手機通訊錄中沒有相應的資訊,只顯示一串電話號 2 .目的 監聽系統來電,獲取到電話號碼,通過呼叫介面,查詢出來相應電話號碼的詳細資訊,並彈出系統懸浮框,給使用者提示。 3

Android 如何返回鍵一個退出對話方塊

Android 如何監聽返回鍵點選事件,並建立一個退出對話方塊, 防止自己寫的應用程式不小心點選退出鍵而直接退出。自己記錄下這個簡單的demo,備用。 注:如下程式碼當時是從網上copy過來的,現在忘了它出自哪個原作者了,在此說聲抱歉。 原始碼如下: public cla

Android開發 之 返回鍵一個退出對話方塊

Android 如何監聽返回鍵點選事件,並建立一個退出對話方塊,防止自己寫的應用程式不小心點選退出鍵而直接退出。 自己記錄下這個簡單的demo,備用。 注:如下程式碼當時是從網上copy過來的,現在忘了它出自哪個原作者了,在此說聲抱歉。 原始碼如下: public

android軟鍵盤的與隱藏並獲取軟鍵盤的高度

最近專案中有一個需求上彈出軟鍵盤的時候,輸入框位移至輸入框上方,但是Activity中其他的VIew都不動。這個需求需要監聽軟軟鍵盤的彈出與隱藏,並獲取鍵盤的高度。上網找了一下發現,Android竟然沒有提供相應的介面。網上找到的替代方法中最常用的就是自定義根試圖從寫on

Android在Fragment中軟鍵盤的和關閉

原理是通過根佈局與當前佈局高度差來判斷的,Fragment實現ViewTreeObserver.OnGlobalLayoutListener這個介面。 @Override public void onGlobalLayout() {

ReactNative Android返回鍵在某個頁面返回鍵退出應用

在之前專案中,在進行返回鍵退出應用時,應用的程式碼如下: componentWillMount() { if (Platform.OS === 'android') { BackHandler.addEventListener('hardwa

Android 系統音樂播放器播放的音樂的方法

  最近在做專案的時候遇到一個小問題,就是需要自己寫一個View來控制系統音樂播放器的播放行為,並且要能得到正在播放的音樂的資訊,可能剛開始是想省點時間,所以就沒有直接去看原始碼,而是上網搜尋了一下,但令我十分驚訝的是網上竟然沒有這個,難道說沒有童鞋做過這個?嘿嘿,啥

Android系統廣播 和自定義廣播遇到的問題

現在有一個專案需要做一個開機自啟動的功能,這個怎麼實現呢?一頓咔咔咔百度,發現很多推薦 使用監聽系統開機廣播BOOT_COMPLETED,CONNECTIVITY_CHANGE 來實現。那好吧  我也這麼來做。先寫一個RootReceiver  extends Broadc

[Android] 系統網路連線開啟或者關閉的訊息

很簡單,所以直接看程式碼。 package xxx; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; impo

如何軟鍵盤的、隱藏(親測可用)

看了N多文章,終於找到了答案 第一步 注意:必須設定 android:windowSoftInputMode="adjustResize" 原理 注意下面的activityRootView對應的R.id.activityR

Android 系統媒體音量變化

在做 SAPA 適配時由於其直連驅動層不經過 Android 的音量增益控制,所以調節系統媒體音量對音量改變無效。現要調節系統音量時也可以控制播放的音量,那麼就需要監聽系統音量變化,然後轉換成增益給輸出

Android 最多輸入30個字元就不能輸入提示框提醒

android顯示edittext最多輸入字元,Android 中的EditText最大可輸入字元數可以通過xml檔案中為EditText設定maxLength屬性或者在程式碼中為EditText設定L

背景變暗提示

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xm

VS2010 MFC點選父視窗的按鈕視窗

MFC 點選一個對話方塊按鈕彈出另一個對話方塊 vs2010中 1.在資源中新增一個對話方塊  右擊Dialog | Insert dialog 2.在對話方塊上新增自己需要的按鈕等控制元件 3.雙擊控制元件會出現一個對話方塊,為新增的對話方塊命名一個類名,例如Dlg

layui button 按鈕提示視窗確定才進行

<button lay-id="{$id}" class='layui-btn layui-btn-normal correct_finish' onclick="return confirm("

Android 中Notification進度條一直提示提示

Android 8.0中Notification的Progress每次更新進度,都會彈出提示,並且有提示音。原始碼如下public void notifyDownloading(long progress, long num, String file_name) {

javaFX 可控制自動關閉時間的提示視窗

public static void showTimedDialog(long time, String message) { Stage popup = new Stage(); pop

廣播小案例-系統網絡狀態 --Android開發

演示 系統網絡 perm new reat inf roi ron str 本例通過廣播實現簡單的監聽系統網絡狀態改變的小案例。 1、案例效果演示 當手機連網後,系統提示“已連接網絡”, 當手機斷網後,系統提示“當前網絡不可

Android使用者開啟系統相機進行錄影行為

首先,新建一個廣播: public class CameraReceiver extends BroadcastReceiver { @Override public void o

Android開發之使一開啟activity等介面Edittext獲取焦點軟鍵盤java程式碼實現

// 獲取編輯框焦點 editText.setFocusable(true); //開啟軟鍵盤 IInputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVI