PhoneStateListener не будет выпущен, и никакие ранее опубликованные ответы не сработали

Этот вопрос задавался несколько раз, и ни один из них не решил проблему для меня. Я испробовал все возможные способы отмены регистрации слушателя нажатием кнопки, переходом в onPause и onDestroy; но слушатель сохраняется, даже когда приложение закрыто. Более того, я подчеркиваю размер массива, который заполняет мой слушатель, даже когда приложение закрывается, тост остается и продолжает увеличиваться. Я пытался использовать null и LISTEN_NONE и все остальное, что смог найти в Интернете.

// Name of this file is Second.class
public class Second extends Activity {

    SignalStrengthListener signalStrengthListener;
    TextView lteRsrp;
    TextView lteRsrq;
    TextView cellPciTextView;
    TextView timerValue;
    Button startButton, stopButton;

    TelephonyManager tm;
    List<CellInfo> cellInfoList;
    String lte1, lte2;
    int cellPci = 0;
    long startTime = 0L;
    long timeInMilliseconds = 0L;
    long timeSwapBuff = 0L;
    long updatedTime = 0L;
    ArrayList<String> rsrpArray;
    ArrayList<String> rsrqArray;
    ArrayList<String> pciArray;


    Handler customHandler = new Handler();
    boolean flag = true;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.second_activity);

        flag = false;

        rsrpArray = new ArrayList<>();
        rsrqArray = new ArrayList<>();
        pciArray = new ArrayList<>();

        lteRsrp = (TextView) findViewById(R.id.lteRsrp);
        lteRsrq = (TextView) findViewById(R.id.lteRsrq);
        cellPciTextView = (TextView) findViewById(R.id.cellPciTextView);
        timerValue = (TextView) findViewById(R.id.timerValue);
        startButton = (Button) findViewById(R.id.startButton);
        stopButton = (Button) findViewById(R.id.stopButton);



        startButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startTime = SystemClock.uptimeMillis();
                customHandler.postDelayed(updateTimerThread, 0);

                //start the signal strength listener
                signalStrengthListener = new SignalStrengthListener();

                ((TelephonyManager) getSystemService(TELEPHONY_SERVICE)).listen(signalStrengthListener, SignalStrengthListener.LISTEN_SIGNAL_STRENGTHS);
                tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);

                try {
                    cellInfoList = tm.getAllCellInfo();
                } catch (Exception e) {
                    Log.d("SignalStrength", "+++++++++++++++++++++++++++++++++++++++++ null array spot 1: " + e);

                }


                try {
                    for (CellInfo cellInfo : cellInfoList) {
                        if (cellInfo instanceof CellInfoLte) {
                            // cast to CellInfoLte and call all the CellInfoLte methods you need
                            // Gets the LTE PCI: (returns Physical Cell Id 0..503, Integer.MAX_VALUE if unknown)
                            cellPci = ((CellInfoLte) cellInfo).getCellIdentity().getPci();
                        }
                    }
                } catch (Exception e) {
                    Log.d("SignalStrength", "++++++++++++++++++++++ null array spot 2: " + e);
                }

            }
        });

        stopButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                timeSwapBuff += timeInMilliseconds;
                customHandler.removeCallbacks(updateTimerThread);
                flag = true;

                try{
                    if(signalStrengthListener != null) {
                        tm.listen(signalStrengthListener, SignalStrengthListener.LISTEN_NONE);
                        Log.d("TAG", "+++++++++++++++++++++++++++++++++++ Success!!!!!!");
                    }
                }catch(Exception e){
                    e.printStackTrace();
                    Log.d("TAG", "+++++++++++++++++++++++++++++++++++ Fail!!!!!! with error = " + e);
                }
            }
        });


    }

    private Runnable updateTimerThread = new Runnable() {
        public void run() {
            timeInMilliseconds = SystemClock.uptimeMillis() - startTime;
            updatedTime = timeSwapBuff + timeInMilliseconds;
            int secs = (int) (updatedTime / 1000);
            int mins = secs / 60;
            secs = secs % 60;
            int milliseconds = (int) (updatedTime % 1000);
            timerValue.setText("" + mins + ":"
                + String.format("%02d", secs) + ":"
                + String.format("%03d", milliseconds));
            customHandler.postDelayed(this, 0);
        }
    };


    private class SignalStrengthListener extends PhoneStateListener {
        @Override
        public void onSignalStrengthsChanged(android.telephony.SignalStrength signalStrength) {

            //++++++++++++++++++++++++++++++++++

            ((TelephonyManager) getSystemService(TELEPHONY_SERVICE)).listen(signalStrengthListener, SignalStrengthListener.LISTEN_SIGNAL_STRENGTHS);

            tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);

            String ltestr = signalStrength.toString();
            String[] parts = ltestr.split(" ");
            lte1 = parts[9];
            lte2 = parts[10];

            try {
                cellInfoList = tm.getAllCellInfo();
                for (CellInfo cellInfo : cellInfoList) {
                    if (cellInfo instanceof CellInfoLte) {
                        // cast to CellInfoLte and call all the CellInfoLte methods you need
                        // Gets the LTE PCI: (returns Physical Cell Id 0..503, Integer.MAX_VALUE if unknown)
                        cellPci = ((CellInfoLte) cellInfo).getCellIdentity().getPci();
                    }
                }
            } catch (Exception e) {
                Log.d("SignalStrength", "+++++++++++++++++++++++++++++++ null array spot 3: " + e);
            }

            if (!flag) {
                rsrpArray.add(lte1);
                rsrqArray.add(lte2);
                pciArray.add(Integer.toString(cellPci));
                int size = rsrpArray.size();
                Toast.makeText(Second.this, "Array size = " + size, Toast.LENGTH_LONG).show();
            }

            lteRsrp.setText(String.valueOf(lte1));
            lteRsrq.setText(String.valueOf(lte2));
            cellPciTextView.setText(String.valueOf(cellPci));

            super.onSignalStrengthsChanged(signalStrength);

            //++++++++++++++++++++++++++++++++++++

        }
    }



    @Override
    public void onPause() {
        Log.d("onPause SigStr", "+++++++++++++++++++++++++++++++++++ onPause");
        try{
            if(signalStrengthListener != null){
                tm.listen(signalStrengthListener, SignalStrengthListener.LISTEN_NONE);
                Log.d("TAG", "+++++++++++++++++++++++++++++++++++ Success!!!!!!");
            }
        }catch(Exception e){
            e.printStackTrace();
            Log.d("TAG", "+++++++++++++++++++++++++++++++++++ Fail!!!!!! with error = " + e);
        }
        flag = true;
        super.onPause();

    }

    @Override
    public void onDestroy() {

        Log.d("onPause SigStr", "+++++++++++++++++++++++++++++++++++ onDestroy");
        try{
            if(signalStrengthListener != null) {
                tm.listen(signalStrengthListener, SignalStrengthListener.LISTEN_NONE);
                Log.d("TAG", "+++++++++++++++++++++++++++++++++++ Success!!!!!!");
            }
        }catch(Exception e){
            e.printStackTrace();
            Log.d("TAG", "+++++++++++++++++++++++++++++++++++ Fail!!!!!! with error = " + e);
        }
        flag = true;
        super.onDestroy();

    }
}

