Nik*_*wal 228 java android broadcastreceiver android-networking android-wifi
我正在开发一个用于检查互联网连接的Android广播接收器.
问题是我的广播接收器被调用了两次.我希望它只在网络可用时才被调用.如果它不可用,我不希望得到通知.
这是广播接收器
public class NetworkChangeReceiver extends BroadcastReceiver {
@Override
public void onReceive(final Context context, final Intent intent) {
final ConnectivityManager connMgr = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
final android.net.NetworkInfo wifi = connMgr
.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
final android.net.NetworkInfo mobile = connMgr
.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
if (wifi.isAvailable() || mobile.isAvailable()) {
// Do something
Log.d("Network Available ", "Flag No 1");
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是manifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.broadcastreceiverforinternetconnection"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<receiver android:name=".NetworkChangeReceiver" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
</intent-filter>
</receiver>
</application>
</manifest>
Run Code Online (Sandbox Code Playgroud)
小智 234
回答你的第一个问题:你的广播接收器被叫了两次,因为
你添加了两个 <intent-filter>
网络连接的变化:
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
WiFi状态的变化:
<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
只需使用一个:
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
.
它只会响应一个动作而不是两个动作.有关更多信息,请参见此处
回答你的第二个问题(如果互联网连接可用,你希望接收者只能拨打一次电话):
你的代码很完美; 只有在互联网可用时才通知您.
UPDATE
如果您只想检查移动设备是否与互联网连接,您可以使用此方法检查您的连接.
public boolean isOnline(Context context) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
//should check null because in airplane mode it will be null
return (netInfo != null && netInfo.isConnected());
}
Run Code Online (Sandbox Code Playgroud)
Vai*_*iya 74
public class NetworkChangeReceiver extends BroadcastReceiver {
@Override
public void onReceive(final Context context, final Intent intent) {
if(checkInternet(context))
{
Toast.makeText(context, "Network Available Do operations",Toast.LENGTH_LONG).show();
}
}
boolean checkInternet(Context context) {
ServiceManager serviceManager = new ServiceManager(context);
if (serviceManager.isNetworkAvailable()) {
return true;
} else {
return false;
}
}
}
Run Code Online (Sandbox Code Playgroud)
ServiceManager.java
public class ServiceManager {
Context context;
public ServiceManager(Context base) {
context = base;
}
public boolean isNetworkAvailable() {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = cm.getActiveNetworkInfo();
return networkInfo != null && networkInfo.isConnected();
}
}
Run Code Online (Sandbox Code Playgroud)
权限:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
Run Code Online (Sandbox Code Playgroud)
Kes*_*era 51
每次使用广播接收器检查互联网状态:
AndroidManifest.xml中
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<receiver android:name=".receivers.NetworkChangeReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
Run Code Online (Sandbox Code Playgroud)
BroadcastReciever
package com.keshav.networkchangereceiverexample.receivers;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;
import static com.keshav.networkchangereceiverexample.MainActivity.dialog;
public class NetworkChangeReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
{
try
{
if (isOnline(context)) {
dialog(true);
Log.e("keshav", "Online Connect Intenet ");
} else {
dialog(false);
Log.e("keshav", "Conectivity Failure !!! ");
}
} catch (NullPointerException e) {
e.printStackTrace();
}
}
private boolean isOnline(Context context) {
try {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
//should check null because in airplane mode it will be null
return (netInfo != null && netInfo.isConnected());
} catch (NullPointerException e) {
e.printStackTrace();
return false;
}
}
}
Run Code Online (Sandbox Code Playgroud)
MainActivity.java
package com.keshav.networkchangereceiverexample;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
import android.net.ConnectivityManager;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.TextView;
import com.keshav.networkchangereceiverexample.receivers.NetworkChangeReceiver;
public class MainActivity extends AppCompatActivity {
private BroadcastReceiver mNetworkReceiver;
static TextView tv_check_connection;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_check_connection=(TextView) findViewById(R.id.tv_check_connection);
mNetworkReceiver = new NetworkChangeReceiver();
registerNetworkBroadcastForNougat();
}
public static void dialog(boolean value){
if(value){
tv_check_connection.setText("We are back !!!");
tv_check_connection.setBackgroundColor(Color.GREEN);
tv_check_connection.setTextColor(Color.WHITE);
Handler handler = new Handler();
Runnable delayrunnable = new Runnable() {
@Override
public void run() {
tv_check_connection.setVisibility(View.GONE);
}
};
handler.postDelayed(delayrunnable, 3000);
}else {
tv_check_connection.setVisibility(View.VISIBLE);
tv_check_connection.setText("Could not Connect to internet");
tv_check_connection.setBackgroundColor(Color.RED);
tv_check_connection.setTextColor(Color.WHITE);
}
}
private void registerNetworkBroadcastForNougat() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
registerReceiver(mNetworkReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
registerReceiver(mNetworkReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}
}
protected void unregisterNetworkChanges() {
try {
unregisterReceiver(mNetworkReceiver);
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
}
@Override
public void onDestroy() {
super.onDestroy();
unregisterNetworkChanges();
}
}
Run Code Online (Sandbox Code Playgroud)
activity_main.xml中
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.keshav.networkchangereceiverexample.MainActivity">
<TextView
android:id="@+id/tv_check_connection"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Connection establised !"
android:padding="25dp"
app:layout_constraintBottom_toBottomOf="parent"
android:gravity="center"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)
Aj *_* 27 26
使用此方法检查网络状态:
private void checkInternetConnection() {
if (br == null) {
br = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Bundle extras = intent.getExtras();
NetworkInfo info = (NetworkInfo) extras
.getParcelable("networkInfo");
State state = info.getState();
Log.d("TEST Internet", info.toString() + " "
+ state.toString());
if (state == State.CONNECTED) {
Toast.makeText(getApplicationContext(), "Internet connection is on", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(), "Internet connection is Off", Toast.LENGTH_LONG).show();
}
}
};
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver((BroadcastReceiver) br, intentFilter);
}
}
Run Code Online (Sandbox Code Playgroud)
记得在onDestroy中取消注册服务.
干杯!!
Sum*_*ain 13
警告: Declaring a broadcastreceiver for android.net.conn.CONNECTIVITY_CHANGE is deprecated for apps targeting N and higher. In general, apps should not rely on this broadcast and instead use JobScheduler or GCMNetworkManager.
由于CONNECTIVITY_CHANGE
已弃用,因此我们应该使用另一种方式来做同样的事情
以下NetworkConnectionLiveData
将处理到现在为止的所有操作系统版本,如果目标 SDK 小于Build.VERSION_CODES.LOLLIPOP
那时,则只有我们可以使用broadcastReceiver
最好的部分是这个类使用LiveData
所以不需要注册任何接收器使用LiveData
它会处理所有的事情
class NetworkConnectionLiveData(val context: Context) : LiveData<Boolean>() {
private var connectivityManager: ConnectivityManager = context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
private lateinit var connectivityManagerCallback: ConnectivityManager.NetworkCallback
override fun onActive() {
super.onActive()
updateConnection()
when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.N -> connectivityManager.registerDefaultNetworkCallback(getConnectivityManagerCallback())
Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP -> lollipopNetworkAvailableRequest()
else -> {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
context.registerReceiver(networkReceiver, IntentFilter("android.net.conn.CONNECTIVITY_CHANGE"))
}
}
}
}
override fun onInactive() {
super.onInactive()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
connectivityManager.unregisterNetworkCallback(connectivityManagerCallback)
} else {
context.unregisterReceiver(networkReceiver)
}
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private fun lollipopNetworkAvailableRequest() {
val builder = NetworkRequest.Builder()
.addTransportType(android.net.NetworkCapabilities.TRANSPORT_CELLULAR)
.addTransportType(android.net.NetworkCapabilities.TRANSPORT_WIFI)
connectivityManager.registerNetworkCallback(builder.build(), getConnectivityManagerCallback())
}
private fun getConnectivityManagerCallback(): ConnectivityManager.NetworkCallback {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
connectivityManagerCallback = object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network?) {
postValue(true)
}
override fun onLost(network: Network?) {
postValue(false)
}
}
return connectivityManagerCallback
} else {
throw IllegalAccessError("Should not happened")
}
}
private val networkReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
updateConnection()
}
}
private fun updateConnection() {
val activeNetwork: NetworkInfo? = connectivityManager.activeNetworkInfo
postValue(activeNetwork?.isConnected == true)
}
}
Run Code Online (Sandbox Code Playgroud)
在任何类中使用 LiveData:
NetworkConnectionLiveData(context ?: return)
.observe(viewLifecycleOwner, Observer { isConnected ->
if (!isConnected) {
// Internet Not Available
return@Observer
}
// Internet Available
})
Run Code Online (Sandbox Code Playgroud)
小智 9
public static boolean isNetworkAvailable(Context context) {
boolean isMobile = false, isWifi = false;
NetworkInfo[] infoAvailableNetworks = getConnectivityManagerInstance(
context).getAllNetworkInfo();
if (infoAvailableNetworks != null) {
for (NetworkInfo network : infoAvailableNetworks) {
if (network.getType() == ConnectivityManager.TYPE_WIFI) {
if (network.isConnected() && network.isAvailable())
isWifi = true;
}
if (network.getType() == ConnectivityManager.TYPE_MOBILE) {
if (network.isConnected() && network.isAvailable())
isMobile = true;
}
}
}
return isMobile || isWifi;
}
/* You can write such method somewhere in utility class and call it NetworkChangeReceiver like below */
public class NetworkChangedReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent) {
if (isNetworkAvailable(context))
{
Toast.makeText(context, "Network Available Do operations",Toast.LENGTH_LONG).show();
}
}
}
Run Code Online (Sandbox Code Playgroud)
仅当网络状态更改为已连接且未断开连接时,才会调用上述广播接收器.
试试这个
public class ConnectionBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (<Check internet connection available >) {
Toast.makeText(context, "connect to the internet", Toast.LENGTH_LONG).show();
/*upload background upload service*/
Intent serviceIntent = new Intent(context,<your service class>);
context.startService(serviceIntent);
}else{
Toast.makeText(context, "Connection failed", Toast.LENGTH_LONG).show();
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是广播接收器.一旦互联网连接触发这将加载
我知道这个帖子已经老了并且已经完全回答了,但我觉得以下内容对某些人有帮助.
问题正文中的代码包含一个没有人在这里解决的错误.@Nikhil正在检查无线/移动是否可用,如果已连接则无法检查.
修复程序在这里:
@Override
public void onReceive(final Context context, final Intent intent) {
final ConnectivityManager connMgr = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
final android.net.NetworkInfo wifi = connMgr
.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
final android.net.NetworkInfo mobile = connMgr
.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
if (wifi.isConnected() || mobile.isConnected()) {
// do stuff
}
}
Run Code Online (Sandbox Code Playgroud)
这是针对活动、片段或上下文执行此操作的一种舒适方式。如果您为活动/片段(在 onDestroy 中)执行此操作,它也会自动取消注册,如果您愿意:
abstract class ConnectionBroadcastReceiver : BroadcastReceiver() {
companion object {
@JvmStatic
fun registerWithoutAutoUnregister(context: Context, connectionBroadcastReceiver: ConnectionBroadcastReceiver) {
context.registerReceiver(connectionBroadcastReceiver, IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION))
}
@JvmStatic
fun registerToFragmentAndAutoUnregister(context: Context, fragment: Fragment, connectionBroadcastReceiver: ConnectionBroadcastReceiver) {
val applicationContext = context.applicationContext
registerWithoutAutoUnregister(applicationContext, connectionBroadcastReceiver)
fragment.lifecycle.addObserver(object : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun onDestroy() {
applicationContext.unregisterReceiver(connectionBroadcastReceiver)
}
})
}
@JvmStatic
fun registerToActivityAndAutoUnregister(activity: AppCompatActivity, connectionBroadcastReceiver: ConnectionBroadcastReceiver) {
registerWithoutAutoUnregister(activity, connectionBroadcastReceiver)
activity.lifecycle.addObserver(object : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun onDestroy() {
activity.unregisterReceiver(connectionBroadcastReceiver)
}
})
}
@JvmStatic
fun hasInternetConnection(context: Context): Boolean {
val info = (context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager).activeNetworkInfo
return !(info == null || !info.isConnectedOrConnecting)
}
}
override fun onReceive(context: Context, intent: Intent) {
val hasConnection = !intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false)
// Log.d("AppLog", "conenctivity changed. hasConnection? $hasConnection")
onConnectionChanged(hasConnection)
}
abstract fun onConnectionChanged(hasConnection: Boolean)
}
Run Code Online (Sandbox Code Playgroud)
片段中的用法:
ConnectionBroadcastReceiver.registerToFragmentAndAutoUnregister(activity!!, this, object : ConnectionBroadcastReceiver() {
override fun onConnectionChanged(hasConnection: Boolean) {
// Log.d("AppLog", "onConnectionChanged:" + hasConnection)
}
})
Run Code Online (Sandbox Code Playgroud)
表现:
<receiver android:name=".your.namepackage.here.ConnectivityReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
</intent-filter>
</receiver>
Run Code Online (Sandbox Code Playgroud)
接收者类:
public class ConnectivityReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
switch (action) {
case ConnectivityManager.CONNECTIVITY_ACTION:
DebugUtils.logDebug("BROADCAST", "network change");
if(NetworkUtils.isConnect()){
//do action here
}
break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
和classs utils类似的例子:
public class NetworkUtils {
public static boolean isConnect() {
ConnectivityManager connectivityManager = (ConnectivityManager) Application.getInstance().getSystemService(Context.CONNECTIVITY_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Network[] netArray = connectivityManager.getAllNetworks();
NetworkInfo netInfo;
for (Network net : netArray) {
netInfo = connectivityManager.getNetworkInfo(net);
if ((netInfo.getTypeName().equalsIgnoreCase("WIFI") || netInfo.getTypeName().equalsIgnoreCase("MOBILE")) && netInfo.isConnected() && netInfo.isAvailable()) {
//if (netInfo.getState().equals(NetworkInfo.State.CONNECTED)) {
Log.d("Network", "NETWORKNAME: " + netInfo.getTypeName());
return true;
}
}
} else {
if (connectivityManager != null) {
@SuppressWarnings("deprecation")
NetworkInfo[] netInfoArray = connectivityManager.getAllNetworkInfo();
if (netInfoArray != null) {
for (NetworkInfo netInfo : netInfoArray) {
if ((netInfo.getTypeName().equalsIgnoreCase("WIFI") || netInfo.getTypeName().equalsIgnoreCase("MOBILE")) && netInfo.isConnected() && netInfo.isAvailable()) {
//if (netInfo.getState() == NetworkInfo.State.CONNECTED) {
Log.d("Network", "NETWORKNAME: " + netInfo.getTypeName());
return true;
}
}
}
}
}
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
仅用于想要动态注册广播的其他人:
BroadcastReceiver mWifiReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (checkWifiConnect()) {
Log.d(TAG, "wifi has connected");
// TODO
}
}
};
private void registerWifiReceiver() {
IntentFilter filter = new IntentFilter();
filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
mContext.registerReceiver(mWifiReceiver, filter);
}
private void unregisterWifiReceiver() {
mContext.unregisterReceiver(mWifiReceiver);
}
private boolean checkWifiConnect() {
ConnectivityManager manager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = manager.getActiveNetworkInfo();
if (networkInfo != null
&& networkInfo.getType() == ConnectivityManager.TYPE_WIFI
&& networkInfo.isConnected()) {
return true;
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
针对Android 7.0(API级别24)及更高版本的应用如果在其清单中声明广播接收器,则不会收到此广播.如果应用程序使用Context.registerReceiver()注册其BroadcastReceiver并且该上下文仍然有效,它们仍将接收广播.
归档时间: |
|
查看次数: |
246744 次 |
最近记录: |