Android Solution for page instability after turning on hot spots

Posted by GirishR on Sat, 13 Jun 2020 01:55:59 +0200

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>

Topics: Android Mobile xml Java