3

I have a simple BroadcastReceiver which is suppose to detect when my screen is turning off and on. I'm using Service instead of Activity. I've tried running the service on Android 4.4.2 API 19, and also Android 6.0 API 23.

What am I doing wrong?

Also, according to many answers from StackOverflow and ThinkAndroid you're not suppose to add a service inside the AndroidManifest.

public class BackgroundService extends Service {

@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 ScreenReceiver();
    registerReceiver(mReceiver, filter);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    boolean screenOn = intent.getBooleanExtra("screen_state", false);
    if (!screenOn) {
        System.out.println("SCREEN OFF");
    } else {
        System.out.println("SCREEN ON");
    }
    return START_NOT_STICKY;
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
    // TODO Auto-generated method stub
    return null;
}

My BroadCastReceiver

public class ScreenReceiver extends BroadcastReceiver {

private boolean screenOff;

@Override
public void onReceive(Context context, Intent intent) {
    if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
        screenOff = true;
    } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
        screenOff = false;
    }
    Intent i = new Intent(context, BackgroundService.class);
    i.putExtra("screen_state", screenOff);
    context.startService(i);
  }
}

My AndroidManifest

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

    <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">
        <service
            android:name=".BackgroundService"
            android:enabled="true"
            android:exported="false" />

        <receiver
            android:name=".ScreenReceiver"
            android:enabled="true"
            android:exported="true"></receiver>

    </application>

</manifest>

Logcat

10-24 15:01:00.122 762-762/com.android.systemui E/KeyguardUpdateMonitor: Object tried to add another callback

java.lang.Exception: Called by
    at com.android.keyguard.KeyguardUpdateMonitor.registerCallback(KeyguardUpdateMonitor.java:1104)
    at com.android.keyguard.KeyguardSelectorView.onResume(KeyguardSelectorView.java:347)
    at com.android.keyguard.KeyguardHostView.onScreenTurnedOn(KeyguardHostView.java:1458)
    at com.android.keyguard.KeyguardViewManager.onScreenTurnedOn(KeyguardViewManager.java:500)
    at com.android.keyguard.KeyguardViewMediator.handleNotifyScreenOn(KeyguardViewMediator.java:1960)
    at com.android.keyguard.KeyguardViewMediator.access$2900(KeyguardViewMediator.java:126)
    at com.android.keyguard.KeyguardViewMediator$5.handleMessage(KeyguardViewMediator.java:1601)
    at android.os.Handler.dispatchMessage(Handler.java:110)
    at android.os.Looper.loop(Looper.java:193)
    at android.app.ActivityThread.main(ActivityThread.java:5368)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:828)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:644)
    at dalvik.system.NativeStart.main(Native Method)

UPDATED LOGCAT AFTER CHANGES ACCORDING TO VOLACON_SECRET

10-24 17:00:32.441 12822-12822/? E/cutils-trace: Error opening trace file: 

No such file or directory (2)
10-24 17:00:32.663 12822-12822/? E/memtrack: Couldn't load memtrack module (No such file or directory)
10-24 17:00:32.663 12822-12822/? E/android.os.Debug: failed to load memtrack module: -2
10-24 17:00:36.773 138-744/? E/AudioMTKHardware: setCommonParameters() still have param.size() = 1, remain param = "screen_state=on"
10-24 17:00:37.802 1002-12848/com.microsoft.launcher E/Item: java.sql.SQLException: Unable to run insert stmt on object ms.loop.lib.profile.Application@42a65780: INSERT INTO `application` (`applicationInstalledAt` ,`applicationLastUsedAt` ,`applicationName` ,`applicationUninstalledAt` ,`applicationUpdatedAt` ,`deviceId` ,`locationLabel` ,`packageName` ,`annotations` ,`updatedAt` ,`changedAt` ,`createdAt` ,`entityId` ,`score` ,`persist` ,`createSignalSent` ,`annotationsChanged` ) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
10-24 17:00:40.124 1053-1053/com.google.process.gapps E/NetworkScheduler.SR: Invalid parameter app
10-24 17:00:40.124 1053-1053/com.google.process.gapps E/NetworkScheduler.SR: Invalid package name : Perhaps you didn't include a PendingIntent in the extras?
10-24 17:00:41.684 1067-3062/com.google.android.gms E/Drive.UninstallOperation: Package still installed com.dahlstore.sosbackground2
10-24 17:00:41.923 138-18033/? E/AudioMTKHardware: setCommonParameters() still have param.size() = 1, remain param = "screen_state=off"
10-24 17:00:42.026 1067-12852/com.google.android.gms E/IntentOperationSvc: Failed to instantiate Chimera operation impl, dropping operation
10-24 17:00:42.027 6694-6694/com.android.vending E/Finsky: [1] com.google.android.finsky.wear.bo.a(836): onConnectionFailed: ConnectionResult{statusCode=API_UNAVAILABLE, resolution=null, message=null}
10-24 17:00:42.278 1053-1053/com.google.process.gapps E/NetworkScheduler.SR: Invalid parameter app
10-24 17:00:42.278 1053-1053/com.google.process.gapps E/NetworkScheduler.SR: Invalid package name : Perhaps you didn't include a PendingIntent in the extras?
10-24 17:00:43.576 12905-12905/com.whatsapp E/dalvikvm: Could not find class 'android.support.v4.app.g', referenced from method android.support.v4.app.ab.a

