4

我有一個收聽來電的廣播接收器。我想調整來電屏幕。現在,我可以提供吐司並將通知添加到通知欄(順便說一下,因爲屏幕已鎖定,用戶無法將其關閉,因此在接受呼叫之前,哪些內容可能會很糟糕)。我試圖顯示一個警報,但它墜毀 - 是不允許的?廣播接收器中的代碼是否有辦法做其他事情,比如更改調用者的頭像或給它起個名字(即使它不存在於聯繫人中)。我們只需說我的廣播接收器攔截了一個電話 - 它是否可以將電話號碼和自定義頭像添加到聯繫人中,以便他們立即顯示在呼叫屏幕中?Android:在通話過程中顯示通知?

您認爲如何?


編輯

我已經測試供應商的代碼,它的工作,但它是不安全的改變從後臺線程的UI,所以我試圖調整自己的代碼位,使其線程安全但由於某種原因,烤麪包不會出現。你怎麼看?

private Handler handler = new Handler(); 

    private void showToast() { 
     Thread thread = new Thread(null, doBackgroundThreadProcessing, "Background"); 
     thread.start(); 
    } 

    private Runnable doBackgroundThreadProcessing = new Runnable() { 
     public void run() { 
      backgroundThreadProcessing(); 
     } 
    }; 

    private void backgroundThreadProcessing() { 
     handler.post(new Runnable() { 
      public void run() { 
       int count = 0; 
       try{ 
        while (count < 10) { 
         toast.show(); 
         Thread.sleep(1850); 
         count++; 

        } 
       } 
       catch(Exception e){ 

        Log.e("LongToast", "", e); 
       } 
      } 
     }); 
    } 

回答

7

你需要這樣一個BroadcastReceiver直來:

public class IncomingBroadcastReceiver extends BroadcastReceiver { 

    @Override 
    public void onReceive(Context context, Intent intent) { 

     MyLog.d("IncomingBroadcastReceiver: onReceive: "); 

     String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE); 
     MyLog.d("IncomingBroadcastReceiver: onReceive: " + state); 
     if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) 
     { 
      Intent i = new Intent(context, IncomingCallActivity.class); 
      i.putExtras(intent); 
      i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 

      context.startActivity(i); 
     } 

    } 

} 

而且在清單中註冊它<action android:name="android.intent.action.PHONE_STATE"></action>

然後創建這樣的活動:

public class IncomingCallActivity extends Activity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 

     MyLog.d("IncomingCallActivity: onCreate: "); 

     // TODO Auto-generated method stub 
     super.onCreate(savedInstanceState); 

     getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE); 
     getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL); 

     setContentView(R.layout.main); 

     String number = getIntent().getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER); 
     TextView text = (TextView)findViewById(R.id.text); 
     text.setText("Incoming call from " + number); 
    } 
} 

具有這種佈局:

<?xml version="1.0" encoding="utf-8"?> 

<TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/text" 
    android:layout_width="match_parent" android:layout_height="match_parent" 
    android:gravity="center_vertical|center_horizontal" 
    android:text="text" 
    android:windowBackground="@android:color/transparent" 
    android:windowIsTranslucent="true" 
    android:windowAnimationStyle="@android:style/Animation.Translucent"></TextView> 

這將產生在來電屏幕的頂部上的半透明對話框樣活性,其允許用戶接聽電話(不干擾觸摸事件)。

+1

我剛剛嘗試了您的代碼,並且在收到呼叫時,將自定義活動顯示一秒鐘,然後顯示常規呼叫屏幕。我根本看不到自定義活動。我使用2.3來測試它在聯結1上。 – Alex1987 2011-04-01 10:39:20

+0

嗨,因爲有些設備在顯示來電活動時有延遲,您可以嘗試在顯示活動之前插入1000ms的睡眠時間。我也有這個問題。 – SirKnigget 2011-04-02 10:42:59

+0

謝謝你,它工作! – Alex1987 2011-04-02 16:56:06

0
+0

你的鏈接提到活動,這不是我問的。我要求創造性地顯示通知。現在,我可以在來電期間以複雜的佈局顯示吐司約3秒鐘。我還可以在通知欄上顯示通知 - 現在還有其他選項嗎? – Alex1987 2011-03-28 16:05:00

+0

@ Alex1987我有同樣的問題。您只能在通知欄中顯示吐司和通知圖標。然而,您可以創建自定義烤麪包的外觀並多次調用顯示方法:) – vendor 2011-03-31 12:45:08

+0

@vendor如何讓烤麪包在很長一段時間內可見?你有一個後臺線程來處理這個問題嗎?如果是的話,你有一些工作代碼嗎? – Alex1987 2011-04-01 10:41:46

4

至於Android 2.3,您不能覆蓋呼叫屏幕,但您可以在其上顯示Toast消息。烤麪包的最長時間是3秒,之後它會消失。但是,您可以創建一個線程,每2秒鐘調用一次麪包的show()方法。類似的東西:

Thread t = new Thread() { 
     public void run() { 

      try { 
       while (true) { 
        if(isInCall){ 

         toast.cancel(); 
         break; 
        } 

        toast.show(); 
        sleep(1850); 
       } 
      } catch (Exception e) { 

       Log.d("Exception: " + e.toString()); 
      } 
     } 
    }; 
    t.start(); 

您必須聲明敬酒:

private Toast toast; 

你必須初始化敬酒對象befor顯示它。

toast = new Toast(getBaseContext());  
LayoutInflater inflater = (LayoutInflater) context 
      .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    View layout = inflater.inflate(R.layout.toast, null, false); 

    toast.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, 0); 
    toast.setDuration(Toast.LENGTH_LONG); 
    toast.setView(layout); 
+0

我測試了您的代碼,它工作正常,但您正在從後臺線程執行UI操作,這可能會導致異常。 – Alex1987 2011-04-01 12:09:05

+0

@ Alex1987這是一個簡單的代碼。您可以添加處理程序並使UI操作安全。 – vendor 2011-04-01 12:22:07

+0

是的,我知道。但是,當我用一個處理程序包裝它時,不會顯示敬酒。我在我的原始消息中發佈了一些代碼。 – Alex1987 2011-04-01 12:57:40