简体   繁体   English

Android:在通话期间显示通知?

[英]Android: Presenting a notification during a call?

I have a broadcast receiver that listens to incoming calls. 我有一个广播接收器,可以监听来电。 And I want to tweak the incoming call screen. 我想调整来电屏幕。 Right now I can present toasts and add notifications to the notification bar (BTW the user can't pull it down because the screen is locked, before accepting the call, which kinda sucks). 现在,我可以呈现敬酒并向通知栏添加通知(顺便说一句,用户不能将其拉下,因为在接受呼叫之前,屏幕已锁定,这有点糟)。 I tried to show an alert but it crashed - is it not allowed? 我试图显示警报,但崩溃了-不允许吗? Is there a way for the code in the broadcast receiver to do other things, like change the avatar of the caller or give it a name (even if it doesn't exist in the contacts). 广播接收器中的代码是否可以执行其他操作,例如更改呼叫者的头像或为其命名(即使联系人中不存在)。 Let's just say my broadcast receiver intercepts a call - can it add the phone number and a custom avatar to the contacts, so that they will immediately be presented in the call screen? 假设我的广播接收器拦截了一个呼叫-它可以在联系人中添加电话号码和自定义头像,以便它们立即显示在呼叫屏幕中吗?

What do you think? 你怎么看?


Edit 编辑

I have tested vendor's code, and it worked, but it is not safe to change the UI from a background thread, so I tried to tweak his code a bit to make it thread safe but the toast doesn't appear for some reason. 我已经测试了供应商的代码,并且可以正常工作,但是从后台线程更改UI并不安全,因此我尝试稍微调整一下他的代码以使其成为线程安全,但是由于某些原因没有出现吐司。 What do you think? 你怎么看?

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

You need a BroadcastReceiver like that: 您需要这样的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);
        }

    }

}

And register it in the manifest to <action android:name="android.intent.action.PHONE_STATE"></action> . 并在清单中将其注册到<action android:name="android.intent.action.PHONE_STATE"></action>

Then create an Activity like that: 然后创建一个活动,像这样:

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

which has this layout: 具有以下布局:

<?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>

This will produce a translucent dialog-like activity on top of the incoming call screen, that allows the user to answer the call (doesn't interfere with touch events). 这将在来电屏幕上方产生半透明的类似对话框的活动,使用户可以接听电话(不会干扰触摸事件)。

Up to Android 2.3 you can not override the calling screen, but you can show a Toast message on it. 在Android 2.3及更高版本中,您无法覆盖呼叫屏幕,但可以在其上显示Toast消息。 The longest period of a toast is 3 seconds and after that it will dissapear. 烤面包的最长时间为3秒,此后消失。 You can however create a thread that calls show() method of the toast every 2 seconds. 但是,您可以创建一个线程,每2秒调用一次吐司的show()方法。 Something like that: 像这样:

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

You have to declare toast: 您必须声明吐司:

private Toast toast;

You have to init the toast object befor showing it. 您必须在显示它之前初始化烤面包对象。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM