WIFI를 통해 네트워크에 연결되어 있는지 감지해야합니다. 유효한 네트워크 연결을 설정하기 위해 전송되는 내용. HTTP에 유효한 네트워크 연결이 있는지 확인해야합니다. 올바른 연결이 존재하는지 확인하기 위해 무엇을 듣고 추가 테스트를 수행해야합니다.
WIFI를 통해 네트워크에 연결되어 있는지 감지해야합니다. 유효한 네트워크 연결을 설정하기 위해 전송되는 내용. HTTP에 유효한 네트워크 연결이 있는지 확인해야합니다. 올바른 연결이 존재하는지 확인하기 위해 무엇을 듣고 추가 테스트를 수행해야합니다.
답변:
BroadcastReceiver
WiFi 연결이 설정되거나 연결이 변경되면 알림을 받도록 등록 할 수 있습니다 .
등록 BroadcastReceiver
:
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
registerReceiver(broadcastReceiver, intentFilter);
그리고 당신의 BroadcastReceiver
일에서 다음과 같이하십시오 :
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (action.equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION)) {
if (intent.getBooleanExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, false)) {
//do stuff
} else {
// wifi connection was lost
}
}
}
자세한 내용은 BroadcastReceiver
및 설명서를 참조하십시오.WifiManager
물론이 전에 장치가 이미 WiFi에 연결되어 있는지 확인해야합니다.
편집 : 금지 지오 엔지니어링 덕분에 장치가 이미 연결되어 있는지 확인하는 방법이 있습니다.
private boolean isConnectedViaWifi() {
ConnectivityManager connectivityManager = (ConnectivityManager) appObj.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mWifi = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
return mWifi.isConnected();
}
private boolean isConnectedViaWifi() { ConnectivityManager connectivityManager = (ConnectivityManager) appObj.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo mWifi = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI); return mWifi.isConnected(); }
나를 위해 일한 최고 :
<receiver android:name="com.AEDesign.communication.WifiReceiver" >
<intent-filter android:priority="100">
<action android:name="android.net.wifi.STATE_CHANGE" />
</intent-filter>
</receiver>
public class WifiReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
if(info != null && info.isConnected()) {
// Do your work.
// e.g. To check the Network Name or other info:
WifiManager wifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
String ssid = wifiInfo.getSSID();
}
}
}
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
나를 위해 WifiManager.NETWORK_STATE_CHANGED_ACTION
작동합니다.
방송 수신기를 등록하십시오.
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
registerReceiver(broadcastReceiver, intentFilter);
수신 :
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if(action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)){
NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
boolean connected = info.isConnected();
//call your method
}
}
사용자 @JPM 및 @usman의 답변은 실제로 매우 유용합니다. 잘 작동하지만 onReceive
제 경우에는 4 번 여러 번 나옵니다. 므로 코드가 여러 번 실행됩니다.
나는 약간의 수정을하고 내 요구 사항에 따라하고 지금은 1 번만 온다.
다음은 Broadcast의 Java 클래스입니다.
public class WifiReceiver extends BroadcastReceiver {
String TAG = getClass().getSimpleName();
private Context mContext;
@Override
public void onReceive(Context context, Intent intent) {
mContext = context;
if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = cm.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_WIFI &&
networkInfo.isConnected()) {
// Wifi is connected
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
String ssid = wifiInfo.getSSID();
Log.e(TAG, " -- Wifi connected --- " + " SSID " + ssid );
}
}
else if (intent.getAction().equalsIgnoreCase(WifiManager.WIFI_STATE_CHANGED_ACTION))
{
int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN);
if (wifiState == WifiManager.WIFI_STATE_DISABLED)
{
Log.e(TAG, " ----- Wifi Disconnected ----- ");
}
}
}
}
Android에서
<receiver android:name=".util.WifiReceiver" android:enabled="true">
<intent-filter>
<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
</intent-filter>
</receiver>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
사용자에게 매번 묻는 일반적인 동작을 무시하도록 선택하면 Wi-Fi 연결을 시작할 수 있습니다 .
세 가지 방법을 사용하기로 결정했습니다 ...
public boolean isOnline()
{
ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
return (networkInfo != null && networkInfo.isConnected());
}
인터넷에 Wi-Fi 또는 CellData가 연결되어 있는지 빠르게 확인할 수 있습니다. 여기에서 수행 할 작업을 선택할 수 있습니다. 비행기 모드인지 확인해야합니다.
별도의 스레드에서. 변수 IpAddress를 = ""로 설정하고 유효한 IP 주소가 될 때까지 폴링합니다.
WifiManager wifi;
wifi = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = wifi.getConnectionInfo();
int ipAddress = wifiInfo.getIpAddress();
String ip = null;
ip = String.format("%d.%d.%d.%d",
(ipAddress & 0xff),
(ipAddress >> 8 & 0xff),
(ipAddress >> 16 & 0xff),
(ipAddress >> 24 & 0xff));
Log.e(" >>IP number Begin ",ip);
다른 코드 스 니펫 ... 켜져 있지 않은 경우 (사용자의 사전 승인을 받아)
if(wifi.isWifiEnabled()!=true)wifi.setWifiEnabled(true);
WIFI 연결 상태를 감지하기 위해 ConnectivityManager 클래스의 CONNECTIVITY_ACTION을 사용했습니다.
IntentFilter filter=new IntentFilter();
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(receiver, filter);
BroadCastReceiver에서 :
if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) {
int networkType = intent.getIntExtra(
android.net.ConnectivityManager.EXTRA_NETWORK_TYPE, -1);
if (ConnectivityManager.TYPE_WIFI == networkType) {
NetworkInfo networkInfo = (NetworkInfo) intent
.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
if (networkInfo != null) {
if (networkInfo.isConnected()) {
// TODO: wifi is connected
} else {
// TODO: wifi is not connected
}
}
}
}
추신 : 저에게 잘 작동합니다 :)
이 코드에는 권한이 전혀 필요하지 않습니다. Wi-Fi 네트워크 연결 상태 변경으로 만 제한됩니다 (다른 네트워크는 고려되지 않음). 수신자는 AndroidManifest.xml 파일에 정적으로 게시 되며 모든 네트워크 연결 상태가 변경 될 때마다 시스템 protected broadcast
에서 호출되므로 내보낼 필요가 없습니다 NETWORK_STATE_CHANGED_ACTION
.
안드로이드
<receiver
android:name=".WifiReceiver"
android:enabled="true"
android:exported="false">
<intent-filter>
<!--protected-broadcast: Special broadcast that only the system can send-->
<!--Corresponds to: android.net.wifi.WifiManager.NETWORK_STATE_CHANGED_ACTION-->
<action android:name="android.net.wifi.STATE_CHANGE" />
</intent-filter>
</receiver>
BroadcastReceiver 클래스 :
public class WifiReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
/*
Tested (I didn't test with the WPS "Wi-Fi Protected Setup" standard):
In API15 (ICE_CREAM_SANDWICH) this method is called when the new Wi-Fi network state is:
DISCONNECTED, OBTAINING_IPADDR, CONNECTED or SCANNING
In API19 (KITKAT) this method is called when the new Wi-Fi network state is:
DISCONNECTED (twice), OBTAINING_IPADDR, VERIFYING_POOR_LINK, CAPTIVE_PORTAL_CHECK
or CONNECTED
(Those states can be obtained as NetworkInfo.DetailedState objects by calling
the NetworkInfo object method: "networkInfo.getDetailedState()")
*/
/*
* NetworkInfo object associated with the Wi-Fi network.
* It won't be null when "android.net.wifi.STATE_CHANGE" action intent arrives.
*/
NetworkInfo networkInfo = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
if (networkInfo != null && networkInfo.isConnected()) {
// TODO: Place the work here, like retrieving the access point's SSID
/*
* WifiInfo object giving information about the access point we are connected to.
* It shouldn't be null when the new Wi-Fi network state is CONNECTED, but it got
* null sometimes when connecting to a "virtualized Wi-Fi router" in API15.
*/
WifiInfo wifiInfo = intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO);
String ssid = wifiInfo.getSSID();
}
}
}
권한 :
None
다음은 Wifi에 연결된 경우에만 통신을 허용하는 사용자 기본 설정을 고려한 내 코드의 예입니다.
나는이 코드를 내부에서 호출하고있다. IntentService
물건을 다운로드하려고 시도하기 전에이 .
이 참고 NetworkInfo
가 될 것입니다 null
어떤 종류의 네트워크 연결이없는 경우.
private boolean canConnect()
{
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
boolean canConnect = false;
boolean wifiOnly = SharedPreferencesUtils.wifiOnly();
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if(networkInfo != null)
{
if(networkInfo.isConnected())
{
if((networkInfo.getType() == ConnectivityManager.TYPE_WIFI) ||
(networkInfo.getType() != ConnectivityManager.TYPE_WIFI && !wifiOnly))
{
canConnect = true;
}
}
}
return canConnect;
}
Android O는 WiFi 상태 변경을 위해 암시 적 브로드 캐스트를 수신 할 가능성을 제거했습니다. 따라서 앱이 닫히면 앱을받을 수 없습니다. 새로운WorkManager
기능은 앱을 닫을 때 실행할 수 있으므로 약간 실험 해 보았으며 꽤 잘 작동하는 것 같습니다.
이것을 종속성에 추가하십시오.
implementation "android.arch.work:work-runtime:1.0.0-alpha08"
WifiConnectWorker.kt
class WifiConnectWorker : Worker() {
override fun doWork(): Result {
Log.i(TAG, "I think we connected to a wifi")
return Result.SUCCESS
}
}
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity)
val workManager = WorkManager.getInstance()
// Add constraint to start the worker when connecting to WiFi
val request = OneTimeWorkRequest.Builder(WifiConnectWorker::class.java)
.setConstraints(Constraints.Builder()
.setRequiredNetworkType(UNMETERED)
.build())
.build()
// The worker should be started, even if your app is closed
workManager.beginUniqueWork("watch_wifi", REPLACE, request).enqueue()
}
}
이는 일회성 알림에 대한 간단한 테스트 일뿐입니다. WiFi를 켜고 끌 때 항상 알림을 받으려면 더 많은 작업이 필요합니다.
추신 : 앱이 강제 종료 되면 작업자가 시작되지 않고 WorkManager
요청을 취소하는 것 같습니다 .
나는이 코드를 사용했다 :
public class MainActivity extends Activity
{
.
.
.
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
.
.
.
}
@Override
protected void onResume()
{
super.onResume();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
registerReceiver(broadcastReceiver, intentFilter);
}
@Override
protected void onPause()
{
super.onPause();
unregisterReceiver(broadcastReceiver);
}
private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver()
{
@Override
public void onReceive(Context context, Intent intent)
{
final String action = intent.getAction();
if (action.equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION))
{
if (intent.getBooleanExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, false))
{
// wifi is enabled
}
else
{
// wifi is disabled
}
}
}
};
}
응용 프로그램 컨텍스트를 수신하는 WIFI 연결을 감지하는 두 가지 방법이 있습니다.
public boolean isConnectedWifi1(Context context) {
try {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if (networkInfo != null) {
NetworkInfo[] netInfo = connectivityManager.getAllNetworkInfo();
for (NetworkInfo ni : netInfo) {
if ((ni.getTypeName().equalsIgnoreCase("WIFI"))
&& ni.isConnected()) {
return true;
}
}
}
return false;
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
return false;
}
public boolean isConnectedWifi(Context context) {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
return networkInfo.isConnected();
}
CONNECTIVITY_CHANGE 브로드 캐스트 를 즐기는 모든 사람들을 위해 Android O에서 앱이 백그라운드에있을 때 더 이상 실행되지 않습니다.
https://developer.android.com/about/versions/o/background.html
1) CONNECTIVITY_ACTION / CONNECTIVITY_CHANGE를 알고 있지만 브로드 캐스트 수신기 접근을 시도했습니다. 가 API 28에서 더 이상 사용되지 않으며 권장되지 않음 . 또한 명시 적 레지스터 사용에 바인딩되어 앱이 실행되는 동안 수신 대기합니다.
2) 또한 작동하지만 앱이 종료되지 않은 Firebase Dispatcher를 시도했습니다.
3) 권장되는 방법은 workManager를 사용하여 registerNetworkRequest ()를 사용하여 프로세스 종료 및 내부적으로 실행을 보장합니다.
# 3 접근 방식에 찬성하는 가장 큰 증거는 Android 문서 자체에서 참조됩니다 . 특히 백그라운드의 앱에 적합합니다.
또한 여기
Android 7.0에서는 CONNECTIVITY_ACTION, ACTION_NEW_PICTURE 및 ACTION_NEW_VIDEO와 같이 일반적으로 사용되는 3 개의 암시 적 브로드 캐스트를 제거합니다. 여러 개의 앱의 백그라운드 프로세스를 한 번에 깨우고 메모리와 배터리에 부담을 줄 수 있기 때문입니다. 앱에서이를 수신하는 경우 Android 7.0을 활용하여 대신 JobScheduler 및 관련 API로 마이그레이션하십시오.
지금까지 Periodic WorkManager 요청을 사용하면 잘 작동합니다.
업데이트 : 나는 그것에 대해 2 시리즈 매체 게시물을 작성 하게되었습니다.