【问题标题】:Android: Programmatically Turn on WiFi hotspotAndroid:以编程方式打开 WiFi 热点
【发布时间】:2014-11-04 03:52:55
【问题描述】:

我正在尝试打开便携式 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


因此我有以下问题:

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

【问题讨论】:

标签: java android android-wifi tethering


【解决方案1】:

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

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

这适用于 4.1.1、4.2 和 4.3 版本。

【讨论】:

    【解决方案2】:

    试试这个代码。我在 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" />
    

    【讨论】:

      【解决方案3】:

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

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

      否则会崩溃并重启设备。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-09-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-09
        • 2016-03-25
        • 1970-01-01
        相关资源
        最近更新 更多