0

I have been searching out a lot of things to sove my problem but none of the solutions I found worked in my case :'(

Here is what I am trying to do:

  1. When the screen is off, my BroadCastReceiver detects it.
  2. Once screen_off is detected, acquire WakeLock and my BroadCastReceiver starts my custom idle screen activity.

(As for the location where it starts the idle screen activity, I have tried in BroadCastReceiver, IntentService and AsyncTask classes but all of them made same problem)

And this is the error message I am getting:

01-25 14:55:13.253: E/ActivityThread(10879): Activity com.example.test.MainActivity has leaked IntentReceiver com.example.test.BCReceiver@41fb1e48 that was originally registered here. Are you missing a call to unregisterReceiver()?

01-25 14:55:13.253: E/ActivityThread(10879): android.app.IntentReceiverLeaked: Activity com.example.test.MainActivity has leaked IntentReceiver com.example.test.BCReceiver@41fb1e48 that was originally registered here. Are you missing a call to unregisterReceiver()?

Here's my code:

MainActivity.java

public class MainActivity extends Activity {
    BCReceiver mReceiver;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //register receiver
        mReceiver = new BCReceiver();
        registerReceiver(mReceiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));
    }
}

BCReceiver.java

public class BCReceiver extends BroadcastReceiver  {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)){
            PowerManager pm = (PowerManager) context.getSystemService(context.POWER_SERVICE);
            PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.PARTIAL_WAKE_LOCK, "com.foreseeson.visionsaylauncher");
            wl.acquire(); //works fine until here
            Intent startHomescreen=new Intent(context, IdleScreenActivity.class);
            startHomescreen.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
            context.startActivity(startHomescreen);
        } 
    }
}

manifest

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.test"
    android:versionCode="1"
    android:versionName="1.0" >
    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="21" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name="IdleScreenActivity"></activity>
    </application>
</manifest>

Everything until "WakeLock" is working but starting an activity from the BroadCastReceiver makes the error. Some people said to put "unregisterReceiver(...)" in "onStop()" but this does not work to me because screen_off can never be detected as my Receiver gets unregistered before the screen_off event happens. Any other thoughts? Please help!

Edit: I am creating a kiosk application now. So if there is nobody playing with my kiosk device and some amount of time passes, the screen goes off and it should display my activity on the screen. I have searched that the best way to detect user-inactivity is to detect screen_off. Therefore, once screen_off is detected, it should wake up itself and start an activity.

Community
  • 1
  • 1
DVN
  • 1
  • 2
  • You should never start an activity from background, it went to background because your activity isn't being used. If you want to display a custom screen for when the user returns to the app do so in the onResume() method. – Dave S Jan 26 '15 at 19:43
  • You know, when your phone is off and get a message, you see the dialog on your screen even though you don't even touch the phone. Isn't that message dialogue controlled in a broadcastreceiver? – DVN Jan 26 '15 at 20:09
  • It seems like you should register receiver in app context, not in activity. – Aleksandr Jan 26 '15 at 20:10
  • Aleksandr would you please give me more details please? – DVN Jan 26 '15 at 23:33
  • Aleksandr, can you give me more tips please? – DVN Jan 30 '15 at 17:17

1 Answers1

0

Going off your requirements,

    1. When the screen is off, my BroadCastReceiver detects it.
    2. Once screen_off is detected, acquire WakeLock and my BroadCastReceiver starts my custom idle screen activity.

Ok, the screen is off, you should not be waking the phone up to display anything at this point. The screen went off because the user isn't using the app.

If you want to display an idle screen for the user to see upon returning to the app, all you need to do is display this screen in onResume(). If you want persistent monitoring use a service and notifications to alert users about events. If you app needs to stay on, you should be acquiring the wake lock before the app goes to the background and releasing it when it no longer is necessary.

Dave S
  • 3,378
  • 1
  • 20
  • 34
  • Thanks for your advice Dave. I am creating a kiosk application now. So if there is nobody playing with the device and some amount of time passes, the screen goes off and it should display my activity on the screen. I have searched that the best way to detect user-inactivity is to detect screen_off. Therefore, once screen_off is detected, it should wake up itself and start an activity. – DVN Jan 26 '15 at 20:05
  • That goes against most design principles, in no case should your app go to the background and then start itself, this could cause an infinite loop of not being able to exit the app. What I've seen that may do what you want are games that just stay open. The screen can go off but the app maintains itself and while it may have a brief loading window it starts again when the screen is turned on again. – Dave S Jan 26 '15 at 20:13
  • I am pretty sure they accomplish this by holding a wake lock while the activity is open, and releasing it when the user deliberately exits the app. – Dave S Jan 26 '15 at 20:13
  • You can find more info about why this is deliberately prevented here: http://android.stackexchange.com/questions/25470/is-there-a-way-to-force-an-app-to-remain-running-in-the-background-no-matter-wha – Dave S Jan 26 '15 at 20:18
  • Also if my app isn't exited and I lock the screen or the screen goes off and I turn it back on again my app is still displaying and I don't need to do anything extra to get that behavior. – Dave S Jan 26 '15 at 20:52
  • Thank you for your advice Dave. But the point is that my app should display an idle_screen_activity by itself in case of user-inactivity. The best way to detect user-inactivity is to detect screen_off in the BroadCastReceiver. And somehow it needs to wake up and start an activity once screen_off is detected. There won't be anyone who turn it back on. It should turn it back on by itself. – DVN Jan 26 '15 at 21:11
  • It should be similar to displaying notification message dialogue while the phone is in screen-off. You know, when your phone is off and get a message, you see the dialog on your screen even though you don't even touch the phone. Isn't that message dialogue controlled in a broadcastreceiver? – DVN Jan 26 '15 at 21:24
  • I'm telling you that the Android OS deliberately prevents this from happening. I don't get any dialogs automatically opened for any notification on my device. As far as I'm aware the best you can do is just keep the screen on indefinitely. To display an inactive screen you can set a timer and reset the timer on user interaction. http://stackoverflow.com/questions/5712849/how-do-i-keep-the-screen-on-in-my-app – Dave S Jan 26 '15 at 21:26
  • Actually this is probably a better solution http://stackoverflow.com/questions/4807634/disable-keep-screen-on – Dave S Jan 26 '15 at 21:30
  • You can start activities from a service but only if your application context still exists, by the time the screen goes off the application should be closed and no context available to start the activity. Apps absolutely should not start themselves. My advice is to instead keep the app on and detect user inactivity in another way. If you want to keep fighting the OS that's your decision but I doubt you will find a solution. – Dave S Jan 26 '15 at 21:49
  • You said to reset the timer on user interaction to detect user-inactivity. Of course I have tried this. It did not work because my application cannot get the user-interaction when the user is using different app in the front. "setting a timer and resetting it" sounds very easy but it is not. I spent several days to find a way to detect user-inactivity itself. – DVN Jan 26 '15 at 22:40
  • Simply, I am creating a Kiosk app which is a type of Android launcher. It should allow user to open some other allowed applications like internet browser. Once my app detects user-inactivity it should display an activity even though the user was using a browser app. So the issues here are 1. How to detect user inactivity even though 3rd-party app is in front 2. How to start my activity once user inactivity is detected – DVN Jan 26 '15 at 22:45
  • Dave I know you are an expert. You probably know the solutions for those two issues I mentioned above. "resetting timer" is not the solution "keeping screen awake" is not a solution either. – DVN Jan 26 '15 at 22:47
  • I see, so it acts like a dashboard that launches other apps and you want to return to the dashboard automatically when there is no activity. I'm sorry but I don't think there is a way to do this without rooting the device or only launching apps you made yourself so they can be intertwined. – Dave S Jan 26 '15 at 23:02
  • For the issue #1, I am letting the screen off in case of user-inactivity through android's basic setting. And for issue #2, I am trying to wakelock and open an activity. You said wakelock and open activity is not possible but I am seeing this everyday. This is an example. I recorded by myself. https://www.dropbox.com/s/e3bj6t1n5uj0nyy/Video.MOV?dl=0 – DVN Jan 26 '15 at 23:04
  • I mean just think about this for a second, it would be a huge problem if every time I powered on my device it returned to some app I downloaded on it's own. From my understanding this is something deliberately prevented to insure a quality user experience. It's like you are trying to take the place of the OS. – Dave S Jan 26 '15 at 23:07
  • Also, I'm fairly sure what you're seeing in that video is a simple notification that is capable of starting an activity, not an Activity itself. This looks like it might be 5.0 functionality, my device is 4.2.2 which might explain why I haven't seen it. http://developer.android.com/guide/topics/ui/notifiers/notifications.html#Heads-up – Dave S Jan 26 '15 at 23:08
  • Anyway this type of functionality is outside the scope of the apps I design, you could try this guys answer http://stackoverflow.com/questions/9554950/activity-to-be-displayed-even-when-phone-is-in-locked-mode but it's pretty old and may not be possible anymore. – Dave S Jan 26 '15 at 23:17
  • Good that we are on the same page now :) I should have explained more detaily in my post. It's my fault. Anyway, showing an activity while the screen is off is not a new feature. I can even find the related post written in 2010. The related posts say that it should be controlled by BCReceiver but it does not work in my case and that's why I first posted this question. My device will be power-plugged and the app admin can disable/enable the custom idle screen option so don't worry about it – DVN Jan 26 '15 at 23:26
  • If you look at the last question I linked, at one point it was possible but there's this comment "kl=km.newKeyguardLock("INFO"); method has been deprecated since API level 13 :( Any idea on how to deactivate keylock in a Dialog themed activity ? – TiGer Jun 10 '14 at 12:09" So it may have been deprecated. – Dave S Jan 26 '15 at 23:38