HDMI out programming for dual screen - android

In my search I found that, the Android SDK provides no support for controlling HDMI port activities and handling HDMI output, as of now. Though certain device manufacturers like Motorola (don't know if any other does that too) provide API's for a little better control. Below are the links to two of them, out of which the dual screen one (which suits my requirement pretty close) is deprecated.
motorola hdmi status api
motorola hdmi dual screen api
Mirroring is the default behavior on connecting HDMI but, I want my app to run a binded service on HDMI out. This will allow the phone to perform any other tasks simultaneously, w/o disturbing my service running on the HDMI screen.
Can someone please suggest how can I go about it? Or if any other manufacturer provides similar flexibility as Motorola?

Create a Service class like so.
public class MultiDisplayService extends Service {
#Override
public void onCreate() {
super.onCreate();
DisplayManager dm = (DisplayManager)getApplicationContext().getSystemService(DISPLAY_SERVICE);
if (dm != null){
Display dispArray[] = dm.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION);
if (dispArray.length>0){
Display display = dispArray[0];
Log.e(TAG,"Service using display:"+display.getName());
Context displayContext = getApplicationContext().createDisplayContext(display);
WindowManager wm = (WindowManager)displayContext.getSystemService(WINDOW_SERVICE);
View view = LayoutInflater.from(displayContext).inflate(R.layout.fragment_main,null);
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.TYPE_TOAST,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.TRANSLUCENT);
wm.addView(view, params);
}
}
}
Start the service, perhaps in your Application class.
public class MultiDisplayApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
startService(new Intent(this, MultiDisplayService.class));
}
}
You will probably need more complex display add/remove logic based on DisplayManager.DisplayListener
mDisplayManager = (DisplayManager) this.getSystemService(Context.DISPLAY_SERVICE);
mDisplayManager.registerDisplayListener(this, null);
Using WindowManager.LayoutParams.TYPE_TOAST requires no permissions but seems like a hack. WindowManager.LayoutParams.TYPE_SYSTEM_ALERT might be more reasonable, but requieres
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
in your AndroidManifest.

Related

Android - click simulation from service [duplicate]

