I choose brightness in my app by this method
public void setBrightness(Context context, int progress) {
float BackLightValue = (float) progress/100;
WindowManager.LayoutParams layoutParams = ((Activity) context).getWindow().getAttributes();
if (BackLightValue == 0.0) {
BackLightValue = 0.01f;
}
layoutParams.screenBrightness = BackLightValue;
// layoutParams.screenBrightness = progress;
((Activity) context).getWindow().setAttributes(layoutParams);
}
this code works, but if I go to another activity brightness settings go back to previous.
How can I change brightness in all application? or I must to restore it on oncreate method on all activities?
Related
This question already has answers here:
SYSTEM_ALERT_WINDOW PERMISSION on API 26 not working as expected. Permission denied for window type 2002
(6 answers)
Closed 3 years ago.
I was working in Floating Widget service icon ,the code is working fine till android version 6.1,i am able to get the notification icon from the server when it send the notification.
but while testing it in android version 8.1 the application getting crushed when the notification is send from the server,
but i am not able to find the solution for it.i dont have any idea why it is happening.
LOGCAT
beginning of crash
2019-03-02 11:41:21.416 12616-12616/com.progressive_solution.parttimeforce E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.progressive_solution.parttimeforce, PID: 12616
java.lang.RuntimeException: Unable to create service com.progressive_solution.parttimeforce.FloatingWidgetService: android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W#ac5309 -- permission denied for window type 2002
at android.app.ActivityThread.handleCreateService(ActivityThread.java:3568)
at android.app.ActivityThread.-wrap4(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1812)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:7000)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:441)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408)
Caused by: android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W#ac5309 -- permission denied for window type 2002
at android.view.ViewRootImpl.setView(ViewRootImpl.java:1026)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:384)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:101)
at com.progressive_solution.parttimeforce.FloatingWidgetService.addRemoveView(FloatingWidgetService.java:86)
at com.progressive_solution.parttimeforce.FloatingWidgetService.onCreate(FloatingWidgetService.java:58)
at android.app.ActivityThread.handleCreateService(ActivityThread.java:3558)
at android.app.ActivityThread.-wrap4(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1812)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:7000)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:441)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408)
MYCODE
FloatingWidgetService.java
public class FloatingWidgetService extends Service implements View.OnClickListener
{
private WindowManager mWindowManager;
private View mFloatingWidgetView, collapsedView, expandedView;
private ImageView remove_image_view;
private Point szWindow = new Point();
private View removeFloatingWidgetView;
private int x_init_cord, y_init_cord, x_init_margin, y_init_margin;
//Variable to check if the Floating widget view is on left side or in right side
// initially we are displaying Floating widget view to Left side so set it to true
private boolean isLeft = true;
public FloatingWidgetService() {
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
//init WindowManager
mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
getWindowManagerDefaultDisplay();
//Init LayoutInflater
LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
addRemoveView(inflater);
addFloatingWidgetView(inflater);
implementClickListeners();
implementTouchListenerToFloatingWidgetView();
}
/* Add Remove View to Window Manager */
private View addRemoveView(LayoutInflater inflater) {
//Inflate the removing view layout we created
removeFloatingWidgetView = inflater.inflate(R.layout.remove_floating_widget_layout, null);
//Add the view to the window.
WindowManager.LayoutParams paramRemove = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
PixelFormat.TRANSLUCENT);
//Specify the view position
paramRemove.gravity = Gravity.TOP | Gravity.LEFT;
//Initially the Removing widget view is not visible, so set visibility to GONE
removeFloatingWidgetView.setVisibility(View.GONE);
remove_image_view = (ImageView) removeFloatingWidgetView.findViewById(R.id.remove_img);
//Add the view to the window
mWindowManager.addView(removeFloatingWidgetView, paramRemove);
return remove_image_view;
}
/* Add Floating Widget View to Window Manager */
private void addFloatingWidgetView(LayoutInflater inflater) {
//Inflate the floating view layout we created
mFloatingWidgetView = inflater.inflate(R.layout.activity_floating_widget_service, null);
//Add the view to the window.
final 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);
//Specify the view position
params.gravity = Gravity.TOP | Gravity.LEFT;
//Initially view will be added to top-left corner, you change x-y coordinates according to your need
params.x = 0;
params.y = 100;
//Add the view to the window
mWindowManager.addView(mFloatingWidgetView, params);
//find id of collapsed view layout
collapsedView = mFloatingWidgetView.findViewById(R.id.collapse_view);
//find id of the expanded view layout
expandedView = mFloatingWidgetView.findViewById(R.id.expanded_container);
}
private void getWindowManagerDefaultDisplay() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2)
mWindowManager.getDefaultDisplay().getSize(szWindow);
else {
int w = mWindowManager.getDefaultDisplay().getWidth();
int h = mWindowManager.getDefaultDisplay().getHeight();
szWindow.set(w, h);
}
}
/* Implement Touch Listener to Floating Widget Root View */
private void implementTouchListenerToFloatingWidgetView() {
//Drag and move floating view using user's touch action.
mFloatingWidgetView.findViewById(R.id.root_container).setOnTouchListener(new View.OnTouchListener() {
long time_start = 0, time_end = 0;
boolean isLongClick = false;//variable to judge if user click long press
boolean inBounded = false;//variable to judge if floating view is bounded to remove view
int remove_img_width = 0, remove_img_height = 0;
Handler handler_longClick = new Handler();
Runnable runnable_longClick = new Runnable() {
#Override
public void run() {
//On Floating Widget Long Click
//Set isLongClick as true
isLongClick = true;
//Set remove widget view visibility to VISIBLE
removeFloatingWidgetView.setVisibility(View.VISIBLE);
onFloatingWidgetLongClick();
}
};
#Override
public boolean onTouch(View v, MotionEvent event) {
//Get Floating widget view params
WindowManager.LayoutParams layoutParams = (WindowManager.LayoutParams) mFloatingWidgetView.getLayoutParams();
//get the touch location coordinates
int x_cord = (int) event.getRawX();
int y_cord = (int) event.getRawY();
int x_cord_Destination, y_cord_Destination;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
time_start = System.currentTimeMillis();
handler_longClick.postDelayed(runnable_longClick, 600);
remove_img_width = remove_image_view.getLayoutParams().width;
remove_img_height = remove_image_view.getLayoutParams().height;
x_init_cord = x_cord;
y_init_cord = y_cord;
//remember the initial position.
x_init_margin = layoutParams.x;
y_init_margin = layoutParams.y;
return true;
case MotionEvent.ACTION_UP:
isLongClick = false;
removeFloatingWidgetView.setVisibility(View.GONE);
remove_image_view.getLayoutParams().height = remove_img_height;
remove_image_view.getLayoutParams().width = remove_img_width;
handler_longClick.removeCallbacks(runnable_longClick);
//If user drag and drop the floating widget view into remove view then stop the service
if (inBounded) {
stopSelf();
inBounded = false;
break;
}
//Get the difference between initial coordinate and current coordinate
int x_diff = x_cord - x_init_cord;
int y_diff = y_cord - y_init_cord;
//The check for x_diff <5 && y_diff< 5 because sometime elements moves a little while clicking.
//So that is click event.
if (Math.abs(x_diff) < 5 && Math.abs(y_diff) < 5) {
time_end = System.currentTimeMillis();
//Also check the difference between start time and end time should be less than 300ms
if ((time_end - time_start) < 300)
onFloatingWidgetClick();
}
y_cord_Destination = y_init_margin + y_diff;
int barHeight = getStatusBarHeight();
if (y_cord_Destination < 0) {
y_cord_Destination = 0;
} else if (y_cord_Destination + (mFloatingWidgetView.getHeight() + barHeight) > szWindow.y) {
y_cord_Destination = szWindow.y - (mFloatingWidgetView.getHeight() + barHeight);
}
layoutParams.y = y_cord_Destination;
inBounded = false;
//reset position if user drags the floating view
resetPosition(x_cord);
return true;
case MotionEvent.ACTION_MOVE:
int x_diff_move = x_cord - x_init_cord;
int y_diff_move = y_cord - y_init_cord;
x_cord_Destination = x_init_margin + x_diff_move;
y_cord_Destination = y_init_margin + y_diff_move;
//If user long click the floating view, update remove view
if (isLongClick) {
int x_bound_left = szWindow.x / 2 - (int) (remove_img_width * 1.5);
int x_bound_right = szWindow.x / 2 + (int) (remove_img_width * 1.5);
int y_bound_top = szWindow.y - (int) (remove_img_height * 1.5);
//If Floating view comes under Remove View update Window Manager
if ((x_cord >= x_bound_left && x_cord <= x_bound_right) && y_cord >= y_bound_top) {
inBounded = true;
int x_cord_remove = (int) ((szWindow.x - (remove_img_height * 1.5)) / 2);
int y_cord_remove = (int) (szWindow.y - ((remove_img_width * 1.5) + getStatusBarHeight()));
if (remove_image_view.getLayoutParams().height == remove_img_height) {
remove_image_view.getLayoutParams().height = (int) (remove_img_height * 1.5);
remove_image_view.getLayoutParams().width = (int) (remove_img_width * 1.5);
WindowManager.LayoutParams param_remove = (WindowManager.LayoutParams) removeFloatingWidgetView.getLayoutParams();
param_remove.x = x_cord_remove;
param_remove.y = y_cord_remove;
mWindowManager.updateViewLayout(removeFloatingWidgetView, param_remove);
}
layoutParams.x = x_cord_remove + (Math.abs(removeFloatingWidgetView.getWidth() - mFloatingWidgetView.getWidth())) / 2;
layoutParams.y = y_cord_remove + (Math.abs(removeFloatingWidgetView.getHeight() - mFloatingWidgetView.getHeight())) / 2;
//Update the layout with new X & Y coordinate
mWindowManager.updateViewLayout(mFloatingWidgetView, layoutParams);
break;
} else {
//If Floating window gets out of the Remove view update Remove view again
inBounded = false;
remove_image_view.getLayoutParams().height = remove_img_height;
remove_image_view.getLayoutParams().width = remove_img_width;
onFloatingWidgetClick();
}
}
layoutParams.x = x_cord_Destination;
layoutParams.y = y_cord_Destination;
//Update the layout with new X & Y coordinate
mWindowManager.updateViewLayout(mFloatingWidgetView, layoutParams);
return true;
}
return false;
}
});
}
private void implementClickListeners() {
mFloatingWidgetView.findViewById(R.id.close_floating_view).setOnClickListener(this);
mFloatingWidgetView.findViewById(R.id.close_expanded_view).setOnClickListener(this);
mFloatingWidgetView.findViewById(R.id.open_activity_button).setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.close_floating_view:
//close the service and remove the from from the window
stopSelf();
break;
case R.id.close_expanded_view:
collapsedView.setVisibility(View.VISIBLE);
expandedView.setVisibility(View.GONE);
break;
case R.id.open_activity_button:
//open the activity and stop service
Intent intent = new Intent(FloatingWidgetService.this, Get_Permission.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
//close the service and remove view from the view hierarchy
stopSelf();
break;
}
}
/* on Floating Widget Long Click, increase the size of remove view as it look like taking focus */
private void onFloatingWidgetLongClick() {
//Get remove Floating view params
WindowManager.LayoutParams removeParams = (WindowManager.LayoutParams) removeFloatingWidgetView.getLayoutParams();
//get x and y coordinates of remove view
int x_cord = (szWindow.x - removeFloatingWidgetView.getWidth()) / 2;
int y_cord = szWindow.y - (removeFloatingWidgetView.getHeight() + getStatusBarHeight());
removeParams.x = x_cord;
removeParams.y = y_cord;
//Update Remove view params
mWindowManager.updateViewLayout(removeFloatingWidgetView, removeParams);
}
/* Reset position of Floating Widget view on dragging */
private void resetPosition(int x_cord_now) {
if (x_cord_now <= szWindow.x / 2) {
isLeft = true;
moveToLeft(x_cord_now);
} else {
isLeft = false;
moveToRight(x_cord_now);
}
}
/* Method to move the Floating widget view to Left */
private void moveToLeft(final int current_x_cord) {
final int x = szWindow.x - current_x_cord;
new CountDownTimer(500, 5) {
//get params of Floating Widget view
WindowManager.LayoutParams mParams = (WindowManager.LayoutParams) mFloatingWidgetView.getLayoutParams();
public void onTick(long t) {
long step = (500 - t) / 5;
mParams.x = 0 - (int) (current_x_cord * current_x_cord * step);
//If you want bounce effect uncomment below line and comment above line
// mParams.x = 0 - (int) (double) bounceValue(step, x);
//Update window manager for Floating Widget
mWindowManager.updateViewLayout(mFloatingWidgetView, mParams);
}
public void onFinish() {
mParams.x = 0;
//Update window manager for Floating Widget
mWindowManager.updateViewLayout(mFloatingWidgetView, mParams);
}
}.start();
}
/* Method to move the Floating widget view to Right */
private void moveToRight(final int current_x_cord) {
new CountDownTimer(500, 5) {
//get params of Floating Widget view
WindowManager.LayoutParams mParams = (WindowManager.LayoutParams) mFloatingWidgetView.getLayoutParams();
public void onTick(long t) {
long step = (500 - t) / 5;
mParams.x = (int) (szWindow.x + (current_x_cord * current_x_cord * step) - mFloatingWidgetView.getWidth());
//If you want bounce effect uncomment below line and comment above line
// mParams.x = szWindow.x + (int) (double) bounceValue(step, x_cord_now) - mFloatingWidgetView.getWidth();
//Update window manager for Floating Widget
mWindowManager.updateViewLayout(mFloatingWidgetView, mParams);
}
public void onFinish() {
mParams.x = szWindow.x - mFloatingWidgetView.getWidth();
//Update window manager for Floating Widget
mWindowManager.updateViewLayout(mFloatingWidgetView, mParams);
}
}.start();
}
/* Get Bounce value if you want to make bounce effect to your Floating Widget */
private double bounceValue(long step, long scale) {
double value = scale * java.lang.Math.exp(-0.055 * step) * java.lang.Math.cos(0.08 * step);
return value;
}
/* Detect if the floating view is collapsed or expanded */
private boolean isViewCollapsed() {
return mFloatingWidgetView == null || mFloatingWidgetView.findViewById(R.id.collapse_view).getVisibility() == View.VISIBLE;
}
/* return status bar height on basis of device display metrics */
private int getStatusBarHeight() {
return (int) Math.ceil(25 * getApplicationContext().getResources().getDisplayMetrics().density);
}
/* Update Floating Widget view coordinates on Configuration change */
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
getWindowManagerDefaultDisplay();
WindowManager.LayoutParams layoutParams = (WindowManager.LayoutParams) mFloatingWidgetView.getLayoutParams();
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
if (layoutParams.y + (mFloatingWidgetView.getHeight() + getStatusBarHeight()) > szWindow.y) {
layoutParams.y = szWindow.y - (mFloatingWidgetView.getHeight() + getStatusBarHeight());
mWindowManager.updateViewLayout(mFloatingWidgetView, layoutParams);
}
if (layoutParams.x != 0 && layoutParams.x < szWindow.x) {
resetPosition(szWindow.x);
}
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
if (layoutParams.x > szWindow.x) {
resetPosition(szWindow.x);
}
}
}
/* on Floating widget click show expanded view */
private void onFloatingWidgetClick() {
if (isViewCollapsed()) {
//When user clicks on the image view of the collapsed layout,
//visibility of the collapsed layout will be changed to "View.GONE"
//and expanded view will become visible.
collapsedView.setVisibility(View.GONE);
expandedView.setVisibility(View.VISIBLE);
}
}
#Override
public void onDestroy() {
super.onDestroy();
/* on destroy remove both view from window manager */
if (mFloatingWidgetView != null)
mWindowManager.removeView(mFloatingWidgetView);
if (removeFloatingWidgetView != null)
mWindowManager.removeView(removeFloatingWidgetView);
}
}
Permissioncheck.java
private void writeCalendarEvent()
{
Log.d(Utils.LogTag, "lst_StartService -> Utils.canDrawOverlays(Main.this): " + Utils.canDrawOverlays(Permissioncheck.this));
if(Utils.canDrawOverlays(Permissioncheck.this))
{
checkPermission_Contact();
startService();
}
else
{
requestPermission(OVERLAY_PERMISSION_REQ_CODE_CHATHEAD);
}
}
public void startService()
{
boolean results = checkPermission_Contact();
if (results)
{
Intent k = new Intent(context, Login.class);
startActivity(k);
}
}
private void needPermissionDialog(final int requestCode)
{
android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(Permissioncheck.this);
builder.setMessage("You need to allow permission");
builder.setPositiveButton("OK",
new android.content.DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which)
{
// TODO Auto-generated method stub
requestPermission(requestCode);
}
});
builder.setNegativeButton("Cancel", new android.content.DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which)
{
// TODO Auto-generated method stub
}
});
builder.setCancelable(false);
builder.show();
}
#Override
protected void onResume()
{
// TODO Auto-generated method stub
super.onResume();
}
private void requestPermission(int requestCode)
{
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, requestCode);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == OVERLAY_PERMISSION_REQ_CODE_CHATHEAD)
{
if (!Utils.canDrawOverlays(Permissioncheck.this))
{
needPermissionDialog(requestCode);
} else
{
startService();
}
}
}
Help me to fix the problem.
add WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
reference
I am trying to scale a view to layout size by using object animator. The view is a LinearLayout. The view does stretch, but not till the screen size in both the directions (i.e X and Y).
Here is the code.
I feel that either the problem is with this:
The formula to calculate how much zoom must be done.
zoomTillX = screen_width/zoomView_width;
zoomTillY = screen_height/zoomView_height;
Or with the Animation property code that is done in a wrong way.
Please let me know how can I achieve a zoom in.
public class MainActivity extends AppCompatActivity {
TextView tv;
double screen_height;
LinearLayout zoomView;
double screen_width;
double zoomTillX;
double zoomTillY;
double zoomView_width;
double zoomView_height;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.tv);
zoomView = (LinearLayout) findViewById(R.id.zoomView);
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
screen_height = (double)dm.heightPixels;
screen_width = (double)dm.widthPixels;
zoomView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
zoomView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
zoomView_width = (double)zoomView.getMeasuredWidth();
zoomView_height = (double)zoomView.getMeasuredHeight();
}
});
zoomView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final Handler handler = new Handler(Looper.getMainLooper());
handler.postDelayed(new Runnable() {
#Override
public void run() {
if(zoomView_width > 0 && zoomView_height > 0)
{
zoomTillX = screen_width/zoomView_width;
zoomTillY = screen_height/zoomView_height;
Log.d("VIEW GET X IS ",String.valueOf(zoomView.getX()));
Log.d("VIEW GET Y IS ",String.valueOf(zoomView.getY()));
ObjectAnimator scaleDownX = ObjectAnimator.ofFloat(zoomView, "scaleX", (float)(zoomTillX));
ObjectAnimator scaleDownY = ObjectAnimator.ofFloat(zoomView, "scaleY",(float)(zoomTillY));
List<Animator> oaList = new ArrayList<Animator>();
oaList.add(scaleDownX);
oaList.add(scaleDownY);
AnimatorSet ani = new AnimatorSet();
ani.playTogether(oaList);
ani.setDuration(500);
ani.start();
}else{
handler.postDelayed(this,300);
}
}
},500);
}
});
}
}
This is how it looks finally.
That can be done via ValueAnimator.
Having this layout as the content of activity:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:id="#+id/view"
android:layout_width="170dp"
android:layout_height="170dp"
android:background="#3143ff"/>
</FrameLayout>
And in activity's onCreate():
final View view = findViewById(R.id.view);
final View contentView = findViewById(R.id.content_frame);
contentView.setOnClickListener(v -> {
final int screenWidth = contentView.getWidth();
final int screenHeight = contentView.getHeight();
ValueAnimator widthAnimator = ValueAnimator.ofInt(view.getWidth(), screenWidth);
ValueAnimator heightAnimator = ValueAnimator.ofInt(view.getHeight(), screenHeight);
widthAnimator.setDuration(1500);
heightAnimator.setDuration(1500);
widthAnimator.addUpdateListener(animation -> {
view.getLayoutParams().width = (int) animation.getAnimatedValue();
view.requestLayout();
});
heightAnimator.addUpdateListener(animation -> {
view.getLayoutParams().height = (int) animation.getAnimatedValue();
view.requestLayout();
});
widthAnimator.start();
heightAnimator.start();
});
This will be the result:
Transitions API
We've implemented this animation ourselves. But why won't we let the system take care of building all this animators?
There's a Transitions API, which will take the heavy lifting for us. All we have to do, is to ask the framework to detect layout changes, create appropriate animators and run the animations.
So, all the code above can be changed to following, which will result in exactly same output:
contentView.setOnClickListener(v -> {
final int screenWidth = contentView.getWidth();
final int screenHeight = contentView.getHeight();
// Uncomment this, if you want Transitions API to run default animation
// TransitionManager.beginDelayedTransition(contentView);
Transition autoTransition = new AutoTransition();
autoTransition.setDuration(1500);
// With this overload you can control actual transition animation
TransitionManager.beginDelayedTransition(contentView, autoTransition);
// After `beginDelayedTransition()` function perform changes to the layout
// Transitions framework will detect those changes and perform appropriate animations
view.getLayoutParams().width = screenWidth;
view.getLayoutParams().height = screenHeight;
view.requestLayout();
view.invalidate();
});
I'm making a little chat in my app and I have an Emoticon Fragment (just like the one from whatsapp or telegram). How can I switch between the fragment and the keyboard without any weird animation?
I already have the fragment wih the emojis and the custom EditText. I just want to switch beween that fragment and keyboard. I really want it to work like whatsapp or Telegram.
For the emoticon Fragment I made a library. I add a fragment (Grid view with SpannableTextViews for each emoji) in the same layout as the EditText.
Any help will be really appreciated.
You don't need to replace the keyboard, you can put your fragment over activity using PopupWindow as Telegram does. Just look at the source: method showEmojiPopup creates EmojiView and put it inside PopupWindow then calculates appropriate size and shows it.
emojiPopup.setHeight(View.MeasureSpec.makeMeasureSpec(currentHeight, View.MeasureSpec.EXACTLY));
emojiPopup.setWidth(View.MeasureSpec.makeMeasureSpec(contentView.getWidth(), View.MeasureSpec.EXACTLY));
emojiPopup.showAtLocation(parentActivity.getWindow().getDecorView(), 83, 0, 0);
You need to code :
public class EmojiKeyboard {
private static final String TAG = "EmojiKeyboard";
private static final String PREF_KEY_HEIGHT_KB = "EmojiKbHeight";
private Context context;
private int screenHeight = -1;
private int emojiKbHeight = -1;
private PopupWindow emojiKeyboardPopup;
private View view;
private SharedPreferences preferences;
public EmojiKeyboard(Context context, View view) {
if (context instanceof Activity) {
this.context = context;
this.view = view;
preferences = context.getSharedPreferences(context.getString(R.string.app_name), Context.MODE_PRIVATE);
//Restore EmojiKeyboard Height
emojiKbHeight = preferences.getInt(PREF_KEY_HEIGHT_KB, -1);
//TODO support less then 11 API, and not perfect resizing when switched the keyboard
view.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
#Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
/*
* Get root view height
* */
screenHeight = screenHeight == -1 && bottom > oldBottom
? bottom
: screenHeight;
/*
* Calculate soft keyboard height
* */
int dHeight = oldBottom - bottom;
boolean validHeight = emojiKbHeight == -1 && dHeight > 80 && bottom != oldBottom;
/*
* Сheck twice because the keyboard may have been switched
* */
emojiKbHeight = validHeight
? dHeight : emojiKbHeight != (dHeight) && dHeight > 0
? dHeight
: emojiKbHeight;
/*
* Store emoji keyboard height into SharedPreferences
* */
preferences.edit().putInt(PREF_KEY_HEIGHT_KB, emojiKbHeight).commit();
/*
* If layout returned to a standard height then dismissing keyboard (OnBackPressed)
* */
if (screenHeight == bottom) {
dismissEmojiKeyboard();
}
/*
* Resize emoji on the go when a user switches between keyboards
* */
resizeEmoji();
}
});
}
}
public void showEmoji() {
if (emojiKeyboardPopup == null) {
createEmojiKeyboard();
}
if (!isShowed()) {
new Handler().postDelayed(new Runnable() {
public void run() {
emojiKeyboardPopup.showAtLocation(view, Gravity.BOTTOM, 0, 0);
resizeEmoji();
}
}, 10L);
} else {
dismissEmojiKeyboard();
}
}
public void createEmojiKeyboard() {
EmojiView emojiKeyboard = new EmojiView(context, EmojiView.EMOJI_DARK_STYLE, new EmojiView.onEmojiClickListener() {
public void onBackspace() {
if (((Activity) context).getWindow().getCurrentFocus() instanceof EditText) {
((Activity) context).getWindow().getCurrentFocus().dispatchKeyEvent(new KeyEvent(0, 67));
}
}
public void onEmojiSelected(Emojicon emojicon) {
if (((Activity) context).getWindow().getCurrentFocus() instanceof EditText) {
EmojiView.input((EditText) ((Activity) context).getWindow().getCurrentFocus(), emojicon);
}
}
});
emojiKeyboardPopup = new PopupWindow(emojiKeyboard);
emojiKeyboardPopup.setHeight(View.MeasureSpec.makeMeasureSpec(setEmojiKeyboardHeight(), View.MeasureSpec.EXACTLY));
emojiKeyboardPopup.setWidth(View.MeasureSpec.makeMeasureSpec(getDisplayDimensions(context).x, View.MeasureSpec.EXACTLY));
emojiKeyboardPopup.setAnimationStyle(0);
}
public void dismissEmojiKeyboard() {
if (isShowed()) {
emojiKeyboardPopup.dismiss();
}
}
public boolean isShowed() {
return emojiKeyboardPopup != null && emojiKeyboardPopup.isShowing();
}
/*
* Emoji set up size
* */
public void resizeEmoji() {
if (isShowed()) {
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
WindowManager.LayoutParams layoutParams = (WindowManager.LayoutParams) emojiKeyboardPopup.getContentView().getLayoutParams();
layoutParams.height = setEmojiKeyboardHeight();
wm.updateViewLayout(emojiKeyboardPopup.getContentView(), layoutParams);
}
}
public int setEmojiKeyboardHeight() {
return emojiKbHeight == -1 && emojiKbHeight != screenHeight && emojiKbHeight < 80
? (getDisplayDimensions(context).y / 2)
: emojiKbHeight;
}
public Point getDisplayDimensions(Context context) {
Point size = new Point();
WindowManager w = ((Activity) context).getWindowManager();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
w.getDefaultDisplay().getSize(size);
} else {
Display d = w.getDefaultDisplay();
size.x = d.getWidth();
size.y = d.getHeight();
}
return size;
}
}
Solve problem
I have a little problem with my Window dimming.
Basically, I want to set the dimAmount of my Activity to zero as soon as I swipe it into one direction.
Please be aware that my Activity is displayed as a dialog, and can be swiped to the left or right. This works perfectly fine. But the setWindowDim() method has no effect when called after swipe.
If i call the setWindowDim inside my onCreate method, it works perfectly fine.
I have no idea why it doesnt work anywhere else.
public class FinishDialog extends Activity {
private FrameLayout frame = null;
private GestureDetector gd = null;
private int displaywidth = 0;
private int original_x = 0;
private int dialog_width = 0;
private final int POS_LEFT = -1;
private final int POS_MID = 0;
private final int POS_RIGHT = 1;
/** the dialogs current position, POS_MID on startup */
private int current_pos = POS_MID;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
//this.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
frame = new FrameLayout(this);
gd = new GestureDetector(this, new TouchManager(this));
// fill the challenge layout into the framelayout
frame.addView(LayoutInflater.from(getBaseContext()).inflate(R.layout.finishdialog, null));
setContentView(frame);
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) frame.getLayoutParams();
GameLogic g = new GameLogic();
displaywidth = g.getDisplayWidth(this);
lp.width = displaywidth - displaywidth / 6;
lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL;
LinearLayout llFinish = (LinearLayout) findViewById(R.id.llFinishDialog);
LinearLayout.LayoutParams lpLL = (LinearLayout.LayoutParams) llFinish.getLayoutParams();
lp.height = lpLL.height;
frame.setLayoutParams(lp);
// setWindowDim(0.0f); ---> if i set the dim here, it works perfectly fine
original_x = (int) frame.getX();
dialog_width = lp.width;
}
private void setWindowDim(float dim) {
Log.i("FinishDialog", "Setting window dim to " + dim + ".");
WindowManager.LayoutParams lpWin = getWindow().getAttributes();
lpWin.dimAmount = dim;
getWindow().setAttributes(lpWin);
}
/**
* move the dialog, depending on the swipe direction and the
* current position of the dialog
* #param action
*/
public void interpretTouch(int action) {
switch(action) {
case TouchManager.MOVE_DIALOG_RIGHT:
if(frame != null) {
if(current_pos == POS_MID) {
swipeDialog(600, frame, 0, dialog_width, 0, 0);
current_pos = POS_RIGHT;
setWindowDim(0.0f); // here setting the dim has no effect
} else if (current_pos == POS_LEFT) {
swipeDialog(600, frame, - dialog_width, original_x, 0, 0);
current_pos = POS_MID;
setWindowDim(0.9f); // here setting the dim has no effect
} else if (current_pos == POS_RIGHT) {
// if we are on the right and swipe right, nothing happens
}
}
Log.i("Challenge", "Moving dialog to the right.");
break;
case TouchManager.MOVE_DIALOG_LEFT:
if(frame != null) {
if(current_pos == POS_MID) {
swipeDialog(600, frame, 0, -dialog_width, 0, 0);
current_pos = POS_LEFT;
setWindowDim(0.0f); // here setting the dim has no effect
} else if (current_pos == POS_LEFT) {
// if we are on the left and swipe left, nothing happens
} else if (current_pos == POS_RIGHT) {
swipeDialog(600, frame, dialog_width, original_x, 0, 0);
current_pos = POS_MID;
setWindowDim(0.9f); // here setting the dim has no effect
}
}
Log.i("Challenge", "Moving dialog to the left.");
break;
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
return gd.onTouchEvent(event);
}
private void swipeDialog(int time, View framelayout, int fromDeltaX, int toDeltaX, int fromDeltaY, int toDeltaY) {
Log.i("FinishDialog", "Dialog swiped.");
TranslateAnimation trans = new TranslateAnimation(fromDeltaX, toDeltaX,
fromDeltaY, toDeltaY);
trans.setFillAfter(true);
trans.setFillEnabled(true);
trans.setDuration(time);
framelayout.startAnimation(trans);
}
}
Starting this activity right after I change the Window dim finally did the job.
Unfortunately, now the Screen flashes pretty "ugly" when the RefreshActivity gets started, does anyone have a solution for that?
import android.app.Activity;
import android.os.Bundle;
public class RefreshActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
finish();
}
}
public void SetBright(float value)
{
Window mywindow = getWindow();
WindowManager.LayoutParams lp = mywindow.getAttributes();
lp.screenBrightness = value;
mywindow.setAttributes(lp);
}
I want to adjust the screen brightness. But nothing happens when i try using this method. Could it be because i use the KEEP_SCREEN_ON flag?
Make sure that "Auto Brightness" is not enabled prior to setting the screen brightness. You can do this manually in Settings>Display or using code if you are using Android 2.2 or above SDK.
Something like:
int brightnessMode = Settings.System.getInt(getContentResolver(), Settings.System.SCREEN_BRIGHTNESS_MODE);
if (brightnessMode == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC) {
Settings.System.putInt(getContentResolver(), Settings.System.SCREEN_BRIGHTNESS_MODE, Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
}
WindowManager.LayoutParams layoutParams = getWindow().getAttributes();
layoutParams.screenBrightness = 0.5F; // set 50% brightness
getWindow().setAttributes(layoutParams);
Ensure the value is between 0.0F and 1.0F. A value of -1.0F uses the default brightness stored in the preferences. Per the documentation "A value of less than 0, the default, means to use the preferred screen brightness. 0 to 1 adjusts the brightness from dark to full bright."
The value of screenBrightness between 0.0f and 1.0f, maybe your value is too big.
I use the WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON flag and also can adjust the screen brightness
Adjust Brightness using a seekbar :
public class AndroidBrightnessActivity extends Activity {
private SeekBar brightbar;
private int brightness;
private ContentResolver cResolver;
private Window window;
TextView txtPerc;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
brightbar = (SeekBar) findViewById(R.id.brightbar);
txtPerc = (TextView) findViewById(R.id.txtPercentage);
cResolver = getContentResolver();
window = getWindow();
brightbar.setMax(255);
brightbar.setKeyProgressIncrement(1);
try
{
brightness = System.getInt(cResolver, System.SCREEN_BRIGHTNESS);
}
catch (SettingNotFoundException e)
{
Log.e("Error", "Cannot access system brightness");
e.printStackTrace();
}
brightbar.setProgress(brightness);
brightbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener()
{
public void onStopTrackingTouch(SeekBar seekBar)
{
System.putInt(cResolver,System.SCREEN_BRIGHTNESS,brightness);
LayoutParams layoutpars = window.getAttributes();
layoutpars.screenBrightness = brightness / (float)255;
window.setAttributes(layoutpars);
}
public void onStartTrackingTouch(SeekBar seekBar)
{
//Nothing handled here
}
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
{
if(progress<=20)
{
brightness=20;
}
else
{
brightness = progress;
}
float perc = (brightness /(float)255)*100;
txtPerc.setText((int)perc +" %");
}
});
}
}
Happy Coding...