检查所有 activity 上的互联网并显示消息 WHILE net is disconnected

Check for internet on all activity and show message WHILE net is disconnected

目标

这是我想要做的:

  1. 在我的应用程序的所有活动中始终检查互联网连接(到目前为止我有 13 个活动)。
  2. 如果网络正常,则一切正常。
  3. 如果网络不工作,显示一条消息(使用 RelativeLayout),该消息将在用户离线时显示,即直到网络再次工作,该消息将在那里(无论 activity 用户去哪里)

之前的尝试

这是我尝试过的:

  1. 我试图创建一个扩展 Broadcast Receiver 的 class。我在所有活动上创建了一个 class 的对象并注册了接收者。
  2. 在我的class中,每当网络状态发生变化时,主class通过Intent发送消息给activity,然后activity接收并检查消息(代码在下面)。

这是问题所在:

  1. 我从来没有取消注册接收器,这当然给了我一个错误。

    Are you missing a call to unregisterReceiver()?
    
  2. 如果我取消注册接收器,它会给我以下错误:

    java.lang.IllegalArgumentException: Receiver not registered
    

活动中的代码

// The onCreate function (Just a sample)

onCreate(){
            registerReceiver(broadcastReceiver, new IntentFilter("broadCastName"));
}

// Outside OnCreate
NetworkStatus broadcastReceiver =  new NetworkStatus() {
    @Override
    public void onReceive(Context context, Intent intent) {
        String message;
        Bundle b = intent.getExtras();
        message = b.getString(KEY_NET_MESSAGE);

        if (message.equals(KEY_NET_DISCONNECTED)){
            Toast.makeText(SignupActivity.this, MESSAGE_NET_DISCONNECTED, Toast.LENGTH_SHORT).show();
            btnSignup.setEnabled(false);
            Network_disconnection.setVisibility(View.VISIBLE);
        }
        if (message.equals(KEY_NET_CONNECTED)){
            btnSignup.setEnabled(true);
            Network_disconnection.setVisibility(View.INVISIBLE);
        }

    }
};

//onStop, just a sample
@Override
protected void onStop() {
    unregisterReceiver(broadcastReceiver);
    super.onStop();
}

AndroidManifest.xml

<receiver android:name=".Common.NetworkStatus">
        -
        <intent-filter>
            <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
        </intent-filter>
    </receiver>

NetworkStatus.java

public class NetworkStatus extends BroadcastReceiver implements Keys.UniversalKeys{

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

    boolean isConnected = arg1.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
    if(isConnected){
        Intent i = new Intent("broadCastName");
        // Data you need to pass to activity
        i.putExtra(KEY_NET_MESSAGE, KEY_NET_DISCONNECTED);

        context.sendBroadcast(i);
    }
    else{

        Intent i = new Intent("broadCastName");
        // Data you need to pass to activity
        i.putExtra(KEY_NET_MESSAGE, KEY_NET_CONNECTED);

        context.sendBroadcast(i);
        Toast.makeText(context, KEY_NET_CONNECTED, Toast.LENGTH_LONG).show();
    }
}
}

问题

我做错了什么?我很清楚一件事,也许我不应该在每个 activity 上创建新的接收器!另外,为什么我需要制作一个额外的 java 文件?我的意思是为什么我不能在每个 activity 上创建一个 BroadcastReceiver 对象并继续它?

了解 XML 与 JAVA

当您在 AndroidMainfest.XML 中注册接收器时,它是静态的。即使应用程序关闭,它也会 运行。

当您在 JAVA (Activity) 中注册接收器时,它是动态的,可以通过动态编码注册和取消注册。

解决方案

  1. 使用以下代码创建 class SampleActivity.java:

    public class SampleActivity extends AppCompatActivity {
        // Declare BroadcastReceiver and RelativeLayout
        BroadcastReceiver breceiver;
        RelativeLayout NoNetBar;
    
    
        @Override
            protected void onResume() {
                Toast.makeText(SampleActivity.this, "App has Resumed", Toast.LENGTH_SHORT).show();
    
                // Register your receiver upon resume.
                registerReceiver(breceiver, new IntentFilter("broadCastName"));
                Toast.makeText(SampleActivity.this, "Broadcast Registered", Toast.LENGTH_SHORT).show();
                super.onResume();
            }
    
            public void setRelative(RelativeLayout param_bar) {
                Toast.makeText(SampleActivity.this, "NoNetBar has been setup", Toast.LENGTH_SHORT).show();
                // This will set RelativeLayout to your desired RelativeLayout from your main activity
                NoNetBar = param_bar;
            }
    
            @Override
            protected void onCreate(@Nullable Bundle savedInstanceState) {
                // Call super oncreate and then set RelativeLayout to invisible initially
                super.onCreate(savedInstanceState);
    
                NoNetBar.setVisibility(View.INVISIBLE);
    
                // Initialize broadcast receiver
                breceiver = new BroadcastReceiver() {
                    @Override
                    public void onReceive(Context context, Intent intent) {
            boolean isConnected = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
                        if (isConnected){
                            NoNetBar.setVisibility(View.VISIBLE);
                        } else if (!isConnected){
                            NoNetBar.setVisibility(View.INVISIBLE);
                        }
    
                    }
                };
                Toast.makeText(SampleActivity.this, "Broadcast Initialized", Toast.LENGTH_SHORT).show();
    
    
                Toast.makeText(SampleActivity.this, "App is Created", Toast.LENGTH_SHORT).show();
            }
    
            @Override
            protected void onPause() {
                super.onPause();
                Toast.makeText(SampleActivity.this, "App has Paused", Toast.LENGTH_SHORT).show();
    
                // Unregister your receiver
                unregisterReceiver(breceiver);
                Toast.makeText(SampleActivity.this, "Broadcast UnRegistered", Toast.LENGTH_SHORT).show();
            }
    }
    

这个 class 扩展了 AppCompatActivity(像往常一样)。您可以使用此 class 创建一个 activity 任何您希望接收器工作的地方,但有一些例外。

  1. 在其他活动中使用此 class,如下所示:

    public class MainActivity extends SampleActivity {
    
        Button btnNext;
        RelativeLayout Network_disconnection;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            // Make sure that you can setRelative before calling super.onCreate or you will get a NULL POINTER EXCEPTION
            setRelative(Network_disconnection);
    
            Toast.makeText(MainActivity.this, "Now Calling Supper", Toast.LENGTH_SHORT).show();
            super.onCreate(savedInstanceState);
    
        }
    }
    
  2. 您可以查看此 link 以了解 Activity 生命周期:
    https://developer.android.com/training/basics/activity-lifecycle/starting.html 或者如果赶时间,请查看此图片: