Jacks
Jacks

Reputation: 51

Getting crash in screen on /off while closing app

I am detecting screen on /off time when app is open or close

Using Services and Broadcast Receiver. it is working good when app is running or minimizing but during closing app it is going crashed.

How to get screen on/off time once close the app without crash .

Error in logcat

E/ActivityThread: Activity com.shah.neeraj.s.MainActivity has leaked IntentReceiver com.shah.neeraj.s.ScreeReceiver@8686ff5 that was originally registered here. Are you missing a call to unregisterReceiver()?
                  android.app.IntentReceiverLeaked: Activity com.shah.neeraj.s.MainActivity has leaked IntentReceiver com.shah.neeraj.s.ScreeReceiver@8686ff5 that was originally registered here. Are you missing a call to unregisterReceiver()?
                      at android.app.LoadedApk$ReceiverDispatcher.<init>(LoadedApk.java:1159)
                      at android.app.LoadedApk.getReceiverDispatcher(LoadedApk.java:946)
                      at android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:1330)
                      at android.app.ContextImpl.registerReceiver(ContextImpl.java:1310)
                      at android.app.ContextImpl.registerReceiver(ContextImpl.java:1304)
                      at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:586)
                      at com.shah.neeraj.s.MainActivity.onCreate(MainActivity.java:37)
                      at android.app.Activity.performCreate(Activity.java:6672)
                      at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1140)
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2612)
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2724)
                      at android.app.ActivityThread.-wrap12(ActivityThread.java)
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1473)
                      at android.os.Handler.dispatchMessage(Handler.java:102)
                      at android.os.Looper.loop(Looper.java:154)
                      at android.app.ActivityThread.main(ActivityThread.java:6123)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757)
Application terminated.

MainActivity

public class MainActivity extends Activity {
    TextView text1,text2,text3;   
    Date d,d1;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);
        text1 = (TextView) findViewById(R.id.text1);
        text2 = (TextView) findViewById(R.id.text2);
        text3 =(TextView) findViewById(R.id.text3);    

        // INITIALIZE RECEIVER
       IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
        filter.addAction(Intent.ACTION_SCREEN_OFF);
        BroadcastReceiver mReceiver = new ScreeReceiver();
        registerReceiver(mReceiver, filter);
//        unregisterReceiver(mReceiver);
        PowerManager pm =(PowerManager) getSystemService(Context.POWER_SERVICE);
        // YOUR CODE
    }

    @Override
    protected void onPause() {
        // WHEN THE SCREEN IS ABOUT TO TURN OFF
        if (ScreeReceiver.wasScreenOn)
        {
        //if (pm.isScreenOn() == false){
            // THIS IS THE CASE WHEN ONPAUSE() IS CALLED BY THE SYSTEM DUE TO A SCREEN STATE CHANGE

            d = new Date();
            CharSequence s = DateFormat.format("hh:mm:ss", d.getTime());

            System.out.println("SCREEN TURNED OFF");
            text1.setText("SCREEN TURNED OFF" + s);
            Log.i("hi", "s"+ s);  
        } else {
            // THIS IS WHEN ONPAUSE() IS CALLED WHEN THE SCREEN STATE HAS NOT CHANGED
        }
        super.onPause();    
    }

    @Override
    protected void onResume() {
        // ONLY WHEN SCREEN TURNS ON
        if (!ScreeReceiver.wasScreenOn) {
            // THIS IS WHEN ONRESUME() IS CALLED DUE TO A SCREEN STATE CHANGE

            d1 = new Date();
            CharSequence s1 = DateFormat.format("hh:mm:ss", d1.getTime());

            text2.setText("SCREEN TURNED ON" + s1);
            Log.i("hi", "s"+ s1);

            System.out.println("SCREEN TURNED ON");

            Timer updateTimer = new Timer();
            updateTimer.schedule(new TimerTask()
            {    
                public void run()
                {
                    try
                    {    
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {    
                                //stuff that updates ui
                                long diff = d1.getTime() - d.getTime();

                                int Hours = (int) (diff/( 1000* 60 * 60));
                                int Mins = (int) (diff/(1000*60)) % 60;

                                Log.i("Difference ", ""+ diff);

                                String diff1= Hours + ":" + Mins; // updated value every 60 second
                                text3.setText( diff1 );
                                Log.i("Differ", "diff"+ diff1);
                            }
                        });    
                    }
                    catch (Exception e)
                    {
                        e.printStackTrace();
                    }
                }    
            }, 0, 600000);    
        } else {
        }
        super.onResume();  
    }    

    @Override
    public void onDestroy() {
        super.onDestroy();
        //Log.d(msg, "The onDestroy() event");
        /*IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
        filter.addAction(Intent.ACTION_SCREEN_OFF);
        BroadcastReceiver mReceiver = new ScreeReceiver();
        unregisterReceiver(mReceive);*/    
    }
}

