Android:以编程方式启用WiFi热点

时间:2014-09-10 13:14:11

标签: java android android-wifi tethering

我试图通过引用此链接打开便携式Wifi热点:
how to set advanced settings of android wifihotspot

这在三星Galaxy S3 Android v4.4.2上运行良好。(没有问题)
但是在具有相同或更低Android版本的其他设备上,应用程序崩溃并重新启动设备
代码如下:

package com.android.startwifi;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import android.app.Activity;
import android.content.Context;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;


public class Main extends Activity {

public WifiManager wifiManager;
public Context context;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Log.i("hi1","hi");
    createWifiAccessPoint();
}
private void createWifiAccessPoint() {
    WifiManager wifiManager = (WifiManager)getBaseContext().getSystemService(Context.WIFI_SERVICE);
    if(wifiManager.isWifiEnabled())
    {
        wifiManager.setWifiEnabled(false);          
    }       
    Method[] wmMethods = wifiManager.getClass().getDeclaredMethods();  
    boolean methodFound=false;
    for(Method method: wmMethods){
        if(method.getName().equals("setWifiApEnabled")){
            methodFound=true;
            WifiConfiguration netConfig = new WifiConfiguration();
            netConfig.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
            netConfig.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
            netConfig.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
            netConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
            netConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
            netConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
            netConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
            netConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
            try {
                boolean apstatus=(Boolean) method.invoke(wifiManager, netConfig,true);          
                //statusView.setText("Creating a Wi-Fi Network \""+netConfig.SSID+"\"");
                for (Method isWifiApEnabledmethod: wmMethods)
                {
                    if(isWifiApEnabledmethod.getName().equals("isWifiApEnabled")){
                        while(!(Boolean)isWifiApEnabledmethod.invoke(wifiManager)){
                        };
                        for(Method method1: wmMethods){
                            if(method1.getName().equals("getWifiApState")){
                                int apstate;
                                apstate=(Integer)method1.invoke(wifiManager);
                                //                    netConfig=(WifiConfiguration)method1.invoke(wifi);
                                //statusView.append("\nSSID:"+netConfig.SSID+"\nPassword:"+netConfig.preSharedKey+"\n");
                            }
                        }
                    }
                }
                if(apstatus)
                {
                    System.out.println("SUCCESSdddd");  
                    //statusView.append("\nAccess Point Created!");
                    //finish();
                    //Intent searchSensorsIntent = new Intent(this,SearchSensors.class);            
                    //startActivity(searchSensorsIntent);
                }else
                {
                    System.out.println("FAILED");   
                    //statusView.append("\nAccess Point Creation failed!");
                }
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }      
    }
    if(!methodFound){
        //statusView.setText("Your phone's API does not contain setWifiApEnabled method to configure an access point");
    }
}  

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}
}


我在清单文件中定义的权限是:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>


生成的日志文件如下:

09-10 18:35:01.644: D/jdwp(29752): prepping for JDWP over ADB
09-10 18:35:01.644: D/jdwp(29752): ADB transport startup
09-10 18:35:01.644: D/dalvikvm(29752): Elevating priority from 0 to -8
09-10 18:35:01.645: D/jdwp(29752): JDWP: thread running
09-10 18:35:01.645: D/jdwp(29752): acceptConnection
09-10 18:35:01.646: D/jdwp(29752): trying to receive file descriptor from ADB
09-10 18:35:01.646: D/dalvikvm(29752): zygote get thread init done
09-10 18:35:01.653: D/jdwp(29752): received file descriptor 34 from ADB
09-10 18:35:01.658: D/jdwp(29752): processIncoming
09-10 18:35:01.659: D/jdwp(29752): processIncoming
09-10 18:35:01.659: D/jdwp(29752): handlePacket : cmd=0x1, cmdSet=0xC7, len=0x13, id=0x40000040, flags=0x0, dataLen=0x8
09-10 18:35:01.661: D/jdwp(29752): processIncoming
09-10 18:35:01.661: D/jdwp(29752): handlePacket : cmd=0x1, cmdSet=0xC7, len=0x17, id=0x40000041, flags=0x0, dataLen=0xC
09-10 18:35:01.663: D/jdwp(29752): processIncoming
09-10 18:35:01.663: D/jdwp(29752): handlePacket : cmd=0x1, cmdSet=0xC7, len=0x13, id=0x40000042, flags=0x0, dataLen=0x8
09-10 18:35:01.665: D/jdwp(29752): processIncoming
09-10 18:35:01.665: D/jdwp(29752): handlePacket : cmd=0x1, cmdSet=0xC7, len=0x13, id=0x40000043, flags=0x0, dataLen=0x8
09-10 18:35:01.676: D/jdwp(29752): sendBufferedRequest : len=0x3D
09-10 18:35:01.736: D/jdwp(29752): sendBufferedRequest : len=0x45
09-10 18:35:01.754: W/asset(29752): AssetManager-->addDefaultAssets CIP path not exsit!
09-10 18:35:02.219: I/hi1(29752): hi
09-10 18:35:02.261: D/WifiManager(29752): Enter init, sThreadRefCount:0
09-10 18:35:02.268: D/WifiManager(29752): Create WifiManager handlerthread
09-10 18:35:03.599: I/System.out(29752): SUCCESSdddd
09-10 18:35:03.634: V/PhoneWindow(29752): DecorView setVisiblity: visibility = 4
09-10 18:35:03.745: V/PhoneWindow(29752): DecorView setVisiblity: visibility = 0
09-10 18:35:03.922: D/libEGL(29752): loaded /system/lib/egl/libEGL_mali.so
09-10 18:35:03.924: D/libEGL(29752): loaded /system/lib/egl/libGLESv1_CM_mali.so
09-10 18:35:03.927: D/libEGL(29752): loaded /system/lib/egl/libGLESv2_mali.so
09-10 18:35:04.111: D/OpenGLRenderer(29752): Enabling debug mode 0
09-10 18:35:10.610: E/InputEventReceiver(29752): channel '41f21f48 com.android.startwifi/com.android.startwifi.Main (client)' ~ Publisher closed input channel or an error occurred.  events=0x9


因此,我有以下问题:

  • 我想知道为什么这个应用程序在Samsung S3上正常运行 但不在其他设备上?
  • 如何解决此问题?

3 个答案:

答案 0 :(得分:3)

我有同样的问题。您必须删除以下代码行:

netConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);    

在版本4.1.1,4.2和4.3中对我有用。

答案 1 :(得分:0)

试试这个代码。我在android 5.0.1中测试:

      public boolean setHotSpot(String SSID,String passWord){
        Method[] mMethods = mWifiManager.getClass().getDeclaredMethods();

        for(Method mMethod: mMethods){

            if(mMethod.getName().equals("setWifiApEnabled")) {
                WifiConfiguration netConfig = new WifiConfiguration();
                if(passWord==""){
                    netConfig.SSID = SSID;
                    netConfig.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
                    netConfig.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
                    netConfig.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
                    netConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);     
                }else{
                netConfig.SSID = SSID ;
                netConfig.preSharedKey = passWord;
                netConfig.hiddenSSID = true;
                netConfig.status = WifiConfiguration.Status.ENABLED;
                netConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
                netConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
                netConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
                netConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
                netConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
                netConfig.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
                netConfig.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
                }
                try {              
                    mMethod.invoke(mWifiManager, netConfig,false);
                    mWifiManager.saveConfiguration();
                    return true;

                } catch (Exception e) {
                  e.getMessage();
                }
            }
        }
        return false; 
  }

在AndroidManifest中插入此权限:

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />

答案 2 :(得分:0)

如果您使用WPA_PSK身份验证,则必须指定preSharedKey。

        netConfig.preSharedKey = "testPassword";
        netConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);

否则会崩溃并重启设备。