How to keep Screen On while looping urls in the Browser.apk? - android

Currently I am using IntentService to loop urls in the Browser.apk. I am running it until the battery drains. Here is my dirty code. =)
#Override
protected void onHandleIntent(Intent intent) {
int size = intent.getStringArrayExtra("addresses").length;
int counter = sp.getInt("counter", 0);
String address = intent.getStringArrayExtra("addresses")[counter];
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(address));
i.setFlags(Intent.FLAG_FROM_BACKGROUND | Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
counter++;
if(counter == size) {
counter = 0;
}
spe.putInt("counter", counter);
spe.commit();
}
I tried to use wakelock but not all devices stays awake. It is working with Motorola Xoom but not in Thinkpad tablet slate.
Do you know other option other than using the wakelock. Or How should I properly implement the wakelock?
Can I tell the Browser that I should keep the Screen On while loading the urls? By using intent or other means.

For open the device screen, if the device is in sleep mode, use the code below:
//acquireLock(context);
PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
boolean isScreenOn = pm.isScreenOn();
Log.e("screen on.................................", ""+isScreenOn);
if(isScreenOn==false)
{
WakeLock wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK |PowerManager.ACQUIRE_CAUSES_WAKEUP |PowerManager.ON_AFTER_RELEASE,"MyLock");
wl.acquire(10000);
WakeLock wl_cpu = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,"MyCpuLock");
wl_cpu.acquire(10000);
}

Best solution here: https://stackoverflow.com/a/2134602/1316372
#Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}

Related

Activity does not start until the screen is turned on

My service starts an Activity like this:
Intent intent = new Intent(context, CallMonitor.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
this happens in CallMonitor.onCreate():
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
On most devices, the activity (called up from service) wakes up the device, turns on the screen and is displayed.
But - for example - on Galaxy Tab 4, the activity is only called if the screen is already switched on.
If the screen is switched off and the service calls up the activity, it is displayed with a delay - It will be displayed immediatly after turning the screen on.
There is also a voice output in the activity. When the Galaxy S4 is switched off, it will not be played back - but immediatly after turning the screen on again.
Any suggestions?
I don't want to use WakeLock!
It looks like that's a device limitation and I don't know how you could work around that without using a WakeLock. We have a really old piece of code which you could modify to your needs which pretty much always worked for us:
public static void bringToFront() {
try {
PowerManager pm = (PowerManager) MainActivity.getAppContext().getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.ON_AFTER_RELEASE, "ALARM");
wl.acquire();
KeyguardManager keyguardManager = (KeyguardManager) MainActivity.getAppContext().getSystemService(Activity.KEYGUARD_SERVICE);
KeyguardManager.KeyguardLock lock = keyguardManager.newKeyguardLock(KEYGUARD_SERVICE);
lock.disableKeyguard();
if (MainActivity.getAppActivity() != null) {
MainActivity.getAppActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
}
} catch(Exception e){
e.printStackTrace();
Log.w(TAG, "bringToFront Err: "+e.toString());
}
}

Android turn on the screen

I making the application where an activity launch is scheduled by AlarmManager. I would like to appear even if the screen is turned off and device is locked.
To achive this a set the Window flags
final Window win = getWindow();
win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
win.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
| WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON);
And try to obtain lock for the screen
if(_lock == null)
{
PowerManager pm = (PowerManager)App.getAppContext()
.getSystemService(Context.POWER_SERVICE);
_lock = pm.newWakeLock(
PowerManager.FULL_WAKE_LOCK, "ScreenOn");
_lock.acquire();
}
The _lock is PowerManager.WakeLock which is released in onPause
protected void onPause()
{
if(_lock != null)
{
_lock.release();
}
}
This code is executed in onCreate and onRestart. Everything works OK if the activity is not launched yet.
But if it was launched earlier the screen is not turned off.
onRestart is called first
onResume is then called
onPause is called immediately
So the activity is not launched. My question is how to turn on the screen in such situation. (I am using API 15).
I came up with the solution. I created a new activity which will be trying to turn on the screen in the onCreate() and then wait until it is turned on. When the screen is ok it will launch the activity which should be displayed. To make the Android always create this activity
public class TurnOnScreen extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
if (pm.isScreenOn()) openActivity();
else {
registerReceiver(mScreenOnReceiver, new IntentFilter(
Intent.ACTION_SCREEN_ON));
reciever_registered = true;
turnScreenOn();
}
}
#Override
public void onDestroy() {
super.onDestroy();
if (reciever_registered) {
unregisterReceiver(mScreenOnReceiver);
reciever_registered = false;
}
}
private boolean reciever_registered = false;
private final BroadcastReceiver mScreenOnReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
openActivity();
}
};
private void openActivity() {
Intent intent = new Intent();
// ....
finish();
}
private void turnScreenOn() {
final Window win = getWindow();
win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
win.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
| WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON);
}
}
I am still looking for explanations why the screen is not turned on in onRestart.
Have you heard of "The Lighted Green Room"? Check out the code below, it may be what you're looking for.
http://code.google.com/p/ch-bfh-fbi-mobicomp-2011/source/browse/ch_simplix_android_repetitive_service/src/com/androidbook/longrun/LightedGreenRoom.java?spec=svn38&r=37
Just use your code :
final Window win = getWindow();
win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
in onCreate() only and remove all those other Activity-Cycle methods if they are not doing anything else then this.
I don't think you need any more code to use to perform it.

Unlock device, display a text, then lock again

For the need of my application, I need to display a message on the screen even if the lockscreen is enabled, then wait 3 seconds, than I have to lock again the phone as I don't want it to make unwanted phone calls in your pockets.
First part is easy:
if (PreferenceManager.getDefaultSharedPreferences(
getBaseContext()).getBoolean("wake", false)) {
KeyguardManager kgm = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
boolean isKeyguardUp = kgm.inKeyguardRestrictedInputMode();
WakeLocker.acquire(ProtoBenService.this);
Intent myIntent = new Intent(ProtoBenService.this,LockActivity.class);
myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (isKeyguardUp) {
ProtoBenService.this.startActivity(myIntent);
} else
Toast.makeText(ProtoBenService.this.getBaseContext(), intention, Toast.LENGTH_LONG).show();
WakeLocker.release();
}
With this class:
public abstract class WakeLocker {
private static PowerManager.WakeLock wakeLock;
public static void acquire(Context ctx) {
if (wakeLock != null) wakeLock.release();
PowerManager pm = (PowerManager) ctx.getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK |
PowerManager.ACQUIRE_CAUSES_WAKEUP |
PowerManager.ON_AFTER_RELEASE, "CobeIm");
wakeLock.acquire();
}
public static void release() {
if (wakeLock != null) wakeLock.release(); wakeLock = null;
}
}
And the Activity:
public class LockActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
TextView tv = new TextView(this);
tv.setText("This is working!");
tv.setTextSize(45);
setContentView(tv);
Runnable mRunnable;
Handler mHandler = new Handler();
mRunnable = new Runnable() {
#Override
public void run() {
LockActivity.this.finish();
}
};
mHandler.postDelayed(mRunnable, 3 * 1000);
}
}
So, this is nice, the phone can display my text!
The only problem comes when I want to lock again the phone, it seems that locking the phone is protected by the system...
Programmatically turning off the screen and locking the phone
how to lock the android programatically
I think that my users won't understand the Device Admin and won't be able to activate it. Is there any workaround to lock the screen without the Device Admin stuff?
I used the following method for locking and unlocking phone.
initializing
KeyguardLock keyguard;
KeyguardManager km = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
keyguard = km.newKeyguardLock("MyApp");
to unlock phone
keyguard.disableKeyguard();
to lock phone again
keyguard.reenableKeyguard();
to turn screen on
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
and dont forget to use the following permission
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
I am pretty sure that you have to use the Device Admin Features to lock the screen.
protected static void initiateDeviceLock(Context context) {
ComponentName componentName = new ComponentName(context, MyDeviceAdminReceiver.class);
DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
boolean active = dpm.isAdminActive(componentName);
Log.i(context.getClass().getSimpleName(), "Active (in initiateDeviceLock) = " + String.valueOf(active));
if (active) {
dpm.lockNow();
}
}
To help the user's setup the Device Admin features you can take them to the settings page:
Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
ComponentName componentName = new ComponentName(TestActivity.this, MyDeviceAdminReceiver.class);
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, componentName);
startActivityForResult(intent, CODE);

Android: service for gps / sensor logging

I m looking for the best practice to implement a service for logging gps- or other sensor-values periodically (every 10-60 sec). The service should deal with the standby mode, when the phone goes asleep.
Any help (pseudo-code or tutorials) is very much appreciated!
It looks like it is impossible to let the orientation sensors work constantly for hours even though the device may fall asleep (refer to http://code.google.com/p/android/issues/detail?id=3708#makechanges
As soon as the display goes off, the sensors will do alike... :(
I now implemented a wakelock (needs permission)
<uses-permission android:name="android.permission.WAKE_LOCK" />
in conjunction with a timer and a broadcastreciever that will turn the display back on again. This is of course crazy for battery life but I found no other way so far.
This is my onCreate method in the service:
#Override
public void onCreate() {
mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
CONTEXT = this;
PowerManager pm = (PowerManager) CONTEXT.getSystemService(Context.POWER_SERVICE);
this.mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "my tag");
mWakeLock.acquire();
Log.d(TAG, "Wakelock acquired");
// 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);
}
this the onStart method of the service:
#Override
public void onStart(Intent intent, int startid) {
Toast.makeText(this, "My Service Started", Toast.LENGTH_SHORT).show();
Log.d(TAG, "onStart");
boolean screenOn = intent.getBooleanExtra("screen_state", false);
if (!screenOn) {
Log.d(TAG, "Screen is on");
} else {
Log.d(TAG, "Screen is off");
Timer timer = new Timer("DigitalClock");
timer.schedule(new TimerTask() {
#Override
public void run() {
Log.d(TAG,"Waiting 1 sec for switching the screen back on again...");
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP,
"my tag");
mWakeLock.acquire();
}
}, 1000);
mWakeLock.acquire();
}
}
and this is the BroadcastReceiver class:
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, MyService.class);
i.putExtra("screen_state", screenOff);
context.startService(i);
}
}
This workaround will also do with a device UN-plugged from the debugger via USB (I first had an issue with this).
Please let me know if you have a better solution, or if there is fix in 2.3. Thanx!
Here's a link to a tutorial on how to use Android Services. LINK
Here's a link to a tutorial on how to read data from sensors. LINK

How can I tell if the screen is on in android?

In Android 2.2 (Level 7) the function PowerManager.IsScreenOn() returns a boolean that is true if the screen is turned on and false if the screen is turned off. I am developing code for Android 1.5 (Level 3). How do I accomplish the same task in older versions of Android?
I do not want to turn the screen on or off in my code. I just want to know what it is.
There's a better way than using BroadcastReceivers:
// If you use API20 or more:
DisplayManager dm = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
for (Display display : dm.getDisplays()) {
if (display.getState() != Display.STATE_OFF) {
return true;
}
}
return false;
// If you use less than API20:
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
if (powerManager.isScreenOn()){ return true; }
Note that Display.getState() can also return STATE_DOZE and STATE_DOZE_SUSPEND which means that the screen is on in an special way. More info on Display.getState() and his return values here: http://developer.android.com/reference/android/view/Display.html#getState()
Also note that although official documentation recommends using isInteractive() instead of isScreenOn(), if you really want to know the status of the screen, Display.getState() is a better option because of the 'special' conditions that sets the screen on while the device is not interactive.
This is how you should do it:
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
boolean result= VERSION.SDK_INT>=VERSION_CODES.KITKAT_WATCH&&powerManager.isInteractive()||VERSION.SDK_INT<VERSION_CODES.KITKAT_WATCH&&powerManager.isScreenOn();
return result;
I'm using the following function:
public boolean isInteractive() {
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH
? powerManager.isInteractive()
: powerManager.isScreenOn();
}
You can accomplish this by setting up broadcast receivers for ACTION_SCREEN_ON and ACTION_SCREEN_OFF.
I'm posting this because on a HUAWAI Prism II Android 4.1.1 (API 16) device the game I'm working on had the following annoying behavior:
I'm displaying my main menu which has some animation in a SurfaceView and plays a sound once in a while.
The device goes idle, dims, and then goes dark.
It calls onDestroy on my Activity, and then while the screen is off creates my Activity again, calling onCreate!
So the problem is my animations and sounds are playing while the screen is off. What I really want to happen is for my animation loop to not run at all if the screen is off. Broadcast receivers don't work because I can't store the state from the last time the screen went off. I thought about some hacks involving static booleans but it just seemed like a kluge that may not work and have horrible edge cases. The screen is already off when my Activity is created again, so I won't get an event through the broadcast receiver that my screen is off.
I solved this using both a broadcast receiver and the code listed above.
In my onCreate, I create the broadcast receiver. This will control my animation loop when the screen turns on and off.
if (mScreenReceiver == null) {
mScreenIntentFilter = new IntentFilter(Intent.ACTION_SCREEN_ON);
mScreenIntentFilter.addAction(Intent.ACTION_SCREEN_OFF);
mScreenReceiver = new ScreenReceiver();
registerReceiver(mScreenReceiver, mScreenIntentFilter);
}
public class ScreenReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
controlAnimLoop(false, false, true);
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
controlAnimLoop(false, false, false);
}
}
}
In my controlAnimLoop, I check isScreenOn, which is this code:
private boolean isScreenOn() {
if (android.os.Build.VERSION.SDK_INT >= 20) {
// I'm counting
// STATE_DOZE, STATE_OFF, STATE_DOZE_SUSPENDED
// all as "OFF"
DisplayManager dm = (DisplayManager) getSystemService(Context.DISPLAY_SERVICE);
for (Display display : dm.getDisplays ()) {
if (display.getState () == Display.STATE_ON ||
display.getState () == Display.STATE_UNKNOWN) {
return true;
}
}
return false;
}
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
return powerManager.isScreenOn();
}
MainActivity.Java
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_HEADSET_PLUG);
filter.addAction(Intent.ACTION_POWER_CONNECTED);
filter.addAction(Intent.ACTION_POWER_DISCONNECTED);
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
registerReceiver(new MyReceiver(), filter);
}
}
MyReciever.Java
public class MyReceiver extends BroadcastReceiver {
MainActivity mActivity;
#Override
public void onReceive(Context arg0, Intent arg1) {
mActivity = (MainActivity) arg0;
TextView tv = (TextView)mActivity.findViewById(R.id.textView1);
if(arg1.getAction().equals(Intent.ACTION_HEADSET_PLUG)) {
tv.setText("Headset Plugin ");
} else if(arg1.getAction().equals(Intent.ACTION_POWER_CONNECTED)) {
tv.setText("Power Connected ");
} else if(arg1.getAction().equals(Intent.ACTION_POWER_DISCONNECTED)) {
tv.setText("Power Disconnected ");
} else if(arg1.getAction().equals(Intent.ACTION_SCREEN_ON)) {
tv.setText("Screen ON ");
} else if(arg1.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
tv.setText("Screen OFF ");
}
}
}

Categories

Resources