安卓系统中的WiFi连接变更操作

5
我希望在WiFi打开时启动我的应用程序,所以我尝试获取WiFi状态更改功能的操作,但它显示为:

01-27 15:52:10.470: ERROR/AndroidRuntime(11584): java.lang.RuntimeException: Unable to instantiate receiver com.example.WiFiScanReceiver: java.lang.InstantiationException: com.example.WiFiScanReceiver

这是我的清单文件。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.example" android:versionCode="1" android:versionName="1.0">
  <application android:icon="@drawable/icon" android:label="@string/app_name"
    android:theme="@android:style/Theme.Light">
    <activity android:name=".WiFiDemo" android:label="@string/app_name">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
    </activity>
    <receiver android:name="com.example.WiFiScanReceiver">
      <intent-filter>
        <action android:name="android.net.wifi.supplicant.CONNECTION_CHANGE" />
      </intent-filter>
    </receiver>
  </application>
  <uses-sdk android:minSdkVersion="3" />
  <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
  <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
 <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS"></uses-permission>
 <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"> </uses-permission>
 <uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission>
<uses-permission android:name="android.permission.INTERNET" />
</manifest>

我跟随这个链接,指导我如何在Wi-Fi打开时启动我的活动。

package com.example;

import java.util.List;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.IntentFilter;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class WiFiDemo extends Activity implements OnClickListener {
 private static final String TAG = "WiFiDemo";
 WifiManager wifi;
 BroadcastReceiver receiver;

 TextView textStatus;
 Button buttonScan;

 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  // Setup UI
  textStatus = (TextView) findViewById(R.id.textStatus);
  buttonScan = (Button) findViewById(R.id.buttonScan);
  buttonScan.setOnClickListener(this);

  // Setup WiFi
  wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);

  // Get WiFi status
  WifiInfo info = wifi.getConnectionInfo();
  textStatus.append("\n\nWiFi Status: " + info.toString());

  // List available networks
  List<WifiConfiguration> configs = wifi.getConfiguredNetworks();
  for (WifiConfiguration config : configs) {
   textStatus.append("\n\n" + config.toString());
  }
  
  // Register Broadcast Receiver
  if (receiver == null)
   receiver = new WiFiScanReceiver(this);

  registerReceiver(receiver, new IntentFilter(
    WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
  Log.d(TAG, "onCreate()");
 }

 @Override
 public void onStop() {
  super.onStart();
  unregisterReceiver(receiver);
 }

 public void onClick(View view) {
  Toast.makeText(this, "On Click Clicked. Toast to that!!!",
    Toast.LENGTH_LONG).show();

  if (view.getId() == R.id.buttonScan) {
   Log.d(TAG, "onClick() wifi.startScan()");
   wifi.startScan();
  }
 }

}

这是我的广播接收器代码

package com.example;

import java.util.List;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.util.Log;
import android.widget.Toast;

public class WiFiScanReceiver extends BroadcastReceiver {
  private static final String TAG = "WiFiScanReceiver";
  WiFiDemo wifiDemo;

  public WiFiScanReceiver(WiFiDemo wifiDemo) {
    super();
    this.wifiDemo = wifiDemo;
  }

  @Override
  public void onReceive(Context c, Intent intent) {
    List<ScanResult> results = wifiDemo.wifi.getScanResults();
    ScanResult bestSignal = null;
 final String action = intent.getAction();
    if (action.equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION)) {
   System.out.println("booladsssssssssssssssssssssssssssssss");
  
  }
    for (ScanResult result : results) {
      if (bestSignal == null
          || WifiManager.compareSignalLevel(bestSignal.level, result.level) < 0)
        bestSignal = result;
    }

    String message = String.format("%s networks found. %s is the strongest.",
        results.size(), bestSignal.SSID);
    Toast.makeText(wifiDemo, message, Toast.LENGTH_LONG).show();

    Log.d(TAG, "onReceive() message: " + message);
  }

}

请发布您的WiFiDemo Activity源代码。我猜测没有注册广播接收器。但是,除非您发布源代码,否则我无法确定。 :) - Jonathan
@Jonathan,我现在更新了我的代码。。 - Gurumoorthy Arumugam
谢谢,我发布了一个答案,建议您将BroadcastReceiver实现移动到匿名类中。然后,您就不需要担心传递对WiFiDemo Activity的引用了。 - Jonathan
2个回答

