1 Question
After Android 8.0, we turned on hotspots in the following way, but when we jump to the page, the hotspots will be disconnected and the phones will not be able to transfer files to each other.
Permission Instructions: Android 8.0 requires location and GPS permissions, while hot spots on mobile phones cannot be turned on.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { try { mWifiManager.startLocalOnlyHotspot(new WifiManager.LocalOnlyHotspotCallback() { @Override public void onFailed(int reason) { super.onFailed(reason); Log.i(TAG, "onFailed start"); } @Override public void onStarted(WifiManager.LocalOnlyHotspotReservation reservation) { super.onStarted(reservation); Log.i(TAG, "onStarted start"); mReservation = reservation; WifiConfiguration wifiConfiguration = reservation.getWifiConfiguration(); String ssid = wifiConfiguration.SSID; String pwd = wifiConfiguration.preSharedKey; Log.i(TAG, "ssid is:" + ssid); Log.i(TAG, "pwd is:" + pwd); } @Override public void onStopped() { super.onStopped(); sendBroadcast(STOP_STATE, "", ""); } }, new Handler()); } catch (Exception e) { e.printStackTrace(); Log.e(TAG, "startLocalOnlyHotspot error"); } }
2 Reflections
1) The mReservation variable is saved globally and statically, and the close method is not executed when jumping pages.
We see the code above
mReservation = reservation;
We shut down. That's how we shut down
if (mReservation != null) { mReservation.close(); mReservation = null; }
To prevent hot spots from turning off, we initially saved the mReservation variable globally static, but there is still a problem that hot spots will break when turned on.
2) Decompile the "Eggplant Express" code and analyze other people's products
"Eggplant Express" app is also a hot spot after the generation of multiple mobile phone connections, and then send files, we decompile the "Eggplant Express" code
Search keyword startLocalOnlyHotspot, as shown below
It looks like reflection is used here, so let's click in to see this function
Reflections are used, so what is an API for?Now I don't know if there's anything fishy about it. Then I'll see where to call it again.
Obviously, a service is started here, and then an intent with parameters is passed in the onStartCommand function. If 0, the close function is executed, if 1, the open hot spot function is executed, and then it overrides the callback LocalOnlyHotspotCallback
Pass in LOHSService as a constructor parameter and execute this.a.a(1, str,WifiConfiguration.preSharedKey;
This function sends broadcasts with username and password to other pages
Then I'll start a service by mimicking this, opening a hot spot inside the service to test, and configuring it as follows
<service android:name="**********.LocalHotService" android:exported="false"> <intent-filter> <action android:name="**********.LocalHotService"/> </intent-filter> </service>
I found it is still unstable, but I opened it with API instead of reflection. Then I used its code to open it with reflection, and the effect is still unstable. That means there is no difference here. Because the first time I opened the hot spot, it is very stable, and the second time I opened the hot spot will be very unstable, so I thought if there was a problem closing the hot spot.
if (mReservation != null) { mReservation.close(); mReservation = null; }
Then I try to turn it off with reflection instead of using the intermediate variable mReservation
@TargetApi(Build.VERSION_CODES.M) public void stopHotPoint(Context context) { try { ConnectivityManager manager = (ConnectivityManager) context.getApplicationContext().getSystemService(ConnectivityManager.class); Method method = manager.getClass().getDeclaredMethod("stopTethering", int.class); if (method == null) { } else { method.invoke(manager, 0); } } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (Exception e){ e.printStackTrace(); } }
In this case, you also need to apply for a permission to modify the system settings, you need to apply through startActivity, of course
android.permission.WRITE_SETTINGS
Of course in AndroidManifest.xml Also configure inside
<uses-permission android:name="android.permission.WRITE_SETTINGS" tools:ignore="ProtectedPermissions" />
This way the program won't run
Then we will analyze the source code again, where the system will call finalize method, memory is not enough to execute, then close method will be called back inside, then close method will be called stopLocalOnlyHotspot() method, hot spots will be closed here
It may be that there isn't enough memory to cause instability, and then why can't we start a process now that Hot Spot Services are turned on?
Then put the service in another process that doesn't do much else, and memory doesn't generally do Java garbage collection
Then start the service in a separate process and test the hot spot is stable and the problem is solved
3 Solutions
Open up a new process Open Hot Spot Services
<service android:name="*****.LocalHotService" android:exported="false" android:process=":aptest"> <intent-filter> <action android:name="*****.LocalHotService"/> </intent-filter> </service>