I'm basically trying to get all touch event data from something like a system overlay, move my sprites around based on this touch data, then allow the OS/homescreen/browser to act upon the data as it should(or vice versa). I have found similar questions, but nothing that leads me anywhere I haven't already been:
Getting the View that is receiving all the touch events
(Implemented, with results below)
Creating a system overlay window (always on top)
What I can do:
I can EITHER grab ALL the touch events and act upon them by moving my sprites and not allow the OS/homescreen/browser to see any of them, OR ELSE I can allow the touch events to pass through and only get a “TOUCH_OUTSIDE” for my app to act upon.
My unattained goal:
I CAN NOT for the life of me figure out a way around getting BOTH to work with the data. The only methods I can think of, that I can't get implemented are:
Intercepting the data in my APP and passing it onto OS/homescreen/browser to work with
Allowing the OS/homescreen/browser to get the data first, and then getting a callback with information somehow
Allowing the OS/homescreen/browser to get the data, act on the data, and the poll them for what their scroll/location values are so as to act upon it in my APP.
I fear that this just isn't possible, I think I read somewhere in some documentation that I can't find now:
“It's all or nothing, either your view gets all the events, or none of them”
(To avoid confusion, I don't mean I have two views. I mean I have one view controlled via activity/service overlaying the OS/homescreen/browser. Like a pane of glass if you will.)
Thank you for any helpful information you can offer, it's very much appreciated!
[UPDATE]
Posted my own documentation on the matter below, so as to not be confusing.
Found this documentation that pretty much states that it's not possible to do both:
Android : Multi touch and TYPE_SYSTEM_OVERLAY
They discuss workarounds but I don't think any of them will actually work for exactly what I'm trying to do. Both given the events to the underlying app, and being able to snoop them to act upon them for myself.
To create an overlay view, when setting up the LayoutParams you need
to set the type to TYPE_SYSTEM_OVERLAY and use the flag
FLAG_WATCH_OUTSIDE_TOUCH. This presents a problem because as the
Android documentation states: "you will not receive the full
down/move/up gesture, only the location of the first down as an
ACTION_OUTSIDE." In order to receive the full array of touch events
you need to use the TYPE_SYSTEM_ALERT type, but this causes the
overlay to take over the screen and stop interaction with other
elements.
Anyone wants to disagree I'd love to hear good news :-D
You can use the GestureOverlayView, if you want to hide the lines it draws you can set the color to Transparent #00000000 so it doesn't show up, and then you can capture all touches, and gestures.
http://developer.android.com/resources/articles/gestures.html
I was looking for the same thing.
This flag does the trick for me FLAG_NOT_TOUCH_MODAL
Works on Android 7 and 8 setup as below.
The only action I've implemented so far is a touch to close the overlay window.
I also used code from here Example System Overlay Code on Github which was needed to get the events.
By the way Google Maps does a really nice job with this on Android 8. You can drag their overlay window around, resize it or close it. And all other apps work fine while it's up.
var type = 0
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
{
type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
}
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
}
var flags = FLAG_NOT_TOUCH_MODAL
mOverlayLayoutParams = WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, type, flags, PixelFormat.TRANSLUCENT)
This is not the optimal solution but it works. Restart the service toggling the flag not touchable. put boolean extra to Intent
which is used to startservice to determine previous state toggle value. A better implementation would be to fire the intent on
touch when the window is listening and after a fixed period when not listening.
public class bleh extends Service {
public void onCteqwer(int i) {
Context context; Class <bleh> context1 = bleh.class;
WindowManager.LayoutParams params = null;
WindowManager mang = (WindowManager) getSystemService(WINDOW_SERVICE);
//check previous state of service
if(i==0)
params = new WindowManager.LayoutParams(arg0,arg1,arg2,arg3,arg4,arg5);
if(i==1)
params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,arg0,arg1,arg2,arg3,arg4);
LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
View mViw = inflater.inflate(arg, null);
mViw.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
return true;
}
});
mang.addView(mViw, params);
Intent z = new Intent(context, context1);
if(i==0)
z.putExtra("name", 1);
if(i==1)
z.putExtra("name", 0);
stopSelf();
startService(z);
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Bundle i=intent.getExtras();
int userName = 0;
if (i != null)
{
userName = i.getInt("name");
onCteqwer(userName);
}
}
}

AMOLED display does not save power with full black display. Why is it so? [duplicate]

