Android 2.3 WiFi热点API

问题描述:

我需要在Android 2.2(Froyo)中创建一个Wifi热点(在Tethering和Portable Hotspot设置项中看到),需要进行什么API调用。Android 2.3 WiFi热点API

+0

对不起,我创建一个使用代码中的热点,但我的电脑无法连接到它... – ericyue

+0

可能重复的[Android 2.2的wifi热点API] (https://*.com/questions/3023226/android-2-2-wifi-hotspot-api) – casualcoder

没有官方API,但您可以使用反射来处理它。我知道有人说,不建议这样做,但是我会说,如果谷歌不想提供任何API的原因,那就搞定吧。

以下是我在我的应用程序中使用的活动的代码,用户可以在其中启用/禁用Wifi AP。 当您启用Wifi AP时,通常会关闭常规Wifi,因此在用户再次禁用Wifi AP后,我们将再次启用常规WiFi。

下面的代码示例取自我的一个项目,希望您可以轻松获取逻辑。如果您还有其他问题,请告诉我。

代码在Nexus One 2.2(以及我认为也是2.3)以及Samsung Galaxy S(2.2)上进行测试。

package com.myapp.android.activity.wifi; 

import android.app.ProgressDialog; 
import android.content.Context; 
import android.net.wifi.WifiConfiguration; 
import android.net.wifi.WifiManager; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.view.View; 
import android.view.WindowManager; 
import android.widget.Button; 

import java.lang.reflect.Method; 

public class WifiAP extends BaseActivity { 

    // boolean mIsWifiEnabled = false; 
    private static final int WIFI_AP_STATE_UNKNOWN = -1; 
    private static final int WIFI_AP_STATE_DISABLING = 0; 
    private static final int WIFI_AP_STATE_DISABLED = 1; 
    private static final int WIFI_AP_STATE_ENABLING = 2; 
    private static final int WIFI_AP_STATE_ENABLED = 3; 
    private static final int WIFI_AP_STATE_FAILED = 4; 

    private final String[] WIFI_STATE_TEXTSTATE = new String[] { 
     "DISABLING","DISABLED","ENABLING","ENABLED","FAILED" 
    }; 

    private WifiManager wifi; 

    @Override 
    protected void onCreate(Bundle icicle) { 
     super.onCreate(icicle); 
     setContentView(R.layout.wifi); 
     getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD 
       |WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON 
       |WindowManager.LayoutParams.FLAG_DIM_BEHIND 
     ); 

     wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE); 
    } 

    @Override 
    public void onResume() { 
     super.onResume(); 
     updateStatusDisplay(); 
    } 

    public void toggleWifi(View v) { 
     boolean wifiApIsOn = getWifiAPState()==WIFI_AP_STATE_ENABLED || getWifiAPState()==WIFI_AP_STATE_ENABLING; 
     new SetWifiAPTask(!wifiApIsOn,false).execute(); 
    } 

    public void close(View v) { 
     boolean wifiApIsOn = getWifiAPState()==WIFI_AP_STATE_ENABLED || getWifiAPState()==WIFI_AP_STATE_ENABLING; 
     if (wifiApIsOn) { 
      new SetWifiAPTask(false,true).execute(); 
     } else { 
      finish(); 
     } 
    } 


    /** 
    * Endable/disable wifi 
    * @param enabled 
    * @return WifiAP state 
    */ 
    private int setWifiApEnabled(boolean enabled) { 
     Log.d("WifiAP", "*** setWifiApEnabled CALLED **** " + enabled); 
     if (enabled && wifi.getConnectionInfo() !=null) { 
      wifi.setWifiEnabled(false); 
      try {Thread.sleep(1500);} catch (Exception e) {} 
     } 

     //int duration = Toast.LENGTH_LONG; 
     //String toastText = "MobileAP status: "; 
     int state = WIFI_AP_STATE_UNKNOWN; 
     try { 
      wifi.setWifiEnabled(false); 
      Method method1 = wifi.getClass().getMethod("setWifiApEnabled", 
       WifiConfiguration.class, boolean.class); 
      method1.invoke(wifi, null, enabled); // true 
      Method method2 = wifi.getClass().getMethod("getWifiApState"); 
      state = (Integer) method2.invoke(wifi); 
     } catch (Exception e) { 
      Log.e(WIFI_SERVICE, e.getMessage()); 
      // toastText += "ERROR " + e.getMessage(); 
     } 

     if (!enabled) { 
      int loopMax = 10; 
      while (loopMax>0 && (getWifiAPState()==WIFI_AP_STATE_DISABLING 
        || getWifiAPState()==WIFI_AP_STATE_ENABLED 
        || getWifiAPState()==WIFI_AP_STATE_FAILED)) { 
       try {Thread.sleep(500);loopMax--;} catch (Exception e) {} 
      } 
      wifi.setWifiEnabled(true); 
     } else if (enabled) { 
      int loopMax = 10; 
      while (loopMax>0 && (getWifiAPState()==WIFI_AP_STATE_ENABLING 
        || getWifiAPState()==WIFI_AP_STATE_DISABLED 
        || getWifiAPState()==WIFI_AP_STATE_FAILED)) { 
       try {Thread.sleep(500);loopMax--;} catch (Exception e) {} 
      } 
     } 

     return state; 
    } 


    private int getWifiAPState() { 
     int state = WIFI_AP_STATE_UNKNOWN; 
     try { 
      Method method2 = wifi.getClass().getMethod("getWifiApState"); 
      state = (Integer) method2.invoke(wifi); 
     } catch (Exception e) {} 
     Log.d("WifiAP", "getWifiAPState.state " + (state==-1?"UNKNOWN":WIFI_STATE_TEXTSTATE[state])); 
     return state; 
    } 

    private void updateStatusDisplay() { 

     if (getWifiAPState()==WIFI_AP_STATE_ENABLED || getWifiAPState()==WIFI_AP_STATE_ENABLING) { 
      ((Button)findViewById(R.id.btnWifiToggle)).setText("Turn off"); 
      findViewById(R.id.bg).setBackgroundResource(R.drawable.bg_wifi_on); 
     } else { 
      ((Button)findViewById(R.id.btnWifiToggle)).setText("Turn on"); 
      findViewById(R.id.bg).setBackgroundResource(R.drawable.bg_wifi_off); 
     } 

    } 


    class SetWifiAPTask extends AsyncTask<Void, Void, Void> { 

     boolean mMode; 
     boolean mFinish; 

     public SetWifiAPTask(boolean mode, boolean finish) { 
      mMode = mode; 
      mFinish = finish; 
     } 

     ProgressDialog d = new ProgressDialog(WifiAP.this); 

     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 
      d.setTitle("Turning WiFi AP " + (mMode?"on":"off") + "..."); 
      d.setMessage("...please wait a moment."); 
      d.show(); 
     } 

     @Override 
     protected void onPostExecute(Void aVoid) { 
      super.onPostExecute(aVoid); 
      try {d.dismiss();} catch (IllegalArgumentException e) {}; 
      updateStatusDisplay(); 
      if (mFinish) finish(); 
     } 

     @Override 
     protected Void doInBackground(Void... params) { 
      setWifiApEnabled(mMode); 
      return null; 
     } 
    } 


} 
+0

我会试试看。 THKS。 – ericyue

+0

什么是BaseActivity? – ericyue

+1

忽略BaseActivity,这只是一个从Activity扩展而来的自定义类,与该示例无关。 –

这里没有公共的API。

有兴趣的人得到这个工作的ICS,设置你的AP名称,和/或保持所有WifiAP代码在自己的班级我向在对方的回答给定的代码更新和改进:

WifiAP.java:

package com.demo.wifiap; 

import android.app.Activity; 
import android.app.ProgressDialog; 
import android.content.Context; 
import android.net.wifi.WifiConfiguration; 
import android.net.wifi.WifiManager; 
import android.os.AsyncTask; 
import android.util.Log; 

import java.lang.reflect.Method; 

import com.demo.WifiAPActivity; 

/** 
* Handle enabling and disabling of WiFi AP 
* @author http://*.com/a/7049074/1233435 
*/ 
public class WifiAP extends Activity { 
    private static int constant = 0; 

    private static final int WIFI_AP_STATE_UNKNOWN = -1; 
    private static int WIFI_AP_STATE_DISABLING = 0; 
    private static int WIFI_AP_STATE_DISABLED = 1; 
    public int WIFI_AP_STATE_ENABLING = 2; 
    public int WIFI_AP_STATE_ENABLED = 3; 
    private static int WIFI_AP_STATE_FAILED = 4; 