2
您的接收器类没有默认构造函数,只有需要一个 WiFiDemo 的构造函数,因此 Android 无法确定如何创建该类的实例。
更新: 我认为您对广播接收器的工作原理有些困惑。有两种方式: 1. 您在 xml 中描述它,并且 Android 将在事件发生时实例化对象 - 在这种情况下,您需要一个默认构造函数,例如 public MyReceiver() {} 而不是 public MyReceiver(MyObject obj) {} 2. 您在代码中注册广播接收器。此类型可以具有任何构造函数。
因此,要解决您的问题,请删除清单中广播接收器的声明。

谢谢您的评论,您能否通过代码向我解释一下?非常感谢。 - Gurumoorthy Arumugam
@user1105375 好的,现在已经阅读了完整的代码和你所遵循的教程。已更新答案。 - tidbeck

0

Android无法实例化该类,因为构造函数需要一个WiFiDemo。

为什么不将广播接收器设为匿名的呢?

    package com.example;

    import java.util.List;

    import android.app.Activity;
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.IntentFilter;
    import android.net.wifi.WifiConfiguration;
    import android.net.wifi.WifiInfo;
    import android.net.wifi.WifiManager;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.TextView;
    import android.widget.Toast;

    public class WiFiDemo extends Activity implements OnClickListener {
     private static final String TAG = "WiFiDemo";
     WifiManager wifi;
     BroadcastReceiver receiver = new BroadcastReceiver(){
         @Override
         public void onReceive(Context c, Intent intent) {
            List<ScanResult> results = wifi.getScanResults();
            ScanResult bestSignal = null;
            final String action = intent.getAction();
            if (action.equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION)) {
               System.out.println("booladsssssssssssssssssssssssssssssss");

            }
            for (ScanResult result : results) {
                 if (bestSignal == null || WifiManager.compareSignalLevel(bestSignal.level, result.level) < 0)
                      bestSignal = result;
            }

             String message = String.format("%s networks found. %s is the strongest.",
             results.size(), bestSignal.SSID);
             Toast.makeText(wifiDemo, message, Toast.LENGTH_LONG).show();

             Log.d(TAG, "onReceive() message: " + message);
         }

     };

     TextView textStatus;
     Button buttonScan;

     /** Called when the activity is first created. */
     @Override
     public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);

      // Setup UI
      textStatus = (TextView) findViewById(R.id.textStatus);
      buttonScan = (Button) findViewById(R.id.buttonScan);
      buttonScan.setOnClickListener(this);

      // Setup WiFi
      wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);

      // Get WiFi status
      WifiInfo info = wifi.getConnectionInfo();
      textStatus.append("\n\nWiFi Status: " + info.toString());

      // List available networks
      List<WifiConfiguration> configs = wifi.getConfiguredNetworks();
      for (WifiConfiguration config : configs) {
       textStatus.append("\n\n" + config.toString());
      }

      // Register Broadcast Receiver        
      registerReceiver(receiver, new IntentFilter(
        WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
      Log.d(TAG, "onCreate()");
     }

     @Override
     public void onStop() {
      super.onStart();
      unregisterReceiver(receiver);
     }

     public void onClick(View view) {
      Toast.makeText(this, "On Click Clicked. Toast to that!!!",
        Toast.LENGTH_LONG).show();

      if (view.getId() == R.id.buttonScan) {
       Log.d(TAG, "onClick() wifi.startScan()");
       wifi.startScan();
      }
     }

    }

再次面对相同的错误 01-27 18:03:26.500: E/AndroidRuntime(19704): java.lang.RuntimeException: 无法实例化接收器 com.example.WiFiDemo: java.lang.ClassCastException: com.example.WiFiDemo 无法转换为 android.content.BroadcastReceiver - Gurumoorthy Arumugam
发现错误,移除:if (receiver == null) receiver = new WiFiScanReceiver(this); - Jonathan
请告诉我清单文件是否正确,现在我更改了问题清单。 - Gurumoorthy Arumugam
01-27 18:38:30.380: E/AndroidRuntime(24278): java.lang.RuntimeException: 无法实例化接收器 com.example.WiFiDemo:java.lang.ClassCastException:com.example.WiFiDemo 无法转换为 android.content.BroadcastReceiver - Gurumoorthy Arumugam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接