Before marking this post as a "duplicate", I am writing this post because no other post holds the solution to the problem.
I am trying to turn off the device, then after a few minutes or sensor change, turn it back on.
Turn Off Display Tests
I am able to turn off the screen using:
params.flags |= LayoutParams.FLAG_KEEP_SCREEN_ON;
params.screenBrightness = 0;
getWindow().setAttributes(params);
I have been unable to turn off the screen using the wl.release() method.
Turn On Display Test
My first guess, as follows, does not work. Nothing happens, screen remains off.
params.flags |= LayoutParams.FLAG_KEEP_SCREEN_ON;
params.screenBrightness = -1f;
getWindow().setAttributes(params);
I also then tried to use wakelocks, with no success.
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "tag");
wl.acquire();
Finally I have tried the following, with no result.
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
All in all, I don't get any kind of error in the console for any of these methods. My test text "Screen should be on", is on the the screen when I turn on the device using the power button. This shows that the code should have ran. Please only answer if you have tested the code, it seems like many of the functions such as params.screenBrightness = -1, do not work as they should according to the sdk.
I am going to assume you only want this to be in effect while your application is in the foreground.
This code:
params.flags |= LayoutParams.FLAG_KEEP_SCREEN_ON;
params.screenBrightness = 0;
getWindow().setAttributes(params);
Does not turn the screen off in the traditional sense. It makes the screen as dim as possible. In the standard platform there is a limit to how dim it can be; if your device is actually allowing the screen to turn completely off, then it is some peculiarity of the implementation of that device and not a behavior you can count on across devices.
In fact using this in conjunction with FLAG_KEEP_SCREEN_ON means that you will never allow the screen to go off (and thus the device to go into low-power mode) even if the particular device is allowing you to set the screen brightness to full-off. Keep this very strongly in mind. You will be using much more power than you would if the screen was really off.
Now for turning the screen back to regular brightness, just setting the brightness value should do it:
WindowManager.LayoutParams params = getWindow().getAttributes();
params.screenBrightness = -1;
getWindow().setAttributes(params);
I can't explain why this wouldn't replace the 0 value you had previously set. As a test, you could try putting a forced full brightness in there to force to that specific brightness:
WindowManager.LayoutParams params = getWindow().getAttributes();
params.screenBrightness = 1;
getWindow().setAttributes(params);
This definitely works. For example, Google's Books apps uses this to allow you to set the screen brightness to dim while using a book and then return to regular brightness when turning that off.
To help debug, you can use "adb shell dumpsys window" to see the current state of your window. In the data for your window, it will tell you the current LayoutParams that have been set for it. Ensure the value you think is actually there.
And again, FLAG_KEEP_SCREEN_ON is a separate concept; it and the brightness have no direct impact on each other. (And there would be no reason to set the flag again when undoing the brightness, if you had already set it when putting the brightness to 0. The flag will stay set until you change it.)
I had written this method to turn on the screen after screen lock. It works perfectly for me. Try it-
private void unlockScreen() {
Window window = this.getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
}
And call this method from onResume().
I would suggest this one:
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "tag");
wl.acquire();
The flag ACQUIRE_CAUSES_WAKEUP is explained like that:
Normal wake locks don't actually turn on the illumination. Instead,
they cause the illumination to remain on once it turns on (e.g. from
user activity). This flag will force the screen and/or keyboard to
turn on immediately, when the WakeLock is acquired. A typical use
would be for notifications which are important for the user to see
immediately.
Also, make sure you have the following permission in the AndroidManifewst.xml file:
<uses-permission android:name="android.permission.WAKE_LOCK" />
Hi I hope this will help:
private PowerManager mPowerManager;
private PowerManager.WakeLock mWakeLock;
public void turnOnScreen(){
// turn on screen
Log.v("ProximityActivity", "ON!");
mWakeLock = mPowerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "tag");
mWakeLock.acquire();
}
#TargetApi(21) //Suppress lint error for PROXIMITY_SCREEN_OFF_WAKE_LOCK
public void turnOffScreen(){
// turn off screen
Log.v("ProximityActivity", "OFF!");
mWakeLock = mPowerManager.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, "tag");
mWakeLock.acquire();
}
WakeLock screenLock = ((PowerManager)getSystemService(POWER_SERVICE)).newWakeLock(
PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "TAG");
screenLock.acquire();
//later
screenLock.release();
//User Manifest file
Are you sure you requested the proper permission in your Manifest file?
<uses-permission android:name="android.permission.WAKE_LOCK" />
You can use the AlarmManager1 class to fire off an intent that starts your activity and acquires the wake lock. This will turn on the screen and keep it on. Releasing the wakelock will allow the device to go to sleep on its own.
You can also take a look at using the PowerManager to set the device to sleep: http://developer.android.com/reference/android/os/PowerManager.html#goToSleep(long)
Simply add
android:keepScreenOn="true"
or call
setKeepScreenOn(true)
on parent view.
The best way to do it ( using rooted devices) :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
.
.
.
int flags = WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
getWindow().addFlags(flags); // this is how your app will wake up the screen
//you will call this activity later
.
.
.
}
Now we have this two functions:
private void turnOffScreen(){
try{
Class c = Class.forName("android.os.PowerManager");
PowerManager mPowerManager = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
for(Method m : c.getDeclaredMethods()){
if(m.getName().equals("goToSleep")){
m.setAccessible(true);
if(m.getParameterTypes().length == 1){
m.invoke(mPowerManager,SystemClock.uptimeMillis()-2);
}
}
}
} catch (Exception e){
}
}
And this:
public void turnOnScreen(){
Intent i = new Intent(this,YOURACTIVITYWITHFLAGS.class);
startActivity(i);
}
Sorry for my bad english.
Here is a successful example of an implementation of the same thing, on a device which supported lower screen brightness values (I tested on an Allwinner Chinese 7" tablet running API15).
WindowManager.LayoutParams params = this.getWindow().getAttributes();
/** Turn off: */
params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
//TODO Store original brightness value
params.screenBrightness = 0.1f;
this.getWindow().setAttributes(params);
/** Turn on: */
params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
//TODO restoring from original value
params.screenBrightness = 0.9f;
this.getWindow().setAttributes(params);
If someone else tries this out, pls comment below if it worked/didn't work and the device, Android API.
To keep screen on:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
Back to screen default mode:
just clear the flag FLAG_KEEP_SCREEN_ON
getWindow().clearFlags(android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
This is worked on Marshmallow
private final String TAG = "OnOffScreen";
private PowerManager _powerManager;
private PowerManager.WakeLock _screenOffWakeLock;
public void turnOnScreen() {
if (_screenOffWakeLock != null) {
_screenOffWakeLock.release();
}
}
public void turnOffScreen() {
try {
_powerManager = (PowerManager) this.getSystemService(POWER_SERVICE);
if (_powerManager != null) {
_screenOffWakeLock = _powerManager.newWakeLock(PROXIMITY_SCREEN_OFF_WAKE_LOCK, TAG);
if (_screenOffWakeLock != null) {
_screenOffWakeLock.acquire();
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
If your app is a system app,you can use PowerManager.goToSleep() to turn screen off,you requires a special permission
before you use goToSleep(), you need use reflection just like:
public static void goToSleep(Context context) {
PowerManager powerManager= (PowerManager)context.getSystemService(Context.POWER_SERVICE);
try {
powerManager.getClass().getMethod("goToSleep", new Class[]{long.class}).invoke(powerManager, SystemClock.uptimeMillis());
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
Now,you can use goToSleep() to turn screen off.
This is what happens when the power key is pressed to turn off the screen.
As per Android API 28 and above you need to do the following to turn on the screen
setShowWhenLocked(true);
setTurnScreenOn(true);
KeyguardManager keyguardManager = (KeyguardManager)
getSystemService(Context.KEYGUARD_SERVICE);
keyguardManager.requestDismissKeyguard(this, null);
Regarding to Android documentation it can be achieve by using following code line:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
I have added this in my onCreate method and it works fine.
On the link you will find different ways to achieve this and general explanation as well.
Link to the documenation: https://developer.android.com/training/scheduling/wakelock.html
I wouldn't have hope of "waking the screen" in the activity. If the screen is off the activity is probably in a paused state and shouldn't be running any code.
When waking up, there is the issue of the lockscreen. I don't know how any app can automatically bypass the lockscreen.
You should consider running your background tasks in a service, and then using the notification manager to send a notification when whatever is detected. The notification should provide some sort of device alert (screen wake up, notification icon, notification led, etc). When clicking the notification it can launch the intent to start your activity.
You could also attempt to start the activity direct from the service, but I really don't know if that will turn the screen on or bypass the lockscreen.
I have tried all above solution but none worked for me. so I googled and found below solutions. I tried and it worked.
https://www.tutorialspoint.com/how-to-turn-android-device-screen-on-and-off-programmatically
if there is any suggestion then please give

Android: Using WebView outside an Activity context

I am trying to achieve Web Scraping through a background IntentService that periodically scrape a website without a view displaying on the users phone.
Since I have to do call some javascript on the loaded page I cannot use any HttpGet's etc.
I therefore have to use a WebView instance which can only run on an UI thread.
Any attempts to start an Activity that use a WebView results in a View coming into the phones foreground (as per Android's design of Activities)
Any attempts to use a WebView outside of an Activity context resulted in error pointing to the fact that you cannot use WebView on a non-UI thread.
For various complexity reasons I cannot consider using libraries such as Rhino for UI-less web scraping.
Is there any way of working around this problem?
You can display a webview from a service. Code below creates a window which your service has access to. The window isn't visible because the size is 0 by 0.
public class ServiceWithWebView extends Service {
#Override
public void onCreate() {
super.onCreate();
WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
params = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP | Gravity.LEFT;
params.x = 0;
params.y = 0;
params.width = 0;
params.height = 0;
LinearLayout view = new LinearLayout(this);
view.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT));
WebView wv = new WebView(this);
wv.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
view.addView(wv);
wv.loadUrl("http://google.com");
windowManager.addView(view, params);
}
}
Also this will require the android.permission.SYSTEM_ALERT_WINDOW permission.
Correct me if I am wrong but the correct answer to this question is that there is NO possible way to use a WebView in the background while the user is doing other things on the phone without interrupting the user by means of an Activity.
I have applied both Randy and Code_Yoga's suggestions: Using an activity with "Theme.NoDisplay" to launch a background service with a WebView to do some work. However even though no view is visible the switching to that activity for that second to start the services interrupts the user (ex. like pausing a running game that was being played).
Totally disastrous news for my app so I am still hoping someone will give me a way to use a WebView that does not need an Activity (or a substitute for a WebView that can accomplish the same)
You can use this to hide the Activity
<activity android:name="MyActivity"
android:label="#string/app_name"
android:theme="#android:style/Theme.NoDisplay">
Doing this will prevent the app from showing any Activity.
And then you can do your stuff in the Activity.
the solution was like this, but with Looper.getMainLooper() :
https://github.com/JonasCz/save-for-offline/blob/master/app/src/main/java/jonas/tool/saveForOffline/ScreenshotService.java
#Override
public void onCreate() {
super.onCreate();
//HandlerThread thread = new HandlerThread("ScreenshotService", Process.THREAD_PRIORITY_BACKGROUND);
//thread.start();
//mServiceHandler = new ServiceHandler(thread.getLooper()); // not working
mServiceHandler = new ServiceHandler(Looper.getMainLooper()); // working
}
with help of #JonasCz : https://stackoverflow.com/a/28234761/466363
I used the following code to get round this problem:
Handler handler = new Handler(Looper.getMainLooper());
try
{
handler.post(
new Runnable()
{
#Override
public void run()
{
ProcessRequest(); // Where this method runs the code you're needing
}
}
);
} catch (Exception e)
{
e.printStackTrace();
}
A WebView cannot exist outside of an Activity or Fragment due to it being a UI.
However, this means that an Activity is only needed to create the WebView, not handle all its requests.
If you create the invisible WebView in your main activity and have it accessible from a static context, you should be able to perform tasks in the view in the background from anywhere, since I believe all of WebView's IO is done asynchronously.
To take away the ick of that global access, you could always launch a Service with a reference to the WebView to do the work you need.
or a substitute for a WebView that can accomplish the same <=== if you do not wish to show the loaded info on UI, maybe you can try to use HTTP to call the url directly, and process on the returned response from HTTP
Why don't you create a Backend Service that does the scraping for you?
And then you just poll results from a RESTful Webservice or even use a messaging middleware (e.g. ZeroMQ).
Maybe more elegant if it fits your use case: let the Scraping Service send your App Push Messages via GCM :)
I am not sure if this is a silver bullet to the given problem.
As per #Pierre's accepted answer (sounds correct to me)
there is NO possible way to use a WebView in the background while the
user is doing other things on the phone without interrupting the user
by means of an Activity.
Thus, I believe there must be some architectural/flow/strategy changes that must be done in order to solve this problem.
Proposed Solution #1: Instead of getting a push notification from the server and run a background job and followed by running some JS code or WebView. Instead, Whenever user launch the application one should query the backend server to know whether there is any need to perform any scraping or not. And on the basis of backend input android client can run JS code or WebView and pass the result back to the server.
I haven't tried this solution. But hope it is feasible.
This will also solve the following problem stated in the comments:
Reason for this is because the backend will get detected as a bot scraping from the same IP and get blocked (in addition to backend resources needed to do a lot of scraping on different pages).
Data might be unavailable for some time (until some user scrape it for you). But surely we can provide a better user experience to the end users using this strategy.
I know it'a been a year and a half, but I'm now facing the same issue. I solved it eventually by running my Javascript code inside a Node engine that is running inside my Android App. It's called JXCore. You can take a look. Also, take a look at this sample that runs Javascript without a WebView. I really would like to know what did you end up using?

Android: How to turn screen on and off programmatically?

Before marking this post as a "duplicate", I am writing this post because no other post holds the solution to the problem.
I am trying to turn off the device, then after a few minutes or sensor change, turn it back on.
Turn Off Display Tests
I am able to turn off the screen using:
params.flags |= LayoutParams.FLAG_KEEP_SCREEN_ON;
params.screenBrightness = 0;
getWindow().setAttributes(params);
I have been unable to turn off the screen using the wl.release() method.
Turn On Display Test
My first guess, as follows, does not work. Nothing happens, screen remains off.
params.flags |= LayoutParams.FLAG_KEEP_SCREEN_ON;
params.screenBrightness = -1f;
getWindow().setAttributes(params);
I also then tried to use wakelocks, with no success.
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "tag");
wl.acquire();
Finally I have tried the following, with no result.
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
All in all, I don't get any kind of error in the console for any of these methods. My test text "Screen should be on", is on the the screen when I turn on the device using the power button. This shows that the code should have ran. Please only answer if you have tested the code, it seems like many of the functions such as params.screenBrightness = -1, do not work as they should according to the sdk.
I am going to assume you only want this to be in effect while your application is in the foreground.
This code:
params.flags |= LayoutParams.FLAG_KEEP_SCREEN_ON;
params.screenBrightness = 0;
getWindow().setAttributes(params);
Does not turn the screen off in the traditional sense. It makes the screen as dim as possible. In the standard platform there is a limit to how dim it can be; if your device is actually allowing the screen to turn completely off, then it is some peculiarity of the implementation of that device and not a behavior you can count on across devices.
In fact using this in conjunction with FLAG_KEEP_SCREEN_ON means that you will never allow the screen to go off (and thus the device to go into low-power mode) even if the particular device is allowing you to set the screen brightness to full-off. Keep this very strongly in mind. You will be using much more power than you would if the screen was really off.
Now for turning the screen back to regular brightness, just setting the brightness value should do it:
WindowManager.LayoutParams params = getWindow().getAttributes();
params.screenBrightness = -1;
getWindow().setAttributes(params);
I can't explain why this wouldn't replace the 0 value you had previously set. As a test, you could try putting a forced full brightness in there to force to that specific brightness:
WindowManager.LayoutParams params = getWindow().getAttributes();
params.screenBrightness = 1;
getWindow().setAttributes(params);
This definitely works. For example, Google's Books apps uses this to allow you to set the screen brightness to dim while using a book and then return to regular brightness when turning that off.
To help debug, you can use "adb shell dumpsys window" to see the current state of your window. In the data for your window, it will tell you the current LayoutParams that have been set for it. Ensure the value you think is actually there.
And again, FLAG_KEEP_SCREEN_ON is a separate concept; it and the brightness have no direct impact on each other. (And there would be no reason to set the flag again when undoing the brightness, if you had already set it when putting the brightness to 0. The flag will stay set until you change it.)
I had written this method to turn on the screen after screen lock. It works perfectly for me. Try it-
private void unlockScreen() {
Window window = this.getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
}
And call this method from onResume().
I would suggest this one:
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "tag");
wl.acquire();
The flag ACQUIRE_CAUSES_WAKEUP is explained like that:
Normal wake locks don't actually turn on the illumination. Instead,
they cause the illumination to remain on once it turns on (e.g. from
user activity). This flag will force the screen and/or keyboard to
turn on immediately, when the WakeLock is acquired. A typical use
would be for notifications which are important for the user to see
immediately.
Also, make sure you have the following permission in the AndroidManifewst.xml file:
<uses-permission android:name="android.permission.WAKE_LOCK" />
Hi I hope this will help:
private PowerManager mPowerManager;
private PowerManager.WakeLock mWakeLock;
public void turnOnScreen(){
// turn on screen
Log.v("ProximityActivity", "ON!");
mWakeLock = mPowerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "tag");
mWakeLock.acquire();
}
#TargetApi(21) //Suppress lint error for PROXIMITY_SCREEN_OFF_WAKE_LOCK
public void turnOffScreen(){
// turn off screen
Log.v("ProximityActivity", "OFF!");
mWakeLock = mPowerManager.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, "tag");
mWakeLock.acquire();
}
WakeLock screenLock = ((PowerManager)getSystemService(POWER_SERVICE)).newWakeLock(
PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "TAG");
screenLock.acquire();
//later
screenLock.release();
//User Manifest file
Are you sure you requested the proper permission in your Manifest file?
<uses-permission android:name="android.permission.WAKE_LOCK" />
You can use the AlarmManager1 class to fire off an intent that starts your activity and acquires the wake lock. This will turn on the screen and keep it on. Releasing the wakelock will allow the device to go to sleep on its own.
You can also take a look at using the PowerManager to set the device to sleep: http://developer.android.com/reference/android/os/PowerManager.html#goToSleep(long)
Simply add
android:keepScreenOn="true"
or call
setKeepScreenOn(true)
on parent view.
The best way to do it ( using rooted devices) :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
.
.
.
int flags = WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
getWindow().addFlags(flags); // this is how your app will wake up the screen
//you will call this activity later
.
.
.
}
Now we have this two functions:
private void turnOffScreen(){
try{
Class c = Class.forName("android.os.PowerManager");
PowerManager mPowerManager = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
for(Method m : c.getDeclaredMethods()){
if(m.getName().equals("goToSleep")){
m.setAccessible(true);
if(m.getParameterTypes().length == 1){
m.invoke(mPowerManager,SystemClock.uptimeMillis()-2);
}
}
}
} catch (Exception e){
}
}
And this:
public void turnOnScreen(){
Intent i = new Intent(this,YOURACTIVITYWITHFLAGS.class);
startActivity(i);
}
Sorry for my bad english.
Here is a successful example of an implementation of the same thing, on a device which supported lower screen brightness values (I tested on an Allwinner Chinese 7" tablet running API15).
WindowManager.LayoutParams params = this.getWindow().getAttributes();
/** Turn off: */
params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
//TODO Store original brightness value
params.screenBrightness = 0.1f;
this.getWindow().setAttributes(params);
/** Turn on: */
params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
//TODO restoring from original value
params.screenBrightness = 0.9f;
this.getWindow().setAttributes(params);
If someone else tries this out, pls comment below if it worked/didn't work and the device, Android API.
To keep screen on:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
Back to screen default mode:
just clear the flag FLAG_KEEP_SCREEN_ON
getWindow().clearFlags(android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
This is worked on Marshmallow
private final String TAG = "OnOffScreen";
private PowerManager _powerManager;
private PowerManager.WakeLock _screenOffWakeLock;
public void turnOnScreen() {
if (_screenOffWakeLock != null) {
_screenOffWakeLock.release();
}
}
public void turnOffScreen() {
try {
_powerManager = (PowerManager) this.getSystemService(POWER_SERVICE);
if (_powerManager != null) {
_screenOffWakeLock = _powerManager.newWakeLock(PROXIMITY_SCREEN_OFF_WAKE_LOCK, TAG);
if (_screenOffWakeLock != null) {
_screenOffWakeLock.acquire();
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
If your app is a system app,you can use PowerManager.goToSleep() to turn screen off,you requires a special permission
before you use goToSleep(), you need use reflection just like:
public static void goToSleep(Context context) {
PowerManager powerManager= (PowerManager)context.getSystemService(Context.POWER_SERVICE);
try {
powerManager.getClass().getMethod("goToSleep", new Class[]{long.class}).invoke(powerManager, SystemClock.uptimeMillis());
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
Now,you can use goToSleep() to turn screen off.
This is what happens when the power key is pressed to turn off the screen.
As per Android API 28 and above you need to do the following to turn on the screen
setShowWhenLocked(true);
setTurnScreenOn(true);
KeyguardManager keyguardManager = (KeyguardManager)
getSystemService(Context.KEYGUARD_SERVICE);
keyguardManager.requestDismissKeyguard(this, null);
Regarding to Android documentation it can be achieve by using following code line:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
I have added this in my onCreate method and it works fine.
On the link you will find different ways to achieve this and general explanation as well.
Link to the documenation: https://developer.android.com/training/scheduling/wakelock.html
I wouldn't have hope of "waking the screen" in the activity. If the screen is off the activity is probably in a paused state and shouldn't be running any code.
When waking up, there is the issue of the lockscreen. I don't know how any app can automatically bypass the lockscreen.
You should consider running your background tasks in a service, and then using the notification manager to send a notification when whatever is detected. The notification should provide some sort of device alert (screen wake up, notification icon, notification led, etc). When clicking the notification it can launch the intent to start your activity.
You could also attempt to start the activity direct from the service, but I really don't know if that will turn the screen on or bypass the lockscreen.
I have tried all above solution but none worked for me. so I googled and found below solutions. I tried and it worked.
https://www.tutorialspoint.com/how-to-turn-android-device-screen-on-and-off-programmatically
if there is any suggestion then please give

Android overlay to grab ALL touch, and pass them on?

I'm basically trying to get all touch event data from something like a system overlay, move my sprites around based on this touch data, then allow the OS/homescreen/browser to act upon the data as it should(or vice versa). I have found similar questions, but nothing that leads me anywhere I haven't already been:
Getting the View that is receiving all the touch events
(Implemented, with results below)
Creating a system overlay window (always on top)
What I can do:
I can EITHER grab ALL the touch events and act upon them by moving my sprites and not allow the OS/homescreen/browser to see any of them, OR ELSE I can allow the touch events to pass through and only get a “TOUCH_OUTSIDE” for my app to act upon.
My unattained goal:
I CAN NOT for the life of me figure out a way around getting BOTH to work with the data. The only methods I can think of, that I can't get implemented are:
Intercepting the data in my APP and passing it onto OS/homescreen/browser to work with
Allowing the OS/homescreen/browser to get the data first, and then getting a callback with information somehow
Allowing the OS/homescreen/browser to get the data, act on the data, and the poll them for what their scroll/location values are so as to act upon it in my APP.
I fear that this just isn't possible, I think I read somewhere in some documentation that I can't find now:
“It's all or nothing, either your view gets all the events, or none of them”
(To avoid confusion, I don't mean I have two views. I mean I have one view controlled via activity/service overlaying the OS/homescreen/browser. Like a pane of glass if you will.)
Thank you for any helpful information you can offer, it's very much appreciated!
[UPDATE]
Posted my own documentation on the matter below, so as to not be confusing.
Found this documentation that pretty much states that it's not possible to do both:
Android : Multi touch and TYPE_SYSTEM_OVERLAY
They discuss workarounds but I don't think any of them will actually work for exactly what I'm trying to do. Both given the events to the underlying app, and being able to snoop them to act upon them for myself.
To create an overlay view, when setting up the LayoutParams you need
to set the type to TYPE_SYSTEM_OVERLAY and use the flag
FLAG_WATCH_OUTSIDE_TOUCH. This presents a problem because as the
Android documentation states: "you will not receive the full
down/move/up gesture, only the location of the first down as an
ACTION_OUTSIDE." In order to receive the full array of touch events
you need to use the TYPE_SYSTEM_ALERT type, but this causes the
overlay to take over the screen and stop interaction with other
elements.
Anyone wants to disagree I'd love to hear good news :-D
You can use the GestureOverlayView, if you want to hide the lines it draws you can set the color to Transparent #00000000 so it doesn't show up, and then you can capture all touches, and gestures.
http://developer.android.com/resources/articles/gestures.html
I was looking for the same thing.
This flag does the trick for me FLAG_NOT_TOUCH_MODAL
Works on Android 7 and 8 setup as below.
The only action I've implemented so far is a touch to close the overlay window.
I also used code from here Example System Overlay Code on Github which was needed to get the events.
By the way Google Maps does a really nice job with this on Android 8. You can drag their overlay window around, resize it or close it. And all other apps work fine while it's up.
var type = 0
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
{
type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
}
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
}
var flags = FLAG_NOT_TOUCH_MODAL
mOverlayLayoutParams = WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, type, flags, PixelFormat.TRANSLUCENT)
This is not the optimal solution but it works. Restart the service toggling the flag not touchable. put boolean extra to Intent
which is used to startservice to determine previous state toggle value. A better implementation would be to fire the intent on
touch when the window is listening and after a fixed period when not listening.
public class bleh extends Service {
public void onCteqwer(int i) {
Context context; Class <bleh> context1 = bleh.class;
WindowManager.LayoutParams params = null;
WindowManager mang = (WindowManager) getSystemService(WINDOW_SERVICE);
//check previous state of service
if(i==0)
params = new WindowManager.LayoutParams(arg0,arg1,arg2,arg3,arg4,arg5);
if(i==1)
params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,arg0,arg1,arg2,arg3,arg4);
LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
View mViw = inflater.inflate(arg, null);
mViw.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
return true;
}
});
mang.addView(mViw, params);
Intent z = new Intent(context, context1);
if(i==0)
z.putExtra("name", 1);
if(i==1)
z.putExtra("name", 0);
stopSelf();
startService(z);
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Bundle i=intent.getExtras();
int userName = 0;
if (i != null)
{
userName = i.getInt("name");
onCteqwer(userName);
}
}
}

Categories

Resources