    private final String[] WIFI_STATE_TEXTSTATE = new String[] { 
      "DISABLING","DISABLED","ENABLING","ENABLED","FAILED" 
    }; 

    private WifiManager wifi; 
    private String TAG = "WifiAP"; 

    private int stateWifiWasIn = -1; 

    private boolean alwaysEnableWifi = true; //set to false if you want to try and set wifi state back to what it was before wifi ap enabling, true will result in the wifi always being enabled after wifi ap is disabled 

    /** 
    * Toggle the WiFi AP state 
    * @param wifihandler 
    * @author http://*.com/a/7049074/1233435 
    */ 
    public void toggleWiFiAP(WifiManager wifihandler, Context context) { 
     if (wifi==null){ 
      wifi = wifihandler; 
     } 

     boolean wifiApIsOn = getWifiAPState()==WIFI_AP_STATE_ENABLED || getWifiAPState()==WIFI_AP_STATE_ENABLING; 
     new SetWifiAPTask(!wifiApIsOn,false,context).execute(); 
    } 

    /** 
    * Enable/disable wifi 
    * @param true or false 
    * @return WifiAP state 
    * @author http://*.com/a/7049074/1233435 
    */ 
    private int setWifiApEnabled(boolean enabled) { 
     Log.d(TAG, "*** setWifiApEnabled CALLED **** " + enabled); 

     WifiConfiguration config = new WifiConfiguration(); 
     config.SSID = "My AP"; 
     config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN); 

     //remember wirelesses current state 
     if (enabled && stateWifiWasIn==-1){ 
      stateWifiWasIn=wifi.getWifiState(); 
     } 

     //disable wireless 
     if (enabled && wifi.getConnectionInfo() !=null) { 
      Log.d(TAG, "disable wifi: calling"); 
      wifi.setWifiEnabled(false); 
      int loopMax = 10; 
      while(loopMax>0 && wifi.getWifiState()!=WifiManager.WIFI_STATE_DISABLED){ 
       Log.d(TAG, "disable wifi: waiting, pass: " + (10-loopMax)); 
       try { 
        Thread.sleep(500); 
        loopMax--; 
       } catch (Exception e) { 

       } 
      } 
      Log.d(TAG, "disable wifi: done, pass: " + (10-loopMax)); 
     } 