My build.gradle (Module:app)

apply plugin: 'com.android.application'

android {
    compileSdkVersion 24
    buildToolsVersion "25.0.0"

defaultConfig {
    applicationId "com.dahlstore.sosbackground2"
    minSdkVersion 15
    targetSdkVersion 24
    versionCode 1
    versionName "1.0"
}
buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:24.2.1'
}
Cœur
  • 37,241
  • 25
  • 195
  • 267
user3506
  • 109
  • 1
  • 12
  • I read in some questions that `SCREEN_OFF` is a protected boradcast and broadcast receiver needs to dynamically register for it instead of in manifest. Were you able to solve the problem? – fsljfke Aug 28 '20 at 00:37

2 Answers2

2

you need to include service and receiver in manifest.....as like that

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.dahlstore.sosbackground">
    <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">

  <service android:name=".BackgroundService"/>

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

</application>
</manifest>

Hey try this Broadcastreceiver.......

public class ScreenReceiver extends BroadcastReceiver {

private boolean screenOff;
@Override
public void onReceive(Context context, Intent intent) {
    // TODO Auto-generated method stub
    Log.i("[BroadcastReceiver]", "MyReceiver");

    if(intent.getAction().equals(Intent.ACTION_SCREEN_ON)){
        Log.i("[BroadcastReceiver]", "Screen ON");
    }
    else if(intent.getAction().equals(Intent.ACTION_SCREEN_OFF)){
        Log.i("[BroadcastReceiver]", "Screen OFF");
       }
     Intent i = new Intent(context, BackgroundService.class);
     i.putExtra("screen_state", screenOff);
     context.startService(i);
    }
  }
Amir Dora.
  • 2,831
  • 4
  • 40
  • 61
  • Thank you very much! Per your suggestion I have now changed the code in the question, but It still throws an exception, as you can see by the new logcat.. – user3506 Oct 24 '16 at 13:06
  • Thank God! Now I get a more reasonable logcat.. I'll try to figure out where I'm suppose to use the PendingIntent.. Or perhaps you already now? – user3506 Oct 24 '16 at 14:05
  • I see you've made your own project to be able to help me,,thank you so much! Unfortunately it doesn't work neither on my emulator, my S7 Edge (Android 6.0.1) or my unknown brand phone (Android 4.4.2). I'm uploading the latest logcat again.. I'm not sure if it could be caused of me using Android Studio. Perhaps I should download and try Eclipse. Since you have a working example of the project could you send it to me? – user3506 Oct 24 '16 at 15:03
  • I think I know the problem now. When I lock/unlock screen multiple times, I get following error: E/KeyguardUpdateMonitor: Object tried to add another callback java.lang.Exception: Called by Do you think the keyguard tries to prevent me getting the receiver to work? – user3506 Oct 24 '16 at 15:13
  • @Secret_Volcano you are not changing variable screenOff when you pass in putExtra. – donmj Sep 03 '21 at 01:50
2

As stated in answer above, you should include Service and BroadcastReceiver in manifest. But, you register your BroadCastReceiver dynamically in Service and never unregister it. If you want to receive notifications all the time, you should register receiver in manifest with corresponding internt filter. Or, unregister receiver in onTerminate() method of Service.

Alex Shutov
  • 3,217
  • 2
  • 13
  • 11
  • Okay, so my IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON); don't do the same job? – user3506 Oct 24 '16 at 13:08
  • This question argues that you should not use it in the manifest – user3506 Oct 24 '16 at 13:17
  • http://stackoverflow.com/questions/1588061/android-how-to-receive-broadcast-intents-action-screen-on-off – user3506 Oct 24 '16 at 13:17
  • you can either use it in manifest, or, register and unregister broadcast receiver dynamically when service start (it will be notified only when service is running) – Alex Shutov Oct 24 '16 at 14:02
  • Okay, if I understand you correct, the broadcast reciever would then have to be registered in the ScreenReceiver.class right? Because I did already have a IntentFilter created in my OnCreate method inside the BackroundService.class? – user3506 Oct 24 '16 at 14:13
  • 1
    if you want to receive events all time, no matter whether your Service is running or not, declare receiver in manifest, otherwise register and unregister it dynamically. Here is tutorial: http://www.vogella.com/tutorials/AndroidBroadcastReceiver/article.html – Alex Shutov Oct 24 '16 at 16:51