ScreenReceiver

public class ScreeReceiver extends BroadcastReceiver {
    public static boolean wasScreenOn = true;
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
            // DO WHATEVER YOU NEED TO DO HERE
            wasScreenOn = false;
        } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
            // AND DO WHATEVER YOU NEED TO DO HERE
            wasScreenOn = true;
        }
        Intent i = new Intent(context, UpdateService.class);
        i.putExtra("screen_state", wasScreenOn);
        context.startService(i);

        Toast.makeText(context, "Intent Detected.", Toast.LENGTH_LONG).show();
    }    
}

UpdateService

public class UpdateService extends Service {
    TextView text1,text2,text3;
    @Override
    public void onCreate() {
        super.onCreate();
        // REGISTER RECEIVER THAT HANDLES SCREEN ON AND SCREEN OFF LOGIC
        IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
        filter.addAction(Intent.ACTION_SCREEN_OFF);
        BroadcastReceiver mReceiver = new ScreeReceiver();
        registerReceiver(mReceiver, filter);
    }

    @Override
    public void onStart(Intent intent, int startId) {
        boolean screenOn = intent.getBooleanExtra("screen_state", false);
        if (!screenOn) {
           // YOUR CODE
            /* Date d = new Date();
            CharSequence s = DateFormat.format("hh:mm:ss", d.getTime());

            System.out.println("SCREEN TURNED OFF");
            text1.setText("SCREEN TURNED OFF" + s);
            Log.i("hi", "s"+ s);
            */
            Date d = new Date();
            CharSequence s = DateFormat.format("hh:mm:ss", d.getTime());

            System.out.println("SCREEN TURNED OFF");
            Log.i("hi Service t off", "s"+ s);

           // text1.setText("SCREEN TURNED OFF" + s);
            System.out.println("SCREEN  Off"+s);

        } else {
            // YOUR CODE
            Date  d1 = new Date();
            CharSequence s1 = DateFormat.format("hh:mm:ss", d1.getTime());

            //text2.setText("SCREEN TURNED ON" + s1);
            Log.i("hi Service t on ", "s"+ s1);

            System.out.println("SCREEN  ON"+s1);
        }
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }


    @Override
    public void onDestroy() {
        IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
        filter.addAction(Intent.ACTION_SCREEN_OFF);
        BroadcastReceiver mReceiver = new ScreeReceiver();
        unregisterReceiver(mReceiver);
    }

Manifest

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>


        </activity>

       <receiver android:name="ScreeReceiver">

           <intent-filter>
               <action android:name="android.intent.action.SCREEN_OFF"/>
               <action android:name="android.intent.action.SCREEN_ON"/>
           </intent-filter>
        </receiver>



        <service android:name=".UpdateService">

        </service>
    </application>

</manifest>

Upvotes: 1

Views: 617

Answers (3)

IntelliJ Amiya
IntelliJ Amiya

Reputation: 75788

Whats your Logcat returns

that was originally registered here. Are you missing a call to unregisterReceiver()?

At first, Declare BroadcastReceiver as Global & You should call below in onPause() Method

And open this onCreate() section .

unregisterReceiver(mReceive);

Finally

 @Override
protected void onStop()
{    ........................
    unregisterReceiver(mReceive);
    super.onStop();
}

Upvotes: 3

Sangeeta
Sangeeta

Reputation: 991

You are registering receiver but not unregistering it.

Your should register and unregister Receiver in onResume() and onPause() (or onStart() and onStop()) respectively.

Upvotes: 0

Dishonered
Dishonered

Reputation: 8841

Uncomment this ,

BroadcastReceiver mReceiver = new ScreeReceiver();
    unregisterReceiver(mReceive);

The error is suggesting that you are not unregistering the receiver.

Upvotes: -1

Related Questions