Мой код начинает становиться уродливым и избыточным, поскольку я продолжаю переставлять вещи в надежде, что это может отменить регистрацию моего слушателя. Ниже приведен мой XML-макет для Second.class. Имя файла макета XML — second_activity.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#42abc0">

    <TextView
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:text=""
        android:textSize="16sp"
        android:textColor="#000000"
        android:id="@+id/lteRsrp"
        android:layout_alignParentTop="true"
        android:layout_alignParentStart="true"
        android:layout_marginStart="29dp"
        android:layout_marginTop="31dp" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="= LTE RSRP"
        android:textSize="16sp"
        android:textColor="#000000"
        android:id="@+id/textView2"
        android:layout_alignTop="@+id/lteRsrp"
        android:layout_centerHorizontal="true" />

    <TextView
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:text=""
        android:textColor="#000000"
        android:textSize="16sp"
        android:id="@+id/lteRsrq"
        android:layout_below="@+id/lteRsrp"
        android:layout_alignStart="@+id/lteRsrp" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="= LTE RSRQ"
        android:textSize="16sp"
        android:textColor="#000000"
        android:id="@+id/textView3"
        android:layout_below="@+id/textView2"
        android:layout_alignStart="@+id/textView2" />

    <TextView
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:text=""
        android:textSize="16sp"
        android:textColor="#000000"
        android:id="@+id/cellPciTextView"
        android:layout_below="@+id/lteRsrq"
        android:layout_alignStart="@+id/lteRsrq" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="= LTE PCI"
        android:textSize="16sp"
        android:textColor="#000000"
        android:id="@+id/textView4"
        android:layout_below="@+id/textView3"
        android:layout_alignStart="@+id/textView3" />

    <Button
        android:layout_width="120dp"
        android:layout_height="wrap_content"
        android:text="Start"
        android:textColor="#000000"
        android:textSize="22sp"
        android:id="@+id/startButton"
        android:layout_alignParentBottom="true"
        android:layout_toEndOf="@+id/textView3"
        android:layout_marginBottom="48dp"
        android:background="#ffffff"
        android:textAlignment="center"
        android:textStyle="bold"
        android:padding="4dp" />

    <Button
        android:layout_width="120dp"
        android:layout_height="wrap_content"
        android:text="Stop"
        android:textSize="22sp"
        android:textColor="#000000"
        android:id="@+id/stopButton"
        android:layout_alignBottom="@+id/startButton"
        android:layout_alignStart="@+id/cellPciTextView"
        android:background="#ffffff"
        android:textStyle="bold"
        android:padding="4dp"
        android:textAlignment="center" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/timerVal"
        android:textSize="40sp"
        android:textColor="#000000"
        android:id="@+id/timerValue"
        android:layout_above="@+id/startButton"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="55dp" />


</RelativeLayout>

И вот мой AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.parksjg.its.pscrindoortesttool" >

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme" >
        <activity android:name=".First"
            android:screenOrientation="portrait" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".Second"
            android:screenOrientation="portrait">

        </activity>
    </application>

</manifest>

Опять же, этот вопрос задавался раньше, НО ни один из опубликованных ответов не сработал!!! Вот некоторые из них, и обратите внимание, что ни один из ответов не был проголосован или он никогда не был отмечен как работающий: live-after-activity-finish">Android: почему PhoneCallListener все еще жив после завершения активности?

Android: как перестать слушать PhoneCallListener?

Надеюсь, я упускаю из виду что-то простое, на что кто-то может указать. Дайте мне знать, если вам нужно больше кода или вы хотите, чтобы я разместил весь проект Android Studio на GitHub.

Спасибо!!!


person JParks    schedule 03.11.2015    source источник
comment
Я еще не тестировал, но все, что я могу предложить вам, это создать глобальную статическую логическую переменную и пометить ее как true, когда приложение запускается, например, в onCreate(), и пометить как false при ondestroy или onpause. И в вашем слушателе поставьте условие if(IsApplicationRunning) { // делайте все остальное } else {//игнорируйте его } таким образом, даже если ваше приложение подключается к системе, несмотря на то, что оно не используется, тогда, по крайней мере, оно будет искать это условие для пробег.   -  person dawncode    schedule 05.11.2015
comment
Это то, что я пытался в последнее время, но безуспешно. Если вы посмотрите в приведенном выше коде, то увидите boolean flag, и я пробовал вставлять его в разные места. Например, в приведенном выше коде я установил флаг в значение true в методе onPause, что должно помешать слушателю продолжать выполнение, но он просто продолжает работать. Я также обернул весь код SignalStrengthListener в оператор if, используя flag bool.   -  person JParks    schedule 05.11.2015
comment
У меня также есть отладочные комментарии в onPause и onDestroy, которые всегда печатают комментарий об успехе, поэтому я знаю, что прослушиватель получает значение LISTEN_NONE до того, как логическое значение «флаг» будет переназначено. Если вы видите более логичный способ использования логического значения flag, пожалуйста, дайте мне знать. Спасибо за ваше время.   -  person JParks    schedule 05.11.2015
comment
Пожалуйста, опубликуйте свой манифест   -  person David Wasser    schedule 10.11.2015


Ответы (1)


Кажется, я понял, что происходит. Я добавил в код еще несколько операторов Log.d(), чтобы определить, сколько раз вызывался SignalStrengthListener. Я запустил приложение на 3 секунды и обнаружил, что SignalStrengthListener вызывался примерно 300 раз! Гораздо больше, чем я думал. Теперь проблема в том, что Toast не может угнаться за тем, сколько раз он вызывался; поэтому, когда я останавливаю или закрываю приложение, тосты продолжают появляться в течение нескольких минут после этого. Моя вина заключалась в том, что я не дал тостам достаточно времени, чтобы наверстать упущенное перед удалением приложения, в то время я думал, что это единственный способ остановить прослушиватель.

Чтобы проверить это, я снова запустил приложение на 3 секунды и получил 273 вызова SignalStrengthListener, и каждый раз, когда он вызывается, он создает Toast. Я остановился и закрыл приложение, и тосты продолжали появляться в течение нескольких минут. Однако в конце концов они остановились на 273 Toast.

Короче говоря, Toast не подходит для вызова много раз в секунду. Это моя вина, что я не понял, как работает мой слушатель. В конце концов, логические значения, которые я установил, и тег LISTEN_NONE для моего слушателя успешно отменили регистрацию слушателя.

person JParks    schedule 10.11.2015
comment
Пожалуйста, дайте мне знать, если я должен удалить свой вопрос. - person JParks; 10.11.2015