活动弹出窗口在来电屏幕弹出窗口、屏幕

2023-09-06 02:59:43 作者:初夏那抹浅蓝

我试图覆盖来电屏幕 - 我知道我不能改变它,所以我想ontop弹出的活动

I'm trying to override the incoming call screen - I know I can't change it so I'm trying to popup an activity ontop.

我的code工作正常,只是当手机已经闲置了几分钟。

My code works fine except when the phone has been idle for a few minutes.

我的code:

的Andr​​oidManifest.xml:

<?xml version="1.0" encoding="utf-8" ?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.example.myfirstapp"
      android:versionCode="7"
      android:versionName="7">
    <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="10"></uses-sdk>
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <uses-permission android:name="android.permission.MODIFY_PHONE_STATE"/>
    <uses-permission android:name="android.permission.CALL_PHONE" />

    <application android:label="@string/app_name" android:icon="@drawable/ic_launcher">
        <receiver android:name=".MyPhoneBroadcastReceiver" android:enabled="true">
            <intent-filter android:priority="99999">
                <action android:name="android.intent.action.PHONE_STATE" />
            </intent-filter>
        </receiver>
        <activity
            android:name=".Call" >
        </activity>
    </application>
</manifest>

MyPhoneBroadcastReceiver.java:

public class MyPhoneBroadcastReceiver extends BroadcastReceiver{

    public void onReceive(final Context context, Intent intent) {

        Thread pageTimer = new Thread(){
            public void run(){
                try{
                    sleep(700);
                } catch (InterruptedException e){
                    e.printStackTrace();
                } finally {
                    Intent i = new Intent();
                    i.setClass(context, Call.class);
                    i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                    i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    i.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);  
                    i.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
                    i.putExtra("INCOMING_NUMBER", incomingNumber);
                    i.setAction(Intent.ACTION_MAIN);
                    i.addCategory(Intent.CATEGORY_LAUNCHER);
                    context.startActivity(i);
                }
            }
        };
        pageTimer.start();
    }
}

Call.java:

package com.example.myfirstapp;

import android.app.Activity;
import android.os.Bundle;

public class Call extends Activity{

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
    getWindow().addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
    getWindow().addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    setContentView(R.layout.main);
    }

}

顺便说一句 - 我试图等待屏幕到睡眠(700)之前醒来,它并没有帮助 (在MyPhoneBroadcastReceiver.java)

BTW - I tried waiting for the screen to wake up before the sleep(700) and it didn't help (in MyPhoneBroadcastReceiver.java)

...
try {      
    if (pm.isScreenOn()) {
        sleep(700);
    } else {
        while (!pm.isScreenOn()) {
            // Do nothing...
        }
        sleep(700);
    }
}        

...

推荐答案

在手机屏幕是关闭的,有来电,还有更多的工作要做(醒来,处理键盘锁认为...),所以在中调用活动需要较长时间才能显示出来,这导致的情况下,您呼叫的活动早于在通话活动开始启动 - >将在调用活动是在上面 还有就是在调用活动需要显示器(你已经尝试过,看到700毫秒是不够的)的没有确切时间 我的解决办法:保持跟踪呼叫活动的状态:

When the phone screen is off and there is an incoming call, there are more work to do (waking up, dealing with the keyguard view...) so the in-call activity take longer to show up and this lead to the case your Call activity starts earlier than the in-call activity starts --> the in-call activity is on top There is no exact time that the in-call activity need to displays (you have tried and see that 700 miliseconds is not enough) My solution: keep tracking the state of Call activity:

如果它仍然在顶部,用户没有关闭它(或任何条件 解雇),只要保持跟踪使用handler 如果有任何其他活动,去前台然后呼叫活动 试图让回到顶部 If it's still on top and user has not dismiss it (or any condition to dismiss), just keep tracking using the handler If there is any other activity go to foreground then Call activity try to get the back to top

我的示例活动:

public class MainActivity extends Activity {
    private ActivityManager mActivityManager;
    private boolean mDismissed = false;

    private static final int MSG_ID_CHECK_TOP_ACTIVITY = 1;
    private static final long DELAY_INTERVAL = 100;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Window window = getWindow();
        window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);

        mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        mHandler.sendEmptyMessageDelayed(MSG_ID_CHECK_TOP_ACTIVITY,
                DELAY_INTERVAL);
    }

    private Handler mHandler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            if (msg.what == MSG_ID_CHECK_TOP_ACTIVITY && !mDismissed) {
                List<RunningTaskInfo> tasks = mActivityManager
                        .getRunningTasks(1);
                String topActivityName = tasks.get(0).topActivity
                        .getClassName();
                if (!topActivityName.equals(MainActivity.this
                        .getComponentName().getClassName())) {
                    // Try to show on top until user dismiss this activity
                    Intent i = new Intent();
                    i.setClass(MainActivity.this, MainActivity.class);
                    i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                    i.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
                    startActivity(i);
                }
                sendEmptyMessageDelayed(MSG_ID_CHECK_TOP_ACTIVITY,
                        DELAY_INTERVAL);
            }
        };
    };

}