PowerManager does not trigger when Activity is started by the AlarmManager - android

I'm an artist and I'm working on an installation with a couple Android smartphones. I'm not an expert in Java/Android programming. I'm just learning by doing and stackoverflow is very helpful. I'm using different devices with different Android versions (2.3-4.4). The devices are constantly powered via usb. The app should run only during opening hours of an exhibition and resort automatically the next day. For scheduling I'm using the AlarmManager. Currently I have problems with the automatic restart on some of the devices, on others it work as expected.
Here are some snippets important form the scheduling:
In the AndroidManifest.xml I have the following permissions set:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
Among others the WAKE_LOCK permission is set.
onCreate starts with:
#Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_start);
pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
if (android.os.Build.VERSION.SDK_INT > 12) {
if (pm != null) {
wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK| PowerManager.ACQUIRE_CAUSES_WAKEUP
| PowerManager.ON_AFTER_RELEASE, "MyWakeLock");
}
}else {
// unlock screen and switch screen back light on
// for Android 2.3 - disable for higher Versions
KeyguardManager km = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
final KeyguardManager.KeyguardLock kl;
if (km != null) {
kl = km.newKeyguardLock("MyKeyguardLock");
kl.disableKeyguard();
}
if (pm != null) {
wakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK| PowerManager.ACQUIRE_CAUSES_WAKEUP
| PowerManager.ON_AFTER_RELEASE, "MyWakeLock");
}
}
wakeLock.acquire();
Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler(this));
PowerManager.ACQUIRE_CAUSES_WAKEUP is used, which to my understanding should put the screen on irrespectively of it's state.
In onDestroy I'm using:
PendingIntent pendingIntent = PendingIntent.getActivity(MyApplication.getInstance().getBaseContext(),0,intent,PendingIntent.FLAG_ONE_SHOT );
AlarmManager alarmManager = (AlarmManager) MyApplication.getInstance().getBaseContext().getSystemService(Context.ALARM_SERVICE);
if (alarmManager != null) {
alarmManager.set(AlarmManager.RTC_WAKEUP , System.currentTimeMillis()+delayInMillis,pendingIntent);
Date date = new Date(System.currentTimeMillis()+delayInMillis);
SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy ' 'HH:mm:ss.SSS");
Log.i("** restart at **",dateFormat.format(date));
}
This snippet is executed when finish() is called because of 'exhibition closing time reached'. As said, this works on most of the devices. On those devices, on which the app seems not to restart automatically, the app starts as soon as the screen is put on e.g. by pressing the power button or disconnecting usb (e.g. for connecting the laptop to read the logcat.) In the logcat I find something like (LG P-875 Android 4.1.3 should start at 14:00:xx)
03-25 14:00:53.516 677-748/? I/ActivityManager: START {flg=0x14000004 cmp=eu.karin_daum.daum.reality/.Start (has extras) u=0} from pid -1
03-25 14:00:53.546 677-748/? I/ActivityManager: Start proc eu.karin_daum.daum.reality for activity eu.karin_daum.daum.reality/.Start: pid=31324 uid=10099 gids={3003, 1015, 1028}
To me, this looks o.k., however the PowerManager did not react. In this example, the PowerManager reacted at the moment when I disconnected usb to connect my laptop some minutes later:
03-25 14:04:13.986 677-691/? D/PowerManagerService: userActivity mLastEventTime=201702573 time=201861160 mUserActivityAllowed=true mUserState=0x0 mWakeLockState=0x0 mProximitySensorActive=false timeoutOverride=-1 force=false
03-25 14:04:13.986 677-691/? D/PowerManagerService: setPowerState: mPowerState=0x0 newState=0x7 noChangeLights=false reason=2
03-25 14:04:13.986 677-691/? D/PowerManagerService: setPowerState: mPowerState=0 newState=7 noChangeLights=false
03-25 14:04:13.996 677-691/? D/PowerManagerService: setTimeoutLocked now=201861160 timeoutOverride=-1 nextState=3 when=201862660
03-25 14:04:14.006 677-747/? D/PowerManagerService: Perflock acquired: 7, 1
03-25 14:04:14.006 677-750/? D/PowerManagerService: offMask=0x0 dimMask=0x0 onMask=0x0 difference=0x1 realDifference=0x0 forceState=0x1
03-25 14:04:14.096 677-1038/? D/PowerManagerService: pid=31324 tag=MyWakeLock mAcquireCausesWakeupTime=201861278 diffTime=149932030
03-25 14:04:14.096 677-1038/? D/PowerManagerService: setPowerState: mPowerState=0x7 newState=0x7 noChangeLights=false reason=3
In the second but last line the request which I send in onCreate seems to be treated (tag=MyWakeLock)
During writing I just realise that the PowerManager did react automatically in the next test but only with a delay of about 10 minutes w.r.t. the AlarmManager action.
What am I doing wrong? Do I have to release the WakeLock in onDestroy? Is there a solution to the problem?

Problem solved. There have been two reasons why it was not working as I expected on all devices:
I was following the proposal made in several threads using PendingIntent.getActivity to start the activity directly instead of using a BroadcastReceiver instead. Apparently doing so would not guarantee to get control on the screen. After reading again the information on the Android Developer pages I implemented a BroadcastReceiver:
public class StartupReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if(intent!=null){
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl;
if (android.os.Build.VERSION.SDK_INT < 13) {
wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP
| PowerManager.ON_AFTER_RELEASE, "**StartupReceiver**");
KeyguardManager km = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
final KeyguardManager.KeyguardLock kl;
if (km != null) {
kl = km.newKeyguardLock("MyKeyguardLock");
kl.disableKeyguard();
}
} else {wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP
| PowerManager.ON_AFTER_RELEASE, "**StartupReceiver**");
}
wl.acquire();
Intent i = new Intent(context, Start.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
wl.release();
}
}}
This works correctly on all devices with SDK<19
In order to get it also working on SDK=19 I had to change alarmManager.set to alarmManager.setExact, i.e.
Intent intent1 = new Intent(this,StartupReceiver.class);
PendingIntent pendingIntent1 = PendingIntent.getBroadcast(MyApplication.getInstance().getBaseContext(),0,intent1,PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmManager = (AlarmManager) MyApplication.getInstance().getBaseContext().getSystemService(Context.ALARM_SERVICE);
if (alarmManager != null) {
if(android.os.Build.VERSION.SDK_INT<19) {
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + delayInMillis, pendingIntent1);
}else{
alarmManager.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + delayInMillis, pendingIntent1);
}
Date date = new Date(System.currentTimeMillis()+delayInMillis);
SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy ' 'HH:mm:ss.SSS");
Log.i("** restart at **",dateFormat.format(date));
}
These changes solved the problem

Related

How to keep sceen on in Android?

How to keep screen on in Android?
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse("tel:" + Uri.encode("+86 212312142")));
startActivityForResult(callIntent, 100);
I want the screen keep turn on, even in the phone dial activity. (No Dim)
I try this
PowerManager pm = (PowerManager) act.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "XXXX");
wakeLock.acquire();
I think you need to add extras permission to use wakelock
<uses-permission android:name="android.permission.WAKE_LOCK" />
but instead of wakelock I recommend you to use this :
#Override
protected void onCreate(Bundle savedBundle) {
super.onCreate(savedBundle);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
there is a good discussion about not using wakelock here -> Force Screen On

AlarmManager awakes Activity from Sleep but the Activity Closes Undesirably

I have an AlarmManager setting an alarm:
Intent intent = new Intent(mContext, AwakeActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(mContext, PENDING_INTENT_ID, intent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(mContext.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + futureTime, pendingIntent);
and the alarm works as expected. When the alarm goes off I have AwakeActivity open. This also works as expected. In AwakeActivity I have:
#Override
public void onCreate(Bundle savedInstanceState)
{
// main
super.onCreate(savedInstanceState);
// inflate
setContentView(R.layout.awake);
Window window = this.getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD); //relates to IInputConnectionWrapper issue - but not cause of instant close of app
window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
Here is my Manifest definition:
<activity
android:name=".AwakeActivity"
android:label="#string/activityAwake"
android:configChanges="keyboardHidden|orientation"
android:theme="#android:style/Theme.NoTitleBar"
android:screenOrientation="portrait"
android:launchMode="singleInstance"
android:noHistory="true"
>
</activity>
The issue I'm having is that when AwakeActivity starts up it doesn't stay open. It instantly closes. But... this only happens if the phone is in sleep mode, if I leave the screen on and AwakeActivity opens via the alarm - all is well.
The other but... is that this happens on my Droid X running 2.3.4 and not my Galaxy Nexus 4.2.2. I've been at this for a while and feel as though I've done things properly.
What am I missing here? Any ideas?
I myself was running into a similar issue. On some devices the device would wake up and on others the activity would close. Have you tried using a WakeLock to see if the same thing happens?
So declare a global wakelock variable:
PowerManager.WakeLock wakelock;
In your onCreate method do something like:
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
wakelock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK
| PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.SCREEN_BRIGHT_WAKE_LOCK
| PowerManager.ON_AFTER_RELEASE, "tag");
wakelock.acquire();
Now you just have to release the wakelock, say in your onPause method:
#Override
protected void onPause() {
super.onPause();
wakelock.release();
}
Also you need to include this in your manifest file:
<uses-permission android:name="android.permission.WAKE_LOCK"/>

Proximity sensor with wakelock issue: can't turn on screen again

I've been looking around for the last days and none of the answers to the questions made have helped me and I'm bumping my head with something that perhaps is simple to solve .... I want to work with the proximity sensor and what I'm doing is that if I put the finger on the sensor it turns off the screen and if I remove the finger away it turns back on the screen! I'm sucessfully turning off the screen and I'm getting the "Log.i("info", "trying to turn on!")" message when I remove the finger but somehow the screen doesn't turn on .... I've tried with wakelock (commented) and with flags with no sucess! If I remove the finger the lights on the keypad turn on but the screen won't .. If I press the power button two times it turns on the screen sucessfully! Can anyone give me an help with it? :(
#Override
public void onSensorChanged(SensorEvent event) {
if(event.sensor.getType()==Sensor.TYPE_PROXIMITY){
ProximityReading.setText("\nProximity Sensor Reading:" + String.valueOf(event.values[0]));
}
if(event.values[0] == 0) {
WindowManager.LayoutParams params = getWindow().getAttributes();
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
params.screenBrightness = 0f;
getWindow().setAttributes(params);
} else {
WindowManager.LayoutParams params = getWindow().getAttributes();
params.screenBrightness = 1f;
getWindow().setAttributes(params);
/*powermanager = (PowerManager) getSystemService(Context.POWER_SERVICE);
wakeLock = powermanager.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP, "TAG");
wakeLock.acquire();
Log.i("info", "trying to turn on!");
}
}
if you want turn screen on,you can use the API such as "TurnScreenOn" in PowerManager,or use ACQUIRE_CAUSES_WAKEUP combined with FULL_WAKE_LOCK
I use the following method to unlock the phone,lighten it up and then reenable the keyguard lock.
public void unlockAndPowerup(){
KeyguardManager km = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
final KeyguardManager.KeyguardLock kl = km.newKeyguardLock("MyKeyguardLock");
kl.disableKeyguard();
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
WakeLock wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK
| PowerManager.ACQUIRE_CAUSES_WAKEUP
| PowerManager.ON_AFTER_RELEASE, "MyWakeLock");
wakeLock.acquire();
wakeLock.release();
kl.reenableKeyguard();
}
Your procedure is wrong. It may work on some devices by chance, but that's not the way to do it.
FLAG_TURN_SCREEN_ON is supposed to be applied on the onCreate method of an activity. You need to modify your app logic.
Your screen off technique is incorrect. You're modifying brightness, that's a hacky way, and may not turn off screen at all, and drain battery.
You need to achieve it via Device Admin permission. That's the official way to do it
Locking sample code
public static void lockNow(Context c) {
DevicePolicyManager dpm = (DevicePolicyManager)c.getSystemService(Context.DEVICE_POLICY_SERVICE);
if(dpm.isAdminActive(new ComponentName(c.getApplicationContext(),DeviceAdmin.class)))
dpm.lockNow();
}
DeviceAdmin.java
import android.app.admin.DeviceAdminReceiver;
public class DeviceAdmin extends DeviceAdminReceiver {
}
In the manifest
<receiver
android:name=".admin.DeviceAdmin"
android:permission="android.permission.BIND_DEVICE_ADMIN" >
<meta-data
android:name="android.app.device_admin"
android:resource="#xml/admin" />
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
</intent-filter>
</receiver>
And asking for Device Admin permission
private void askAdminPerm(){
Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
new ComponentName(root.getContext(), DeviceAdmin.class));
intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, getString(R.string.lock_msg_big));
startActivity(intent);
}

Android: Which events do wakeup a device

I have written an android application and now there is a problem.
If my application is running and I power off my device, then sometimes it just wakes up after about 8 seconds and then the screen is on and it shows my application again.
My question is:
Which events or processing constraints (like handling broadcast intents) do wakeup a device?
Edit: Will an alarm with RCT_WAKEUP turn on the device screen?
Thanks in advance!
The AlarmManager won't actually turn the screen on for you. You can use a wakelock instead.
PowerManager.WakeLock wakelock;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
.........
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
wakelock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK
| PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "AlarmReceiver");
wakelock.acquire();
}
When you're done with the activity just be sure to release the wakelock:
#Override
protected void onStop() {
super.onStop();
wakelock.release();
}
You also need to add the wake lock permission in your manifest file:
<uses-permission android:name="android.permission.WAKE_LOCK"/>
Alternatively, if you don't want to have to include this extra permission you can use the following code in your activity instead of using a wakelock:
this.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN |
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD |
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON |
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

Lock Android Phone after user dials a phone number

I am developing a security application whereby, if a user dials a phone number that is not frequently called and he has never called before, the user will have to reauthenticate himself. For this purpose I want to lock the phone after checking the phone number.
public class outgoingCalls extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
Log.v("onReceive", "In onReceive()");
if (confidence == 0) {
Log.v("onReceive","confidence zeroed");
Intent i = new Intent();
i.setClassName("abc.xyz.SECURITY","abc.xyz.SECURITY.lockActivity");
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
In this new Activity lockActivity, I need to lock the phone where I have commented // LOCK PHONE
public class lockActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.v("lock","lockActivity onCreate method called");
// setContentView(R.layout.main);
Log.v("lock","locking");
// LOCK PHONE
}
}
The phone is not getting locked with the methods I have tried. These include the following:
1. KeyguardManager mgr = (KeyguardManager) getSystemService(Activity.KEYGUARD_SERVICE);
KeyguardLock lock = mgr.newKeyguardLock("edu.Boston.SECURITY.lockActivity");
((KeyguardLock) lock).reenableKeyguard();
2. PowerManager manager = (PowerManager) getSystemService(Context.POWER_SERVICE);
manager.goToSleep(100);//int amountOfTime
3. PowerManager.WakeLock wl = manager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Tag");
wl.acquire();
wl.release();
4. WindowManager.LayoutParams params = getWindow().getAttributes();
params.screenBrightness = 0;
getWindow().setAttributes(params);
Android manifest file has below permissions
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
<uses-permission android:name="android.permission.WAKE_LOCK" />
Why am I not able to lock the phone? Any pointers?
Thanks a lot in advance for your help. Appreciate it!
Try creating a DevicePolicyManager
http://developer.android.com/training/enterprise/device-management-policy.html
and then call:
DevicePolicyManager mDPM = (DevicePolicyManager)context.getSystemService(Context.DEVICE_POLICY_SERVICE);
mDPM.lockNow();

Categories

Resources