androidwifimanager

How to turn on hotspot by WifiManager.LocalOnlyHotspotCallback


I need to turn on a device hotspot from inside an app. To do so, I have used WifiManager.LocalOnlyHotspotCallback (see detail here)

On android 8, it first shows a dialog box as "the app has stopped", and after clicking close app, the page setting/general management is shown for a second. However, on android 12, it never shows any thing and is closed automatically.

Does anyone know how I can get it running (either on android 8 or 12)? Thanks in advance. Here is my code in MainActivity.java:

package io.ionic.starter;
import android.Manifest;
import android.content.pm.PackageManager;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Handler; 
import androidx.core.app.ActivityCompat;
import com.getcapacitor.BridgeActivity;

public class MainActivity extends BridgeActivity {
  public static int MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1;
  private WifiManager wifiManager;
  private WifiManager.LocalOnlyHotspotReservation hotspotReservation;

  @Override
  public void onStart() { 
    super.onStart();
    turnOnHotspot();
  }
  private void turnOnHotspot() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
      requestPermissions( new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
      MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
    }
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
      // TODO: Consider calling
      //    ActivityCompat#requestPermissions
      // here to request the missing permissions, and then overriding
      //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
      //                                          int[] grantResults)
      // to handle the case where the user grants the permission. See the documentation
      // for ActivityCompat#requestPermissions for more details.

      return;
    }
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
      wifiManager.startLocalOnlyHotspot(new
        WifiManager.LocalOnlyHotspotCallback() {
        @Override
        public void onStarted(WifiManager.LocalOnlyHotspotReservation reservation) {
          super.onStarted(reservation);
          hotspotReservation = reservation;
          String key = hotspotReservation.getWifiConfiguration().preSharedKey;
          String ussid = hotspotReservation.getWifiConfiguration().SSID;
          System.out.println("KEY: " + key);
          System.out.println("USSID: " + ussid);
          System.out.println("STARTED THE HOTSPOT");
        }

        @Override
        public void onStopped() {
          super.onStopped();
          System.out.println("STOPPED THE HOTSPOT");
        }

        @Override
        public void onFailed(int reason) {
          super.onFailed(reason);
          System.out.println("FAILED THE HOTSPOT");
        }
        }, new Handler());
    }
  }  
}

Solution

  • Looking into the logcat I realized I am getting an error which says:

    LocalOnlyHotspotCallback() is called by a null object.

    Which means WifiManager is not defined correctly! Thanks to this answer I could solve the problem by defining the object like this:

    WifiManager manager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
    

    So here is the whole code that works on android 8:

    package io.ionic.starter;    
    import android.Manifest;
    import android.content.Context;
    import android.content.pm.PackageManager;
    import android.net.wifi.WifiManager;
    import android.os.Build;
    import android.os.Handler; 
    import androidx.annotation.RequiresApi;
    import androidx.core.app.ActivityCompat;    
    import com.getcapacitor.BridgeActivity;
    
    public class MainActivity extends BridgeActivity {
      private WifiManager.LocalOnlyHotspotReservation mReservation;
      @Override
      public void onStart() { 
        super.onStart();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
           turnOnHotspot();
        }
      }
    
      @RequiresApi(api = Build.VERSION_CODES.O)
      private void turnOnHotspot() {
        WifiManager manager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
    
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
          // TODO: Consider calling
          //    ActivityCompat#requestPermissions
          // here to request the missing permissions, and then overriding
          //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
          //                                          int[] grantResults)
          // to handle the case where the user grants the permission. See the documentation
          // for ActivityCompat#requestPermissions for more details.
          return;
        }
        manager.startLocalOnlyHotspot(new WifiManager.LocalOnlyHotspotCallback() {
    
          @Override
          public void onStarted(WifiManager.LocalOnlyHotspotReservation reservation) {
            super.onStarted(reservation);
            mReservation = reservation;
          }
    
          @Override
          public void onStopped() {
            super.onStopped();    
          }
    
          @Override
          public void onFailed(int reason) {
            super.onFailed(reason);    
          }
        }, new Handler());
      }
    
      private void turnOffHotspot() {
        if (mReservation != null) {
          mReservation.close();
        }
      }
    }