-2

I have been trying to write a library which i can later use for my other apps. The problem is,

Once my app(main app) says my library to monitor it. The library will have to check every time the app(main app) enters to foreground. And each time it has to show a lock screen. All these have to be handled in the library.

My approach: I tried getting running tasks info by using getRunningTasks in a intent service. But this method is deprecated from lollipop. (I need a work around for this.)

Note: I don't want to check every time the any app enters foreground or not. If there will be a way to get notified just when my app enters foreground will be helpful(All the handling should happen in the library, my main app will just say to monitor or not monitor i.e a boolean thats it).

Thanks in advance.

Praveen Kumar C
  • 423
  • 3
  • 8
  • https://developer.android.com/reference/android/app/Application.html#registerActivityLifecycleCallbacks(android.app.Application.ActivityLifecycleCallbacks) – Eugen Pechanec Mar 13 '17 at 08:19
  • @EugenPechanec As I have mentioned I don't want to add any line of code to my main app. But I think when I use registerActivityLifecycleCallbacks i might need to write code in my main app for it to get my callbacks received to my library. If I have misunderstood, Can you please elaborate your approach. – Praveen Kumar C Mar 13 '17 at 08:38
  • you can message your library (service) that your app is in foreground from your app. There are callbacks in the activity lifecycle which message that activity is in front now. – Vladyslav Matviienko Mar 13 '17 at 08:46

1 Answers1

0

You can register Application.ActivityLifecycleCallbacks which will notify you each time such an event happens.

When and where to register the callbacks without touching the app module? Write a custom no-op content provider. A content provider runs by default only in the main process of an app which is where all UI should be anyway.

class MyInitProvider : ContentProvider() {
    override fun onCreate(): Boolean {
        val app = context.applicationContext as Application

        // Do what you need to do here.

        return false // Indicate the provider is not to be used further.
    }

    // All other abstract method implementations return either 0 or null.
}

Register the content provider in the library AndroidManifest.xml:

<application>
    <provider
        android:name=".MyInitProvider"
        android:authorities="${applicationId}.mylibraryinitprovider"
        android:exported="false"/>
</application>

Read more about content providers: https://developer.android.com/reference/android/content/ContentProvider.html

The callbacks are invoked on main thread. Don't do heavy work there.

Eugen Pechanec
  • 37,669
  • 7
  • 103
  • 124
  • Just to be clear, I should be writing all this class to my library, Thats what you are suggesting right? – Praveen Kumar C Mar 13 '17 at 09:12
  • 1
    1.) Can you please tell me how would I register Application.ActivityLifecycleCallbacks in my library so I can receive callbacks on whenever my app enters foreground. 2.) Does this content provider gets called every time the callback is received from the application callbacks? – Praveen Kumar C Mar 13 '17 at 09:20
  • 1) https://developer.android.com/reference/android/app/Application.html#registerActivityLifecycleCallbacks(android.app.Application.ActivityLifecycleCallbacks) 2) No. A content provider is set up once when the app starts (before `Application.onCreate`). If you register callbacks here, they will be registered once. – Eugen Pechanec Mar 13 '17 at 09:25
  • What if I need to show the lock screen even when the app is resumed from background(i.e from running app list). In that case this content provider wont be called right? – Praveen Kumar C Mar 13 '17 at 09:32
  • We've been taught that `Application.onCreate` is the first thing to run in our apps. Well content providers are initialized before that. You don't get any more control than this. – Eugen Pechanec Mar 13 '17 at 09:36
  • I am clear with the whole logic now, but i still could not figure out where to register Application.ActivityLifecycleCallbacks in my library. I tried creating a custom Application class and implemented Application.ActivityLifecycleCallbacks but the custom Application class is not recognised in my library manifest file. – Praveen Kumar C Mar 13 '17 at 10:14
  • `ContentProvider.getContext()` gives you a `Context` and `context.getApplicationContext()` is an `Application`. Read the code in the answer. The whole point of this is that you don't interfere with the app module itself. – Eugen Pechanec Mar 13 '17 at 10:26
  • I am not able to get ContentProvider.getContext? – Praveen Kumar C Mar 13 '17 at 10:32
  • Basically, I'll leave up to you ensuring that you don't show the lock screen everytime the user rotates the phone or navigates to a different activity within your app. Or even infinite lock screens because that's an activity in your app as well. – Eugen Pechanec Mar 13 '17 at 10:34
  • I get that, I just need to show the lock screen whenever the app comes to foreground from background or a new launch. But the problem here is I am not able to get the ContentProvider.getContext, Seems like no getContext method is available. – Praveen Kumar C Mar 13 '17 at 10:46
  • Always verify before asking. https://developer.android.com/reference/android/content/ContentProvider.html It's not a static method. This is security stuff, are you up to the challenge? – Eugen Pechanec Mar 13 '17 at 10:54
  • Thanks for the answer. Tried it in my app and it works fine. – Praveen Kumar C Mar 16 '17 at 13:43