Mobile Hotspot on and off Android on Marshmallow - android

I want turn on or off Mobile Hotspot by pressing a button On or button Off .I have written this code for setOnClickListner and Given Permission in Manifest File.But i am not able to turn on Mobile Hotspot.I just want to turn mobile hotspot On without any configuration of hotspot or mobile data.My android Os version is Marshmellow.
btnHotspotOn.setOnClickListener(new View.OnClickListener() {
#Override
#SuppressLint("WifiManagerLeak")
public void onClick(View v) {
try {
WifiManager manager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
Method method = manager.getClass().getDeclaredMethod("setWifiApEnabled", WifiConfiguration.class,
Boolean.TYPE);
method.setAccessible(true);
boolean enable =true;
WifiConfiguration configuration = null;
method.invoke(manager, configuration, enable);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
});
Following is the Manifest File:-
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>

Related

How to turn on/off wifi hotspot programmatically in Android 8.0 (Oreo)

I know how to turn on/off wifi hot spot using reflection in android using below method.
private static boolean changeWifiHotspotState(Context context,boolean enable) {
try {
WifiManager manager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
Method method = manager.getClass().getDeclaredMethod("setWifiApEnabled", WifiConfiguration.class,
Boolean.TYPE);
method.setAccessible(true);
WifiConfiguration configuration = enable ? getWifiApConfiguration(manager) : null;
boolean isSuccess = (Boolean) method.invoke(manager, configuration, enable);
return isSuccess;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
But the above method is not working Android 8.0(Oreo).
When I execute above method in Android 8.0, I am getting below statement in logcat.
com.gck.dummy W/WifiManager: com.gck.dummy attempted call to setWifiApEnabled: enabled = true
Is there any other way to on/off hotspot on android 8.0
I thought the LocalOnlyHotspot route was the way to, but as #edsappfactory.com said in the comments - it only gives closed network, no internet access.
In Oreo hot-spotting/tethering moved to ConnectionManager, and its annotated #SystemApi, so (nominally) inaccessible.
As part of something else I was doing, I made an app and put it on github here. It uses reflection to get at the function and DexMaker to generate a subclass of ConnectionManager.OnStartTetheringCallback (which is also inaccessible).
Think it all works okay - bit rough around the edges, so please feel free to make better!
Relevant bits of code are in:
MyOreoWifiManager and;
CallbackMaker
I lost patience trying to get my DexMaker-generated callback to fire the MyOnStartTetheringCallback so all that code is in disarray and commented out.
Finally I got the solution.
Android 8.0, they provided public api to turn on/off hotspot. WifiManager
Below is the code to turn on hotspot
private WifiManager.LocalOnlyHotspotReservation mReservation;
#RequiresApi(api = Build.VERSION_CODES.O)
private void turnOnHotspot() {
WifiManager manager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
manager.startLocalOnlyHotspot(new WifiManager.LocalOnlyHotspotCallback() {
#Override
public void onStarted(WifiManager.LocalOnlyHotspotReservation reservation) {
super.onStarted(reservation);
Log.d(TAG, "Wifi Hotspot is on now");
mReservation = reservation;
}
#Override
public void onStopped() {
super.onStopped();
Log.d(TAG, "onStopped: ");
}
#Override
public void onFailed(int reason) {
super.onFailed(reason);
Log.d(TAG, "onFailed: ");
}
}, new Handler());
}
private void turnOffHotspot() {
if (mReservation != null) {
mReservation.close();
}
}
onStarted(WifiManager.LocalOnlyHotspotReservation reservation) method will be called if hotspot is turned on.. Using WifiManager.LocalOnlyHotspotReservation reference you call close() method to turn off hotspot.
Note:
To turn on hotspot, the Location(GPS) should be enabled in the device. Otherwise, it will throw SecurityException
As per Jon suggestion, I got another way to enable WifiHotSpot in Android Oreo and above.
public boolean enableTetheringNew(MyTetheringCallback callback) {
File outputDir = mContext.getCodeCacheDir();
try {
proxy = ProxyBuilder.forClass(classOnStartTetheringCallback())
.dexCache(outputDir).handler(new InvocationHandler() {
#Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
switch (method.getName()) {
case "onTetheringStarted":
callback.onTetheringStarted();
break;
case "onTetheringFailed":
callback.onTetheringFailed();
break;
default:
ProxyBuilder.callSuper(proxy, method, args);
}
return null;
}
}).build();
} catch (IOException e) {
e.printStackTrace();
}
ConnectivityManager manager = (ConnectivityManager) mContext.getApplicationContext().getSystemService(ConnectivityManager.class);
Method method = null;
try {
method = manager.getClass().getDeclaredMethod("startTethering", int.class, boolean.class, classOnStartTetheringCallback(), Handler.class);
if (method == null) {
Log.e(TAG, "startTetheringMethod is null");
} else {
method.invoke(manager, TETHERING_WIFI, false, proxy, null);
}
return true;
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return false;
}
private Class classOnStartTetheringCallback() {
try {
return Class.forName("android.net.ConnectivityManager$OnStartTetheringCallback");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}

Can't access socket from external device on Android

I wrote a simple HTTP-Proxy for Android which is listening on the device external IP Address and a specific port (e.g. 192.168.1.20:8080).
I can access IP/port from the device itself - but any tries from external devices will never be accepted in the run-loop.
The simplified code looks like this:
public class MainActivity extends AppCompatActivity implements Runnable {
private ServerSocket socket;
private int port = 8080;
private Thread thread;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WifiManager wm = (WifiManager) getSystemService(Context.WIFI_SERVICE);
String ip = Formatter.formatIpAddress(wm.getConnectionInfo().getIpAddress());
Log.v("TAG", "http://"+ip+":"+port);
try {
Log.v("TAG", InetAddress.getByName(ip).toString());
socket = new ServerSocket(port, 5, InetAddress.getByName(ip));
socket.setSoTimeout(5000);
thread = new Thread(this);
thread.start();
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void run() {
while (true) {
try {
Socket client = socket.accept();
// Never reaches this line if connected externally
Log.d("TAG", "client connected");
} catch (SocketTimeoutException e) {
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
I also added the permissions in AndroidManifest.xml:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
But still no luck. Anybody out there who can give advise?
Thx.

How to create access point programmatically

I've written the code to create an access point for android devices. I've tested on both emulator and real device.But it doesn't work. Where did i get wrong?
public class MainWAP extends Activity {
WifiManager wifiManager;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_wap);
}
public void openWifi(View v) {
createWifiAccessPoint();
}
private void createWifiAccessPoint() {
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.SSID = "AccessPoint";
netConfig.allowedAuthAlgorithms.set(
WifiConfiguration.AuthAlgorithm.OPEN);
try {
boolean apstatus = (Boolean) method.invoke(
wifiManager, netConfig, true);
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);
}
}
}
}
if (apstatus) {
Log.d("Splash Activity",
"Access Point created");
} else {
Log.d("Splash Activity",
"Access Point creation failed");
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
if (!methodFound) {
Log.d("Splash Activity",
"cannot configure an access point");
}
}
}
Your WiFiManager is definately not initialized.
In your onCreate method add this:
wifiManager = (WiFiManager) getSystemService(Context.WIFI_SERVICE);
You need few things to make this code to work.
1) Init wifiManager onCreate() :
WifiManager wifiManager = (WiFiManager) getSystemService(Context.WIFI_SERVICE);
2) You need to ask for this permissions in you AndroidManifest.xml :
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.WRITE_APN_SETTINGS" />
3) Your application need to be signed with system certificates.
With your method of exploiting undocumented APIs using reflection, things might not work well in all scenarios.
Well, you can try adding these in your manifest file and give a try.
android.permission.ACCESS_WIFI_STATE
android.permission.CHANGE_WIFI_STATE
android.permission.WRITE_APN_SETTINGS

Start / stop built-in Wi-Fi / USB tethering from code?

How can I start or stop the built-in tethering in Android 2.2 from my application?
There is a non-public Tethering API in the ConnectivityManager. As shown above you can use reflection to access it. I tried this on a number of Android 2.2 phones, and it works on all of them (my HTC turns on tethering but does NOT show this in the status bar..., so check from the other end). Below is some rough code which emits debugging stuff and turns on tethering on usb0.
ConnectivityManager cman = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
Method[] methods = cman.getClass().getDeclaredMethods();
for (Method method : methods) {
if (method.getName().equals("getTetherableIfaces")) {
try {
String[] ifaces = (String[]) method.invoke(cman);
for (String iface : ifaces) {
Log.d("TETHER", "Tether available on " + iface);
}
} catch (Exception e) {
e.printStackTrace();
}
}
if (method.getName().equals("isTetheringSupported")) {
try {
boolean supported = (Boolean) method.invoke(cman);
Log.d("TETHER", "Tether is supported: " + (supported ? "yes" : "no"));
} catch (Exception e) {
e.printStackTrace();
}
}
if (method.getName().equals("tether")) {
Log.d("TETHER", "Starting tether usb0");
try {
int result = (Integer) method.invoke(cman, "usb0");
Log.d("TETHER", "Tether usb0 result: " + result);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Please note: this code requires the following permissions to work:
android.permission.ACCESS_NETWORK_STATE
android.permission.CHANGE_NETWORK_STATE
I answered this question here. In short, it is possible, here is the code:
private void setWifiTetheringEnabled(boolean enable) {
WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
Method[] methods = wifiManager.getClass().getDeclaredMethods();
for (Method method : methods) {
if (method.getName().equals("setWifiApEnabled")) {
try {
method.invoke(wifiManager, null, enable);
} catch (Exception ex) {
}
break;
}
}
}
Your app should have the following permission:
android.permission.CHANGE_WIFI_STATE
There are no public APIs in the Android SDK for managing the tethering -- sorry!
I used the code from Android How to turn on hotspot in Android Programmatically! and I enable the portable hotspot for android 4.2. Here's the code.
WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
// TODO Auto-generated method stub
WifiConfiguration wifi_configuration = null;
wifiManager.setWifiEnabled(false);
try
{
//USE REFLECTION TO GET METHOD "SetWifiAPEnabled"
Method method=wifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);
method.invoke(wifiManager, wifi_configuration, true);
}
catch (NoSuchMethodException e){
// TODO Auto-generated catch block
e.printStackTrace();
}catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

Trouble in Enabling and Disabling services in Android

I am new to Android development and have trouble enabling / disabling the wifi & audio services. I get the appropriate manager instance using the getSystemService method. But I don't get any error when enabling wifi using:
wifiMgr.setWifiEnabled(true);
But the wifi is simply not turned on! Similarly I use
mAudio.setRingerMode(AudioManager.RINGER_MODE_SILENT);
or
mAudio.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
But the phone doesn't go to silent mode! Here is my complete code:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try{
final ToggleButton bt = (ToggleButton)findViewById(R.id.bluetooth_button);
final ToggleButton wf = (ToggleButton)findViewById(R.id.wifi_button);
final ToggleButton sb = (ToggleButton)findViewById(R.id.sound_button);
// Check Audio
AudioManager mAudio = (AudioManager) getSystemService(Activity.AUDIO_SERVICE);
soundStatus = mAudio.getRingerMode();
if(soundStatus == AudioManager.RINGER_MODE_NORMAL)
sb.setChecked(true);
// Check WiFi
WifiManager wifiMgr = (WifiManager) getSystemService(Context.WIFI_SERVICE);
wifiStatus = wifiMgr.isWifiEnabled();
if(wifiStatus)
wf.setChecked(true);
sb.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
try {
TextView tv = (TextView) findViewById(R.id.result);
AudioManager mAudio = (AudioManager) getSystemService(Activity.AUDIO_SERVICE);
if(sb.isChecked()) {
mAudio.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
tv.setText("Ringer set to Normal");
} else {
mAudio.setRingerMode(AudioManager.RINGER_MODE_SILENT);
tv.setText("Ringer set to Silent");
}
}catch (Exception e) {
e.printStackTrace();
}
}
});
bt.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
try {
TextView tv = (TextView) findViewById(R.id.result);
if(bt.isChecked())
tv.setText("Bluetooth is On!");
else
tv.setText("Bluetooth is Off!");
} catch (Exception e) {
e.printStackTrace();
}
}
});
wf.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
try {
TextView tv = (TextView) findViewById(R.id.result);
WifiManager wifiMgr = (WifiManager) getSystemService(Context.WIFI_SERVICE);
if(wf.isChecked()) {
wifiMgr.setWifiEnabled(true);
tv.setText("Wifi is On!");
} else {
wifiMgr.setWifiEnabled(false);
tv.setText("Wifi is Off!");
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
}catch (Exception e) {
e.printStackTrace();
}
}
I have added the following permissions:
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
I am using Motorola milestone (android 2.1).. What Am I missing? can anybody point me what is wrong with this code?
Thanks in Advance for suggestions and corrections.
The Issue was solved by added more permissions!
For people who are facing the same issue, you will have to add the following permissions as well:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.UPDATE_DEVICE_STATS"></uses-permission>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission>
Now, In addition to these I needed Audio and Bluetooth access. for that I had to add:
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.BLUETOOTH" />

Categories

Resources