     //enable/disable wifi ap 
     int state = WIFI_AP_STATE_UNKNOWN; 
     try { 
      Log.d(TAG, (enabled?"enabling":"disabling") +" wifi ap: calling"); 
      wifi.setWifiEnabled(false); 
      Method method1 = wifi.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class); 
      //method1.invoke(wifi, null, enabled); // true 
      method1.invoke(wifi, config, enabled); // true 
      Method method2 = wifi.getClass().getMethod("getWifiApState"); 
      state = (Integer) method2.invoke(wifi); 
     } catch (Exception e) { 
      Log.e(WIFI_SERVICE, e.getMessage()); 
      // toastText += "ERROR " + e.getMessage(); 
     } 


     //hold thread up while processing occurs 
     if (!enabled) { 
      int loopMax = 10; 
      while (loopMax>0 && (getWifiAPState()==WIFI_AP_STATE_DISABLING || getWifiAPState()==WIFI_AP_STATE_ENABLED || getWifiAPState()==WIFI_AP_STATE_FAILED)) { 
       Log.d(TAG, (enabled?"enabling":"disabling") +" wifi ap: waiting, pass: " + (10-loopMax)); 
       try { 
        Thread.sleep(500); 
        loopMax--; 
       } catch (Exception e) { 

       } 
      } 
      Log.d(TAG, (enabled?"enabling":"disabling") +" wifi ap: done, pass: " + (10-loopMax)); 

      //enable wifi if it was enabled beforehand 
      //this is somewhat unreliable and app gets confused and doesn't turn it back on sometimes so added toggle to always enable if you desire 
      if(stateWifiWasIn==WifiManager.WIFI_STATE_ENABLED || stateWifiWasIn==WifiManager.WIFI_STATE_ENABLING || stateWifiWasIn==WifiManager.WIFI_STATE_UNKNOWN || alwaysEnableWifi){ 
       Log.d(TAG, "enable wifi: calling"); 
       wifi.setWifiEnabled(true); 
       //don't hold things up and wait for it to get enabled 
      } 

      stateWifiWasIn = -1; 
     } else if (enabled) { 
      int loopMax = 10; 
      while (loopMax>0 && (getWifiAPState()==WIFI_AP_STATE_ENABLING || getWifiAPState()==WIFI_AP_STATE_DISABLED || getWifiAPState()==WIFI_AP_STATE_FAILED)) { 
       Log.d(TAG, (enabled?"enabling":"disabling") +" wifi ap: waiting, pass: " + (10-loopMax)); 
       try { 
        Thread.sleep(500); 
        loopMax--; 
       } catch (Exception e) { 

       } 
      } 
      Log.d(TAG, (enabled?"enabling":"disabling") +" wifi ap: done, pass: " + (10-loopMax)); 
     } 
     return state; 
    } 

    /** 
    * Get the wifi AP state 
    * @return WifiAP state 
    * @author http://*.com/a/7049074/1233435 
    */ 
    public int getWifiAPState() { 
     int state = WIFI_AP_STATE_UNKNOWN; 
     try { 
      Method method2 = wifi.getClass().getMethod("getWifiApState"); 
      state = (Integer) method2.invoke(wifi); 
     } catch (Exception e) { 

     } 

     if(state>=10){ 
      //using Android 4.0+ (or maybe 3+, haven't had a 3 device to test it on) so use states that are +10 
      constant=10; 
     } 

     //reset these in case was newer device 
     WIFI_AP_STATE_DISABLING = 0+constant; 
     WIFI_AP_STATE_DISABLED = 1+constant; 
     WIFI_AP_STATE_ENABLING = 2+constant; 
     WIFI_AP_STATE_ENABLED = 3+constant; 
     WIFI_AP_STATE_FAILED = 4+constant; 

     Log.d(TAG, "getWifiAPState.state " + (state==-1?"UNKNOWN":WIFI_STATE_TEXTSTATE[state-constant])); 
     return state; 
    } 

    /** 
    * the AsyncTask to enable/disable the wifi ap 
    * @author http://*.com/a/7049074/1233435 
    */ 
    class SetWifiAPTask extends AsyncTask<Void, Void, Void> { 
     boolean mMode; //enable or disable wifi AP 
     boolean mFinish; //finalize or not (e.g. on exit) 
     ProgressDialog d; 

     /** 
     * enable/disable the wifi ap 
     * @param mode enable or disable wifi AP 
     * @param finish finalize or not (e.g. on exit) 
     * @param context the context of the calling activity 
     * @author http://*.com/a/7049074/1233435 
     */ 
     public SetWifiAPTask(boolean mode, boolean finish, Context context) { 
      mMode = mode; 
      mFinish = finish; 
      d = new ProgressDialog(context); 
     } 

     /** 
     * do before background task runs 
     * @author http://*.com/a/7049074/1233435 
     */ 
     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 
      d.setTitle("Turning WiFi AP " + (mMode?"on":"off") + "..."); 
      d.setMessage("...please wait a moment."); 
      d.show(); 
     } 

     /** 
     * do after background task runs 
     * @param aVoid 
     * @author http://*.com/a/7049074/1233435 
     */ 
     @Override 
     protected void onPostExecute(Void aVoid) { 
      super.onPostExecute(aVoid); 
      try { 
       d.dismiss(); 
       WifiAPActivity.updateStatusDisplay(); 
      } catch (IllegalArgumentException e) { 

      }; 
      if (mFinish){ 
       finish(); 
      } 
     } 

     /** 
     * the background task to run 
     * @param params 
     * @author http://*.com/a/7049074/1233435 
     */ 
     @Override 
     protected Void doInBackground(Void... params) { 
      setWifiApEnabled(mMode); 
      return null; 
     } 
    } 
} 

