I have an android device, it can only run a app (like ATM screen). Now I want to implement the following feature:
If the device is not in use for over 30 minutes, I will adjust the screen brightness to the lowest. At this time, if I touch the screen, I should adjust the screen brightness to the maximum. The user can not see any Android system menu, application, etc. They only can use this app (can't close it). This app will run in this device from the power on it and power off it.
I don't how to implement this feature.
Thanks.
You can use a class that extends service and can dim the screen brightness. Use AlarmManager to check the time that the user never touches the screen. I will give you an example of using the Service class:
public class DimScreen extends Service {
public static int ID_NOTIFICATION = 2018;
private WindowManager windowManager;
private LinearLayout saverScreen;
private PopupWindow pwindo;
boolean mHasDoubleClicked = false;
long lastPressTime;
private Boolean _enable = true;
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
super.onCreate();
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
saverScreen = new LinearLayout(this);
saverScreen.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));
Bitmap sample = Bitmap.createBitmap(100, 100, Config.ARGB_8888);
saverScreen.setBackground(new BitmapDrawable(this.getResources(),
convertColorIntoBlackAndWhiteImage(sample)));
saverScreen.setClickable(false);
saverScreen.setFocusable(false);
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.FILL_PARENT,
WindowManager.LayoutParams.FILL_PARENT,
PixelFormat.TRANSLUCENT);
params.flags = WindowManager.LayoutParams.FLAG_FULLSCREEN
|WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
|WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
|WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
|WindowManager.LayoutParams.FLAG_DIM_BEHIND;
params.dimAmount = (float) 0.6;
params.screenBrightness = (float) 0.3;
params.systemUiVisibility = View.SYSTEM_UI_FLAG_LOW_PROFILE;
windowManager.addView(saverScreen, params);
}
#Override
public void onDestroy() {
super.onDestroy();
if (saverScreen != null) windowManager.removeView(saverScreen);
}
private Bitmap convertColorIntoBlackAndWhiteImage(Bitmap orginalBitmap) {
ColorMatrix colorMatrix = new ColorMatrix();
colorMatrix.setSaturation(2);
ColorMatrixColorFilter colorMatrixFilter = new ColorMatrixColorFilter(
colorMatrix);
Bitmap blackAndWhiteBitmap = orginalBitmap.copy(
Bitmap.Config.ARGB_8888, true);
Paint paint = new Paint();
paint.setColorFilter(colorMatrixFilter);
Canvas canvas = new Canvas(blackAndWhiteBitmap);
canvas.drawBitmap(blackAndWhiteBitmap, 0, 0, paint);
return blackAndWhiteBitmap;
}
}
In your Activity class call
startService(new Intent(this,DimScreen.class));
You only have to implement the AlarmManager now. If the user never touches the screen, launch the Service class. If the user Interrupt with the app, then call stopService.
Try this
WindowManager.LayoutParams localLayoutParams = getWindow()
.getAttributes();
localLayoutParams.screenBrightness = 0.12F;
getWindow().setAttributes(localLayoutParams);
Related
I am building a lock screen app. I want to place a floating icon on Homescreen, which when clicked will lock the phone. I was able to implement the functionality of Locking the Phone using Device Manager API. Now I want to add a Floating Icon on Homescreen.
I tried using the solution recommended here:
What APIs are used to draw over other apps (like Facebook's Chat Heads)?
But this does not seem to be working in my case. It is not diplaying an icon on the homescreen ever after gaining SYSTEM OVERLAY Permission.
LockButtonService.java
public class LockButtonService extends Service {
private WindowManager windowManager;
private ImageView chatHead;
#Override public IBinder onBind(Intent intent) {
// Not used
return null;
}
#Override public void onCreate() {
super.onCreate();
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
chatHead = new ImageView(this);
chatHead.setImageResource(R.drawable.lock);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP | Gravity.LEFT;
params.x = 0;
params.y = 100;
windowManager.addView(chatHead, params);
}
#Override
public void onDestroy() {
super.onDestroy();
if (chatHead != null) windowManager.removeView(chatHead);
}
}
MainActivity.java
add_homescreen.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Code For Adding Shortcut Icon On Home Screen
// if (ShortcutManagerCompat.isRequestPinShortcutSupported(getApplicationContext())) {
// ShortcutInfoCompat shortcutInfo = new ShortcutInfoCompat.Builder(getApplicationContext(), "#1")
// .setIntent(new Intent(getApplicationContext(), LockActivity.class).setAction(Intent.ACTION_MAIN)) // !!! intent's action must be set on oreo
// .setShortLabel("Lock Screen")
// .setIcon(IconCompat.createWithResource(getApplicationContext(), R.drawable.lock))
// .build();
// ShortcutManagerCompat.requestPinShortcut(getApplicationContext(), shortcutInfo, null);
// } else {
// Toast.makeText(MainActivity.this,"launcher does not support short cut icon",Toast.LENGTH_LONG).show();
// }
//Code For Requesting System Overlay
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.canDrawOverlays(getApplicationContext())) {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, 12345);
}
else {
//Code To Execute If The Permission Is Granted
Toast.makeText(getApplicationContext(),"Permission Granted",Toast.LENGTH_LONG);
startService(new Intent(getApplicationContext(), LockButtonService.class));
}
}
}
I figured out the issue. It seems like I forgot to declare this service in Android Manifest. I was using WindowManager.LayoutParams.TYPE_PHONE in LockButtonService.java.
I have now changed it into WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, and my icon is displaying on homescreen and all other activities.
I was trying to detect touch events in background service so that I can get all the touch events when user is using any apps.
What's I've done is using WindowManager to add a small view and when running the app in the background, this small view can still be on the screen. I also set the view as an onTouchListener so when user touch inside the view, I can get the touch event.
My problem is that is there any way to detect touch events outside this small view.
Here is my code.
public class GlobalTouchService extends Service implements View.OnTouchListener {
private WindowManager mWindowManager;
private WindowManager.LayoutParams mLayoutParams;
private MyView myView;
private boolean flag = true;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
mWindowManager = (WindowManager)getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
mLayoutParams = new WindowManager.LayoutParams();
mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
mLayoutParams.format = PixelFormat.TRANSLUCENT;
mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
mLayoutParams.x = 0;
mLayoutParams.y = 0;
mLayoutParams.height = 300;
mLayoutParams.width = 300;
myView = new MyView(this);
myView.setOnTouchListener(this);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (flag) {
flag = false;
mWindowManager.addView(myView, mLayoutParams);
}
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
float x = motionEvent.getRawX();
float y = motionEvent.getRawY();
Log.d("x,y", "X" + x + " Y" + y);
return false;
}
You can't. Android explicitly does not allow you to get touch events when you aren't the foreground app for security reasons. What you're trying to do is explicitly against what the OS wants, and if you find a way Google will plug the hole as quick as you find it. The only way to do this is on a rooted device, which means it won't work over the play store (and the way to do it there is by reading touch data from the linux device layer).
I'm developing an Android app that have a overlay view that the user can access from anywhere.
I have taken the code from the following question:
Overlay
Put it simple, a class "HUD" that call a subclass ViewGroup"HUDView", containing all the necessary elements.
Now I want to add in this ViewGroup also a SeekBar that, on progress change, draw a Canvas every time: for example seekBar progress =1, draw a circle with 10° angle, progress=2, redraw the circle with 20° angle, and so on...
The circle and the seekbar must overlay the actual screen from everywhere.
I've managed to put the Canvas (created in the onDraw method of the ViewGroup) and the seekBar (created in the onCreate method of the HUD class, also with his listener).
In the method "onProgressChanged" I would like to redraw the circle, but this doesnt seems to work.
Here the listener code:
// SeekBar Change Listener
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progresValue, boolean fromUser) {
mView = new HUDView(getApplicationContext());
progress = progresValue;
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.CENTER | Gravity.TOP;
params.setTitle("Load Average");
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.addView(mView, params);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
//Toast.makeText(getApplicationContext(), "Started tracking seekbar", Toast.LENGTH_SHORT).show();
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
//textView.setText("Covered: " + progress + "/" + seekBar.getMax());
//Toast.makeText(getApplicationContext(), "Stopped tracking seekbar", Toast.LENGTH_SHORT).show();
}
});
Here the onDraw method of the HUDView:
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
final RectF oval = new RectF();
oval.set(30, 30, 450, 450);
Bitmap bg = Bitmap.createBitmap(480, 480, Bitmap.Config.ARGB_8888);
canvas.drawArc(oval, 90, progress*10 , true, paint);
}
I'm using osmdroid and have implemented a MapEventsReceiver, MapEventsOverlay and a LongPressHelper in order to add a new marker when the user holds down on the map. This works the first time and the first time only.
If I remove the addMarker(p); from my longPressHelper then it will fire every single time.
Has anyone got any idea why this is happening like this?
code:
mapviewInit - called in onCreate
private void mapviewInit() {
mapview = (MapView) findViewById(R.id.mapview);
mapview.setTileSource(TileSourceFactory.MAPNIK);
mapview.setBuiltInZoomControls(true);
mapview.setMultiTouchControls(true);
IMapController mapController = mapview.getController();
mapController.setZoom(16);
GeoPoint startPoint = new GeoPoint(48.8583, 2.2944);
mapController.setCenter(startPoint);
MapEventsReceiver meReceiver = new MapEventsReceiver() {
#Override
public boolean singleTapConfirmedHelper(GeoPoint p) {
return false;
}
#Override
public boolean longPressHelper(GeoPoint p) {
Toast toast = Toast.makeText(getApplicationContext(), "DEBUGDEBUGDEBUG", Toast.LENGTH_LONG);
toast.show();
addMarker(p);
return true;
}
};
addMarker - called by LongPressHelper
public void addMarker(GeoPoint geoPoint) {
Drawable dr = getResources().getDrawable(R.drawable.icn_crosshair_red);
Bitmap bitmap = ((BitmapDrawable) dr).getBitmap();
Drawable d = new BitmapDrawable(getResources(), Bitmap.createScaledBitmap(bitmap, 100, 100, true));
mapview.getOverlays().clear();
mapview.invalidate();
selectedPosMarker = new Marker(mapview);
selectedPosMarker.setPosition(geoPoint);
selectedPosMarker.setInfoWindow(null);
selectedPosMarker.setIcon(d);
selectedPosMarker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM);
mapview.getOverlays().add(selectedPosMarker);
mapview.invalidate();
}
I assume you add a MapEventsOverlay somewhere, in a part of your code you didn't provided.
The issue is that you remove it in addMarker! :
mapview.getOverlays().clear();
So of course it is not present to react to long press on the second time...
Don't call mapview.invalidate() twice in the same method, it's useless and time-consuming.
for some time I've been working on this app, that allows user to take photos. The interesting thing about it, is that there should be some lines drawn over camera preview. The problem is that I'm not quite sure how to do this. I do have codes to initiate camera and to draw line, but I do not know how to merge them.
I use this code to initiate camera on button click:
initCamera.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
//Starting a new Intent
/*Intent nextScreen = new Intent(getActivity().getApplicationContext(), CameraActivity.class);
startActivity(nextScreen);*/
count++;
String file = dir+count+".jpg";
File newfile = new File(file);
try {
newfile.createNewFile();
} catch (IOException e) {}
Uri outputFileUri = Uri.fromFile(newfile);
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(cameraIntent, TAKE_PHOTO_CODE);
}
});
And here's how I usually draw lines:
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
height = displaymetrics.heightPixels;
width = displaymetrics.widthPixels;
imageView1 = (ImageView) findViewById(R.id.imageView1);
Bitmap.Config conf = Bitmap.Config.ARGB_8888;
bmp = Bitmap.createBitmap(width, height, conf);
canvas = new Canvas(bmp);
p = new Paint();
p.setColor(Color.RED);
imageView1.setImageBitmap(bmp);
p.setStrokeWidth(5);
canvas.drawLine(0, height/2, width, height/2, p);
You will need an overlay to draw on top of the live camera preview. The overlay is a child class of the surface the preview is drawn on. The preview class looks something like this:
class Preview extends ViewGroup implements SurfaceHolder.Callback, Camera.PreviewCallback
{
Preview(Context context)
{
super(context);
SurfaceView mSurfaceView;
SurfaceHolder mHolder;
mSurfaceView = new SurfaceView(PreviewContext);
addView(mSurfaceView);
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = mSurfaceView.getHolder();
mHolder.addCallback(this);
PreviewCameraOverlay = new CameraOverlay(context);
addView(PreviewCameraOverlay);
}
// Additional functions like:
// surfaceChanged(SurfaceHolder holder, int format, int width, int height)
// onPreviewFrame(byte[] data, Camera pCamera)
// etc.
}
protected class CameraOverlay extends View
{
public CameraOverlay(Context context)
{
super(context);
setWillNotDraw(false);
setBackgroundColor(Color.TRANSPARENT);
setAlpha(1f);
OverlayPaint = new Paint[PaintColors];
}
// Additional functions:
// onDraw(Canvas canvas)
// onMeasure(int widthMeasureSpec, int heightMeasureSpec)
}
From your main activity you would call: Preview CameraPreview = new Preview(this); and draw whatever it is you want to draw from CameraOverlay's onDraw().