无法添加窗口 - 令牌 null 不适用于广播接收器的 OnReceive 内的应用程序

Posted

技术标签:

【中文标题】无法添加窗口 - 令牌 null 不适用于广播接收器的 OnReceive 内的应用程序【英文标题】:Unable to add window -- token null is not for an application inside OnReceive of Broadcast Receiver 【发布时间】:2016-09-30 18:27:49 【问题描述】:
I'm trying to implement a scenario, if my application loses internet connectivity I'm posting a alert dialog to the user.

I'm planning to use Broadcast receiver to check internet connectivity in my app by using register and unregister in my main activity.

Here is the code:

**BroadcastReceiver** class : here I'm checking the internet connectivity.

我正在检查 wifi 或数据连接服务,如果不可用,我会提醒用户。

public class NetworkChangeReceiver extends BroadcastReceiver 

    private static final String TAG = "ConnectionReceiver";

    private AlertDialog alertDialog;

    public NetworkChangeReceiver() 
    

    @Override
    public void onReceive(final Context context, final Intent intent) 
        if (intent.getAction().equals("android.net.conn.CONNECTIVITY_CHANGE")) 
            ConnectivityManager cm =
                    (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

            NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
            boolean isConnected = activeNetwork != null &&
                    activeNetwork.isConnectedOrConnecting();
            if (isConnected) 
                try 
                    if (alertDialog != null && alertDialog.isShowing())
                        alertDialog.dismiss();
                 catch (Exception e) 
                    e.printStackTrace();
                
             else 
                if (alertDialog == null || !alertDialog.isShowing()) 
                    AlertDialog.Builder builder = new AlertDialog.Builder(context);
                    builder.setTitle("No internet connection");
                    builder.setMessage("check your connection.");
                    builder.setPositiveButton(context.getString(R.string.confirm_button_text), new DialogInterface.OnClickListener() 
                                @Override
                                public void onClick(DialogInterface dialog, int which) 

                                
                            );
                    alertDialog = builder.create();
                    alertDialog.show();
                
            
        
    




**And in my Activity I'm registering the broadcast receiver.** :

public class MyActivity extends Activity 

    private NetworkChangeReceiver networkChangeReceiver = new NetworkChangeReceiver();

@Override
    protected void onResume() 
        super.onResume();
        registerReceiver(networkChangeReceiver, new IntentFilter(
                "android.net.conn.CONNECTIVITY_CHANGE"));
    

    @Override
    protected void onPause() 
        super.onPause();
        unregisterReceiver(networkChangeReceiver);
    




When I put my phone in airplane mode , alert dialog pops up and after 2 seconds my app gives an "Unable to add window -- token null is not for an application " exception. and this exception occurs 2 times.

**here is my log**:

AndroidRuntime: FATAL EXCEPTION: main Process: , PID: 9923 java.lang.RuntimeException: Unable to start receiver xxxx.NetworkChangeReceiver: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application

Caused by: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application


My **Manifest** file:

<application
        android:name="xxxxx"
        android:allowBackup="true"
        tools:replace = "android:icon"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">

        <receiver android:name=".xxx.NetworkChangeReceiver" >
            <intent-filter>
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
                <action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
            </intent-filter>
        </receiver>


<activity
            android:name="xxxx"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>

    </application>

谁能帮我解决这个异常,为什么异常会发生两次?

【问题讨论】:

How to raise an alert dialog from BroadcastReceiver class?的可能重复 这发生了两次,因为您在两个地方注册了接收器;清单和Activity 在我的活动中,我还有 20 个其他片段。每次用户移动到其他片段时,我都想显示警报对话框。但它仅在调用 onResume 时显示,即一次。如果我移动到其他片段,我关闭我的警报对话框后,我想再次弹出警报。知道怎么做吗?我需要在所有片段中注册吗? 我不明白你在问什么。您正在为CONNECTIVITY_CHANGE 广播注册接收器。为什么它会因为用户导航到另一个Fragment 而触发? 我的意思是我的应用程序有底部标签,当我的应用程序启动并且没有互联网连接时,我会弹出一个警报,并且在用户按“确定”将其关闭并导航到其他标签后,即新片段 我想再次提醒用户没有连接。简而言之,每当他导航到其他片段时,我都想改变用户关于互联网连接的信息。 【参考方案1】:

只需从 manifest.xml 中删除我的接收器即可解决我的问题。谢谢。

【讨论】:

以上是关于无法添加窗口 - 令牌 null 不适用于广播接收器的 OnReceive 内的应用程序的主要内容,如果未能解决你的问题,请参考以下文章

对话框抛出“无法添加窗口 - 令牌 null 不适用于应用程序”,getApplication() 作为上下文

Android 1.6:“android.view.WindowManager$BadTokenException:无法添加窗口——令牌 null 不适用于应用程序”

错误的窗口令牌,您无法在创建 Activity 之前或在广播接收器中隐藏异常之后显示对话框

广播接收器不适用于SMS

自动检查互联网的广播接收器不适用于果冻豆或奇巧

WorkManager 不适用于百度推送 SDK