WifiAPActivity.java:

package com.demo; 

import android.app.Activity; 
import android.content.Context; 
import android.net.wifi.WifiManager; 
import android.os.Bundle; 
import android.view.View; 
import android.view.WindowManager; 
import android.widget.Button; 

import com.demo.WifiAP; 

public class WifiAPActivity extends Activity { 
    //private String TAG = "WifiAPActivity"; 

    boolean wasAPEnabled = false; 
    static WifiAP wifiAp; 
    private WifiManager wifi; 
    static Button btnWifiToggle; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.wifi); 

     btnWifiToggle = (Button) findViewById(R.id.btnWifiToggle); 

     wifiAp = new WifiAP(); 
     wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE); 

     btnWifiToggle.setOnClickListener(new View.OnClickListener() { 
      public void onClick(View v) { 
       wifiAp.toggleWiFiAP(wifi, WifiAPActivity.this); 
      } 
     }); 

     getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD|WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON|WindowManager.LayoutParams.FLAG_DIM_BEHIND);  
    } 

    @Override 
    public void onResume() { 
     super.onResume(); 
     if (wasAPEnabled) { 
      if (wifiAp.getWifiAPState()!=wifiAp.WIFI_AP_STATE_ENABLED && wifiAp.getWifiAPState()!=wifiAp.WIFI_AP_STATE_ENABLING){ 
       wifiAp.toggleWiFiAP(wifi, WifiAPActivity.this); 
      } 
     } 
     updateStatusDisplay(); 
    } 

    @Override 
    public void onPause() { 
     super.onPause(); 
     boolean wifiApIsOn = wifiAp.getWifiAPState()==wifiAp.WIFI_AP_STATE_ENABLED || wifiAp.getWifiAPState()==wifiAp.WIFI_AP_STATE_ENABLING; 
     if (wifiApIsOn) { 
      wasAPEnabled = true; 
      wifiAp.toggleWiFiAP(wifi, WifiAPActivity.this); 
     } else { 
      wasAPEnabled = false; 
     } 
     updateStatusDisplay(); 
    } 

    public static void updateStatusDisplay() { 
     if (wifiAp.getWifiAPState()==wifiAp.WIFI_AP_STATE_ENABLED || wifiAp.getWifiAPState()==wifiAp.WIFI_AP_STATE_ENABLING) { 
      btnWifiToggle.setText("Turn off"); 
      //findViewById(R.id.bg).setBackgroundResource(R.drawable.bg_wifi_on); 
     } else { 
      btnWifiToggle.setText("Turn on"); 
      //findViewById(R.id.bg).setBackgroundResource(R.drawable.bg_wifi_off); 
     } 
    } 
} 

WIF i.xml:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:orientation="vertical" > 

    <Button 
     android:id="@+id/btnWifiToggle" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="Button" /> 

</LinearLayout> 

权限:

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission> 
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission> 
+1

@mathias谢谢!这工作直接复制和粘贴我的LG C710h,我可以看到我的电脑上的网络。我在一个Galexy S II上试了一下,它是wpa_supplicant我修补过的,可以检测ad hoc网络,但它不能马上工作(可能是补丁)。 – methodMan

+0

@bbodenmiller你的代码工作的很好,但你能告诉我如何使用热点共享文件 – Kunu

+0

你应该使用套接字@Kunu – gumuruh