检查所有 activity 上的互联网并显示消息 WHILE net is disconnected
Check for internet on all activity and show message WHILE net is disconnected
目标
这是我想要做的:
- 在我的应用程序的所有活动中始终检查互联网连接(到目前为止我有 13 个活动)。
- 如果网络正常,则一切正常。
- 如果网络不工作,显示一条消息(使用 RelativeLayout),该消息将在用户离线时显示,即直到网络再次工作,该消息将在那里(无论 activity 用户去哪里)
之前的尝试
这是我尝试过的:
- 我试图创建一个扩展
Broadcast Receiver
的 class。我在所有活动上创建了一个 class 的对象并注册了接收者。
- 在我的class中,每当网络状态发生变化时,主class通过Intent发送消息给activity,然后activity接收并检查消息(代码在下面)。
这是问题所在:
我从来没有取消注册接收器,这当然给了我一个错误。
Are you missing a call to unregisterReceiver()?
如果我取消注册接收器,它会给我以下错误:
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) 中注册接收器时,它是动态的,可以通过动态编码注册和取消注册。
解决方案
使用以下代码创建 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 任何您希望接收器工作的地方,但有一些例外。
在其他活动中使用此 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);
}
}
您可以查看此 link 以了解 Activity 生命周期:
https://developer.android.com/training/basics/activity-lifecycle/starting.html
或者如果赶时间,请查看此图片:
目标
这是我想要做的:
- 在我的应用程序的所有活动中始终检查互联网连接(到目前为止我有 13 个活动)。
- 如果网络正常,则一切正常。
- 如果网络不工作,显示一条消息(使用 RelativeLayout),该消息将在用户离线时显示,即直到网络再次工作,该消息将在那里(无论 activity 用户去哪里)
之前的尝试
这是我尝试过的:
- 我试图创建一个扩展
Broadcast Receiver
的 class。我在所有活动上创建了一个 class 的对象并注册了接收者。 - 在我的class中,每当网络状态发生变化时,主class通过Intent发送消息给activity,然后activity接收并检查消息(代码在下面)。
这是问题所在:
我从来没有取消注册接收器,这当然给了我一个错误。
Are you missing a call to unregisterReceiver()?
如果我取消注册接收器,它会给我以下错误:
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) 中注册接收器时,它是动态的,可以通过动态编码注册和取消注册。
解决方案
使用以下代码创建 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 任何您希望接收器工作的地方,但有一些例外。
在其他活动中使用此 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); } }
您可以查看此 link 以了解 Activity 生命周期:
https://developer.android.com/training/basics/activity-lifecycle/starting.html 或者如果赶时间,请查看此图片: