当应用程序在后台时停止服务

Stop a service when application is in background

我是 android 的新手,我正在创建一个 MAC 欺骗应用程序。我创建了一个 IntentService 以每 5 秒在应用程序中欺骗 MAC 地址并且它工作正常。然后我创建了一个 BaseActivity,我的所有活动都从中扩展,这样我就可以检测应用程序何时进入后台,这也工作正常。我已经有了它,所以当应用程序在后台时,MAC 地址不再更改并恢复到原来的状态,但我不想这样,而是在应用程序在后台时停止服务并重新启动再次打开应用程序时的服务。到目前为止,这是我的代码:

基础活动

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.wifi.WifiManager;
import android.util.Log;
import android.widget.Toast;

public class BaseActivity extends Activity {
    private static int sessionDepth = 0;
    public static boolean isInBackground = false;
    WifiManager wifiManager;
    private Intent myIntent;



    // app in foreground
    @Override
    protected void onStart() {
        super.onStart();
        sessionDepth++;
        isInBackground = false;

        // for MAC spoofing
        myIntent = new Intent(this, IntentService.class);
        startService(myIntent);

    }

    // app in background
    @Override
    protected void onStop() {
        super.onStop();
        if (sessionDepth > 0)
            sessionDepth--;
        if (sessionDepth == 0) {
            Toast.makeText(getApplicationContext(), "App is in background",
                    Toast.LENGTH_SHORT).show();
            isInBackground = true;
            Log.d("My log2", "background " + isInBackground);
            wifiManager = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);
            wifiManager.setWifiEnabled(false); // restart wifi
            wifiManager.setWifiEnabled(true);
            stopService(myIntent);
        }
    }
    @Override
    protected void onPause() {
        super.onPause();
        stopService(myIntent);
    }

    public boolean getStatus(){
        return isInBackground;
    }

}

意图服务

package edu.fiu.mpact.reuproject;

import android.content.Intent;
import android.net.wifi.WifiManager;
import android.util.Log;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;


    public class IntentService extends android.app.IntentService {
        Process p = null;
        String[] ouiList;
        Random gen = new Random();
        char[] charList = {'A', 'B', 'C', 'D', 'E', 'F', '0', '1', '2', '3', '4', '5', '6', '7',
                '8', '9'};


        public IntentService() {
            super("MAC");
        }

        @Override
        protected void onHandleIntent(Intent intent) {
            try {
                ouiList = loadOUIs();
            } catch (IOException e) {
                e.printStackTrace();
            }

            try {
                p = Runtime.getRuntime().exec("su");  // prompt for root access
            } catch (IOException e) {
                e.printStackTrace();
            }
            new Timer().scheduleAtFixedRate(new TimerTask() {
                BaseActivity b = new BaseActivity();

                @Override
                public void run() {
                  Log.d("my log2", b.getStatus() + "");

                    try {
                        if(!b.getStatus()) {
                            changeMac();
                        }

                        Log.d("my log3", Utils2.getMACAddress("wlan0"));
                    } catch (IOException | InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }, 0, 5000); // changes MAC every 3 seconds



        }
        private void changeMac() throws IOException, InterruptedException {
            String mac = generateMac();

            //commands to execute
            String[] cmds = {"ip link set wlan0 address " + mac};

            // execute the commands
            DataOutputStream os = new DataOutputStream(p.getOutputStream());
            for (String tmpCmd : cmds) {
                os.writeBytes(tmpCmd + "\n");
            }

        }
        private String generateMac(){
            String s = ouiList[gen.nextInt(20847)] + ":";

            for(int i = 0; i < 6; i++){
                s = s + charList[gen.nextInt(16)];

                //add colon
                if(((i + 1) % 2 == 0) && i != 5){
                    s = s + ":";
                }
            }

            return s;
        }

        private String[] loadOUIs() throws IOException {
            String[] ouiList = new String[20847];

            int i = 0;
            InputStream inStream = getApplicationContext().getResources().openRawResource(R.raw.oui2);
            InputStreamReader is = new InputStreamReader(inStream);
            BufferedReader reader = new BufferedReader(is);

            String word = reader.readLine();  //read first OUI
            while(word != null){             //continue until no more OUI's
                ouiList[i] = word;
                word = reader.readLine();
                i++;
            }

            return ouiList;

        }


    }

由于某些原因,尽管我调用了 stopService(),但当应用程序进入后台时服务并未停止。

For some reason the service is not stopping when the app goes to background

它在您的 stopService() 调用之前很久就停止了,因为一旦 onHandleIntent() 返回它就停止了,它在创建后几毫秒就停止了。

不会停止的是您的 Timer,它在后台线程上运行并将继续 运行 直到您取消它或您的进程终止。

恕我直言,这是对 IntentService 的不当使用。如果要控制寿命,请使用 Service,并在 onDestroy() 停止后台工作。