I need to get my screen turned on/off using SensorEventListener when
#Override
public final void onSensorChanged(SensorEvent event) {
if (event.values[0] == 0)
turnScreenOFF();
else if (event.values[0] == 5)
turnScreenON();
}
I have tried many sample code for it, but I can't get my screen turned ON again after it's turned OFF
There is the code to turn off the screen :
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 = 0.0f;
getWindow().setAttributes(params);
For screen on-off state, you can try with ACTION_SCREEN_ON and ACTION_SCREEN_OFF intents,which will come in nifty if you’re making an application that might need to save state or respond to the user’s screen going to sleep/waking up, etc.
Check out the Handling Screen ON/OFF.
EDITED:
Try out below:
private void unlockScreen() {
Window window = this.getWindow();
window.addFlags(LayoutParams.FLAG_DISMISS_KEYGUARD);
window.addFlags(LayoutParams.FLAG_SHOW_WHEN_LOCKED);
window.addFlags(LayoutParams.FLAG_TURN_SCREEN_ON);
}
And call this method from onResume().
Related
I am creating a basic camera app as a small project I'm doing to get started with Android development.
When I click on the button to take a picture, there is about a 1-second delay in which the preview freezes before unfreezing again. There is no issue with crashing - just the freezing issue. Why is this happening and how can I fix it?
Below is the method where the camera is instantiated, as well as my SurfaceView class.
private void startCamera() {
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
cameraPreviewLayout = (FrameLayout) findViewById(R.id.camera_preview);
camera = checkDeviceCamera();
camera.setDisplayOrientation(90);
mImageSurfaceView = new ImageSurfaceView(MainActivity.this, camera);
cameraPreviewLayout.addView(mImageSurfaceView);
ImageButton captureButton = (ImageButton)findViewById(R.id.imageButton);
captureButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
camera.takePicture(null, null, pictureCallback);
camera.stopPreview();
camera.startPreview();
}
});
}
public class ImageSurfaceView extends SurfaceView implements
SurfaceHolder.Callback {
private Camera camera;
private SurfaceHolder surfaceHolder;
public ImageSurfaceView(Context context, Camera camera) {
super(context);
this.camera = camera;
this.surfaceHolder = getHolder();
this.surfaceHolder.addCallback(this);
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
try {
this.camera.setPreviewDisplay(holder);
this.camera.startPreview();
this.camera.setDisplayOrientation(90);
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
}
EDIT: There is currently nothing in the pictureCallback.
Camera.PictureCallback pictureCallback = new Camera.PictureCallback() {
}
You don't need to call stopPreview() after takePicture(). And you don't need startPreview() on the next line. You do need startPreview() inside your onPictureTaken() callback (not in onClick() as in the posted code!!) if you want live preview to restart after the picture is captured into a Jpeg stream.
To keep your UI responsive while using camera, you should do all work with the camera on a background thread. But it is not enough to call Camera.open() or Camera.close() on some background thread. You must create a Handler thread and use it for Camera.open(). The same Looper will be used for all camera callbacks, including PictureCallback.onPictureTaken(). See my detailed walkthrough about the use of HandlerThread.
As I explained elsewhere, you can achieve even better performance if you use the new camera2 API on devices that fully support this API (but better use the old API with devices that provide only LEGACY level of camera2 support).
But if you want to get maximum from the camera ISP, this kind of freeze may be inevitable (this depends on many hardware and firmware design choices, made by the manufacturer). Some clever UI tweaks may help to conceal this effect.
You’ll need to enable access to the hidden “Developer options” menu on
your Android phone. To do that, simply tap the “About phone” option in
Settings. Then tap “Build number” seven times and you’re done. Now you
can just back out to the main Settings menu and you’ll find Developer
options somewhere near the bottom of the list.
==>Now that you’re done with that part, let the real fun begins. Tap the new Developer options menu you just enabled and scroll until you
see the following three settings (note that they may be located within
an “Advanced” subsection):
Window animation scale Transition animation scale Animator animation
scale
==>Did you see them? By default, each of those three options is set to “1x” but tapping them and changing them to “.5x” will dramatically
speed up your phone. This harmless tweak forces the device to speed up
all transition animations, and the entire user experience is faster
and smoother as a result
(Android) On a music player, you update the seekbar as expected with this:
PRECISION_SEEKBAR = 100000;
((SeekBar) findViewById(R.id.seekBar2)).setMax(PRECISION_SEEKBAR);
timerSeekBarUpdate.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
final SeekBar seekBar = (SeekBar) findViewById(R.id.seekBar);
#Override
public void run() {
if (control == null || player == null) {
cancel();
return;
}
seekBar.setProgress((int) (player.getCurrentPosition() * PRECISION_SEEKBAR / player.getDuration()));
...
However, if the focus is on the seek bar, talkback steadily and nonstop gives feedback for the progress. Like "seek control 25%", "seek control 25%", "seek control 25%", "seek control 26%", "seek control 26%", "seek control 27%"
I'm missing sth but couldnot solve the problem. I have set the contentDescription to other than #null. But then it reads the content description this time without stopping.
On Spotify client, I checked, it reads the progress as "xx percent" just once. Despite saving the focus on the seekbar.
When I edit the precision for 1 or 100, then you lose the precision on the seekbar. It looks like there are a few parts in the song. You either play one or another by swiping on the seekbar.
Has anybody experienced sth like this? I couldn't find anything on google docs, stack network or somewhere else.
You can just override sendAccessibilityEvent() so it ignores description updates:
#Override
public void sendAccessibilityEvent(int eventType) {
if (eventType != AccessibilityEvent.CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION) {
super.sendAccessibilityEvent(eventType);
}
}
As Altoyyr mentioned, this has the side effect of ignore ALL description updates, including scrolling with volume buttons. So you'll need add back sending the event for volume press actions:
#Override
public boolean performAccessibilityAction(int action, Bundle arguments) {
switch (action) {
case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD:
case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: {
super.sendAccessibilityEvent(AccessibilityEvent.CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION);
}
}
return super.performAccessibilityAction(action, arguments);
}
I had the problem and found that SeekBar reads the percentage on every update.
It helped, that I update the SeekBar only when the percentage changes but still keep a high precision (in my case in ms).
#Override
public void updateSeekBar(final int currentPosInMillis, final int durationInMillis) {
long progressPercent = calculatePercent(currentPosInMillis, durationInMillis);
if (progressPercent != previousProgressPercent) {
seekBar.setMax(durationInMillis);
seekBar.setProgress(currentPosInMillis);
}
previousProgressPercent = progressPercent;
}
private int calculatePercent(int currentPosInMillis, int durationInMillis) {
if(durationInMillis == 0) {
return 0;
}
return (int) (((float)currentPosInMillis / durationInMillis) * 100);
}
previousProgressPercent is initialized to -1.
Please note that this solution is not the same as Spotify does it.
Spotify overrides the message announced by the system when the SeekBar gets selected.
This has following 2 effects:
Updates can be made as often as you want without the percentage beeing repeated
When the percentage changes while the SeekBar is selected then nothing gets announced
Point 2 might me a drawback depending on what you want to achieve.
On my app I have an ImageView which I turned into a Bitmap for editing. I need to detect which pixels on the ImageView were touched by the user. In addition, if the user draws a line with his finger, I need to know all the pixels that were touched in order to change them. How do I detect which pixels were touched?
Ok Jonah, here are some directions for you.
I guess you want that blending effect to react quickly to user input so first thing you'd better go for a custom SurfaceView instead of a ImageView because it is more suitable for drawing high frame rate animations required in 2D action games and animations. I strongly recommend you to read this guide; giving special attention to the part about the use of SurfaceView, before going any further. You will basically need to create a class that extends SurfaceView and implements SurfaceHolder.Callback. This view will then be responsible to listen for user touch events and to render the frames to animate the blending effect.
Take a look at following code as a reference:
public class MainView extends SurfaceView implements SurfaceHolder.Callback {
public MainView(Context context, AttributeSet attrs) {
super(context, attrs);
SurfaceHolder holder = getHolder();
holder.addCallback(this); // Register this view as a surface change listener
setFocusable(true); // make sure we get key events
}
#Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
// Check if the touch pointer is the one you want
if (event.getPointerId(event.getActionIndex()) == 0) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// User touched screen...
case MotionEvent.ACTION_CANCEL:
// User dragged his finger out of the view bounds...
case MotionEvent.ACTION_UP:
// User raised his finger...
case MotionEvent.ACTION_MOVE:
// User dragged his finger...
// Update the blending effect bitmap here and trigger a frame redraw,
// if you don't already have an animation thread to do it for you.
return true;
}
return false;
}
/*
* Callback invoked when the Surface has been created and is ready to be
* used.
*/
public void surfaceCreated(SurfaceHolder holder) {
// You need to wait for this call back before attempting to draw
}
/*
* Callback invoked when the Surface has been destroyed and must no longer
* be touched. WARNING: after this method returns, the Surface/Canvas must
* never be touched again!
*/
public void surfaceDestroyed(SurfaceHolder holder) {
// You shouldn't draw to this surface after this method has been called
}
}
Then use it on the layout of your "drawing" activity like this:
<com.xxx.yyy.MainView
android:id="#+id/main_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
To draw to this surface you need the following code:
Canvas c = null;
try {
c = mSurfaceHolder.lockCanvas(null);
synchronized (mSurfaceHolder) {
if (c != null)
c.drawBitmap(blendingImage, 0, 0, null); // Render blending effect
}
} catch (Exception e) {
Log.e("SurfaceView", "Error drawing frame", e);
} finally {
// do this in a finally so that if an exception is thrown
// during the above, we don't leave the Surface in an
// inconsistent state
if (c != null) {
mSurfaceHolder.unlockCanvasAndPost(c);
}
}
A fully functional example would be impractical to put in an answer so I recommend you to download the Lunar Lander sample game from Google for a full working example. Note however, that you won't need a game animation thread (although it won't hurt having one), like the one coded in the Lunar Lander sample, if all you need is the blending effect. The purpose of that thread is to create a game loop in which game frames are constantly generated to animate objects that may or may not depend on user input. In your case, all you need is to trigger a frame redraw after processing each touch event.
EDIT: The following code are fixes to get the code you've provided in the comments, working.
Here are the changes to MainActivity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// put pics from drawables to Bitmaps
Resources res = getResources();
BitmapDrawable bd1 = (BitmapDrawable) res.getDrawable(R.drawable.pic1);
// FIX: This block makes `operation` a mutable bitmap version of the loaded resource
// This is required because immutable bitmaps can't be changed
Bitmap tmp = bd1.getBitmap();
operation = Bitmap.createBitmap(tmp.getWidth(), tmp.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(operation);
Paint paint = new Paint();
c.drawBitmap(tmp, 0f, 0f, paint);
BitmapDrawable bd2 = (BitmapDrawable) res.getDrawable(R.drawable.pic2);
bmp = bd2.getBitmap();
myView = new MainView(this, operation, bmp);
FrameLayout preview = (FrameLayout) findViewById(R.id.preview);
preview.addView(myView);
}
...
Here are the changes to the MainView class:
public class MainView extends SurfaceView implements Callback {
private SurfaceHolder holder;
private Bitmap operation;
private Bitmap bmp2;
private boolean surfaceReady;
// took out AttributeSet attrs
public MainView(Context context, Bitmap operation, Bitmap bmp2) {
super(context);
this.operation = operation;
this.bmp2 = bmp2;
holder = getHolder(); // Fix: proper reference the instance variable
holder.addCallback(this); // Register this view as a surface change
// listener
setFocusable(true); // make sure we get key events
}
// Added so the blending operation is made in one place so it can be more easily upgraded
private void blend(int x, int y) {
if (x >= 0 && y >= 0 && x < bmp2.getWidth() && x < operation.getWidth() && y < bmp2.getHeight() && y < operation.getHeight())
operation.setPixel(x, y, bmp2.getPixel(x, y));
}
// Added so the drawing is now made in one place
private void drawOverlays() {
Canvas c = null;
try {
c = holder.lockCanvas(null);
synchronized (holder) {
if (c != null)
c.drawBitmap(operation, 0, 0, null); // Render blending
// effect
}
} catch (Exception e) {
Log.e("SurfaceView", "Error drawing frame", e);
} finally {
// do this in a finally so that if an exception is thrown
// during the above, we don't leave the Surface in an
// inconsistent state
if (c != null) {
holder.unlockCanvasAndPost(c);
}
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
if (!surfaceReady) // No attempt to blend or draw while surface isn't ready
return false;
// Check if the touch pointer is the one you want
if (event.getPointerId(event.getActionIndex()) == 0) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// User touched screen. Falls through ACTION_MOVE once there is no break
case MotionEvent.ACTION_MOVE:
// User dragged his finger...
blend((int) event.getX(), (int) event.getY());
}
// Update the blending effect bitmap here and trigger a frame
// redraw,
// if you don't already have an animation thread to do it for you.
drawOverlays();
return true;
}
return false;
}
/*
* Callback invoked when the Surface has been created and is ready to be
* used.
*/
public void surfaceCreated(SurfaceHolder holder) {
surfaceReady = true;
drawOverlays();
}
/*
* Callback invoked when the Surface has been destroyed and must no longer
* be touched. WARNING: after this method returns, the Surface/Canvas must
* never be touched again!
*/
public void surfaceDestroyed(SurfaceHolder holder) {
// You shouldn't draw to this surface after this method has been called
surfaceReady = false;
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
}
This code works for me. I just hope I didn't forget anything =:)
Let me know if you still have trouble, ok?
So the answer to this is that you're going to have to be a little clever, but it really shouldn't be so bad. Instead of posting all the code to do what you want to do, I'll give you a link here and an explanation.
So by managing the touch events of an application, you can figure out the average coordinates of a touch event. Using that information you can determine the center of all the pixels touched and continue to track that as a line is drawn with the finger. To track a straight line use the
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_UP:
clauses to determine the start and end of the line. If you want to track a line that is not straight and drawn, you're going to need a little more tracking using
case MotionEvent.ACTION_MOVE:
and that should get you fairly started. You may need a little bit of logic to deal with the fact that you will be drawing a very thin line and I suspect that's not quite what you're going for. Maybe it is though. Either way this should be a good place to get started.
EDIT
In regards to your first comment, here is a link you can use for an example. I have to make a small disclaimer though. To get all of the pieces to work together correctly, it may not seem that simple at first. I assure you that this is one of the simplest examples and breaks the tutorial into sections.
For what you would like to do, I think you'll want to pay particular attention to section 2 (no to be confused with step 2):
2. Facilitate Drawing
I suggest this because it shows different ways to use information form the TouchEvent. The things included in section 1 will explain a little bit about the environment to setup displaying a TouchEvent's captured data whereas section 3 is mostly about aesthetics. This may not directly answer your question, but I suspect it will get you where you need to be.
Happy coding! Leave a comment if you have any questions.
I want to make my android screen "flash" white temporarily (only once). It needs to be long enough that the user will be able to tell that the screen did in fact turn white.
The user will land on a screen, which will flash white after 5 seconds, then display the original screen again (possibly fading from white).
What would be the best way to do this? Right now I am creating a rectangle that takes up the entire screen and programatically showing and hiding it.
Add a foreground by creating an overlaying (match_parent size) ImageView and set android:src to a white drawable.
Set the visibility of this view to android:visibility="gone".
When you want to show the white flash, I recommend an animation to fade the white flash in and display it.
This is a basic animation which will fade in an ImageView's drawable. The fade out will be the reverse of this.
public static void FadeIn(final ImageView v,
final int begin_alpha, final int end_alpha, int time,
final boolean toggleVisibility) {
if (Integer.valueOf(android.os.Build.VERSION.SDK_INT) >= android.os.Build.VERSION_CODES.JELLY_BEAN)
v.setImageAlpha(begin_alpha);
else
v.setAlpha(begin_alpha);
if (toggleVisibility) {
if (v.getVisibility() == View.GONE)
v.setVisibility(View.VISIBLE);
else
v.setVisibility(View.GONE);
}
Animation a = new Animation() {
#Override
protected void applyTransformation(float interpolatedTime,
Transformation t) {
if (interpolatedTime == 1) {
if (Integer.valueOf(android.os.Build.VERSION.SDK_INT) >= android.os.Build.VERSION_CODES.JELLY_BEAN)
v.setImageAlpha(end_alpha);
else
v.setAlpha(end_alpha);
if (toggleVisibility) {
if (v.getVisibility() == View.GONE)
v.setVisibility(View.VISIBLE);
else
v.setVisibility(View.GONE);
}
} else {
int new_alpha = (int) (begin_alpha + (interpolatedTime * (end_alpha - begin_alpha)));
if (Integer.valueOf(android.os.Build.VERSION.SDK_INT) >= android.os.Build.VERSION_CODES.JELLY_BEAN)
v.setImageAlpha(new_alpha);
else
v.setAlpha(new_alpha);
v.requestLayout();
}
}
#Override
public boolean willChangeBounds() {
return true;
}
};
a.setDuration(time);
v.startAnimation(a);
}
You could, instead of creating a new view, use the android:foreground property if you're using a framelayout and toggle the opacity from 0 (transparent) to 1 (opaque). (NB. For the first method, when the flash view is visible, you won't be able to interact with any elements under it, which makes this a better option than a FrameLayout with a foreground property). This is harder to implement, however.
Hello Developers,
i am working with Btwebview here on long press we are avoiding the default selection functionality on long press and giving our own.The overriding of long press method is working perfectly till android 4.3 but with 4.4 the defalut selection also coming with actionbar.Below i am mentioning the sample code-
public class BTWebView extends WebView implements TextSelectionJavascriptInterfaceListener, OnTouchListener, OnLongClickListener,DragListener {
.......
public BTWebView(Context context) {
super(context);
this.ctx = context;
this.setup(context);
}
protected void setup(Context context)
{
this.setOnLongClickListener(this);
this.setOnTouchListener(this);
}
and on long press
#Override
public boolean onLongClick(View v)
{
......
return true;
}
}
Here after overriding the long click and return value as true so it avoid default selection till 4.3 so please tell me how to avoid either the complete default selection or atleast avoid the action bar comes on long press .thanks in advance
i found the solution for this question here on github ,it is-
if(event.getAction() == MotionEvent.ACTION_UP)
{
if(!mScrolling){
mScrolling = false;
endSelectionMode();
return false;
}
mScrollDiffX = 0;
mScrollDiffY = 0;
mScrolling = false;
// Fixes 4.4 double selection
return true;
}
here also you have to return the true,after that the default selection will not come .
The solution for KitKat and above proposed by Ravi Saini works to prevent the default selection interface to appear. However, return true for ACTION_UP event prevents fling gestures for scrolling the contents vertically quickly, so the use of WebView seems unnatural. I added isInSelectionMode() condition to prevent this, now fling gestures work fine, except when in selection mode. The code from WebViewMarker GitHub project with my change is as follows (in TextSelectionSupport.java module, onTouch() method):
case MotionEvent.ACTION_UP:
if (!mScrolling) {
endSelectionMode();
//
// Fixes 4.4 double selection
// See: http://stackoverflow.com/questions/20391783/how-to-avoid-default-selection-on-long-press-in-android-kitkat-4-4
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
return false;
}
}
mScrollDiffX = 0;
mScrollDiffY = 0;
mScrolling = false;
//
// Fixes 4.4 double selection
// See: http://stackoverflow.com/questions/20391783/how-to-avoid-default-selection-on-long-press-in-android-kitkat-4-4
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && isInSelectionMode()) {
return true;
}
break;
Greg
If the onLongClick() method isn't getting called and the long press in the WebView is enabling the user selection (i.e. copy, cut, paste etc) then you could try the user-select CSS property
user-select:none;
Which will surpress that behaviour, although not sure if this will still fire the long click listener, or whether the WebView will continue to inherit the click events.