I am working on android.I have some little problem to display dialog fragment in specific position.
Following is some information regarding my code.
I'm taking one Costume adapter for display data.in Adpater Layout i am having one image view and i want to display Dialog Fragment Exact left side of this image view When i Tapped in Image.So I'm Doing Following Code to get X and y Co-ordinate where I tapped in Screen.
holder.img_Infoimage.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
//showDialog( holder.img_Infoimage.getX(), holder.img_Infoimage.getY());
//int position = (int) v.getTag();
Bundle bundle = new Bundle();
bundle.putInt("X", (int) event.getX());
bundle.putInt("Y", (int) event.getY());
//bundle.putInt("X", holder.img_Infoimage.getLeft());
//bundle.putInt("Y", holder.img_Infoimage.getTop());
// bundle.putInt("X", (int) holder.img_Infoimage.getLeft());
// bundle.putInt("Y", (int) holder.img_Infoimage.getTop());
Log.e(this.getClass().getName(), ":::::: position x ::::" +event.getX());
Log.e(this.getClass().getName(), ":::::: position Y ::::" + event.getY());
InfoAlertDialog alertDialog = new InfoAlertDialog();
alertDialog.setArguments(bundle);
alertDialog.show(fragmentManager, NearByFriendsFragment.class.getName());
}
return true;
}
});
And I am Also having on InfoAlertDialog class which is extends by DialogFragment.
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);
WindowManager.LayoutParams wmlp = getDialog().getWindow().getAttributes();
wmlp.gravity = Gravity.TOP | Gravity.LEFT;
/*wmlp.x = 422; //x position
wmlp.y = 49;*/ //y position
getDialog().getWindow().setBackgroundDrawableResource(android.R.color.transparent);
getDialog().setCancelable(true);
Bundle bundle = getArguments();
//Log.e("", "X :::::::" + wmlp.x + " Y:::::" + wmlp.y);
wmlp.x = bundle.getInt("X"); //x position
wmlp.y = bundle.getInt("Y"); //y position
/*
WindowManager.LayoutParams wmlp = getDialog().getWindow().getAttributes();
wmlp.width = ViewGroup.LayoutParams.WRAP_CONTENT;
wmlp.height=ViewGroup.LayoutParams.WRAP_CONTENT;
wmlp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE;
wmlp.gravity = Gravity.TOP | Gravity.LEFT;
wmlp.x = bundle.getInt("X"); //x position
wmlp.y = bundle.getInt("Y"); //y position
wmlp.gravity = Gravity.TOP | Gravity.RIGHT;
wmlp.y = 500;
*/
Log.e("", "X :::::::" + wmlp.x + " Y:::::" + wmlp.y);
//getDialog().getWindow().setAttributes(wmlp);
View view = inflater.inflate(R.layout.dialog_info_alert, container, false);
return view;
}
in All Above code we can have some Comment it's Just for your Reference because i also try this but it's not display dialog at any specific position.
Please anyone can tell me how can i fix it...?
I would recommend looking into PopupWindow. It's a lot more flexible than a Dialog in cases like yours.
I Really try hard to solve this problem and Finally I got solution of this problem.I am share this code with you.
Just making following change in my code.
First Pass Listview in Constructor of Adapter.
int xCoordinates,yCoordinates;
ListView lv;
public NearByFriendsAdapter(Context context, List<NearByFriendsSupportClass> list, FragmentManager fragmentManager, ListView lst_NearByFriends) {
super(context, 0,list);
this.context = context;
this.list = list;
this.fragmentManager=fragmentManager;
this.lv=lst_NearByFriends;
}
and Also taking Two Seperate event to get X and Y co-ordinate of your screen and Display Dialog Like Following.
holder.img_Infoimage.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
int[] listViewCoords = new int[2];
lv.getLocationOnScreen(listViewCoords);
int x = (int) motionEvent.getRawX() - listViewCoords[0];
int y = (int) motionEvent.getRawY() - listViewCoords[1];
//xCoordinates=x-1500;
yCoordinates=y-490;
return false;
}
});
holder.img_Infoimage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Bundle bundle=new Bundle();
//bundle.putInt("X", xCoordinates);
bundle.putInt("Y", yCoordinates);
InfoAlertDialog alertDialog=new InfoAlertDialog();
alertDialog.setArguments(bundle);
alertDialog.show(fragmentManager, NearByFriendsFragment.class.getName());
}
});
And Also making Following change in AlertDialog
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);
WindowManager.LayoutParams wmlp = getDialog().getWindow().getAttributes();
getDialog().getWindow().setBackgroundDrawableResource(android.R.color.transparent);
getDialog().setCancelable(true);
Bundle bundle = getArguments();
wmlp.y = bundle.getInt("Y");
getDialog().getWindow().setAttributes(wmlp);
View view=inflater.inflate(R.layout.dialog_info_alert,container,false);
Log.e("", "X :::::::" + wmlp.x + " Y:::::" + wmlp.y);
return view;
}
Thanks,
I hope it's Help full to you.
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 have spend like 2 hours,
I'm unable to figure out what is the issue in service. I'm not calling stopService() or stopSelf from anywhere else. Below is the code ,
public class FloatingViewService extends Service {
private WindowManager mWindowManager;
private View mFloatingView;
WindowManager.LayoutParams params,landscapeParams,nonTouchableParams;
public FloatingViewService() {
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
//Inflate the floating view layout we created
mFloatingView = LayoutInflater.from(this).inflate(R.layout.layout_floating_widget, null);
//Add the view to the window.
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
params.x = 0;
params.y = 100;
//Add the view to the window.
landscapeParams = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
//Specify the view position
landscapeParams.gravity = Gravity.TOP | Gravity.LEFT; //Initially view will be added to top-left corner
landscapeParams.x = 0;
landscapeParams.y = 100;
//Add the view to the window.
nonTouchableParams = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
PixelFormat.TRANSLUCENT);
//Specify the view position
nonTouchableParams.gravity = Gravity.TOP | Gravity.LEFT; //Initially view will be added to top-left corner
nonTouchableParams.x = 0;
nonTouchableParams.y = 100;
//Add the view to the window
mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
mWindowManager.addView(mFloatingView, params);
//The root element of the collapsed view layout
final View collapsedView = mFloatingView.findViewById(R.id.collapse_view);
//The root element of the expanded view layout
final View expandedView = mFloatingView.findViewById(R.id.expanded_container);
//Set the close button
ImageView closeButtonCollapsed = (ImageView) mFloatingView.findViewById(R.id.close_btn);
closeButtonCollapsed.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//close the service and remove the from from the window
stopSelf();
}
});
//Set the close button
ImageView closeButton = (ImageView) mFloatingView.findViewById(R.id.close_button);
closeButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
collapsedView.setVisibility(View.VISIBLE);
expandedView.setVisibility(View.GONE);
}
});
//Set the close button
ImageView lock = (ImageView) mFloatingView.findViewById(R.id.lock_button);
lock.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mWindowManager.updateViewLayout(mFloatingView, nonTouchableParams);
}
});
//Set the close button
ImageView expand = (ImageView) mFloatingView.findViewById(R.id.expand);
expand.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mWindowManager.updateViewLayout(mFloatingView, landscapeParams);
}
});
//Drag and move floating view using user's touch action.
mFloatingView.findViewById(R.id.root_container).setOnTouchListener(new View.OnTouchListener() {
private int initialX;
private int initialY;
private float initialTouchX;
private float initialTouchY;
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
//remember the initial position.
initialX = params.x;
initialY = params.y;
//get the touch location
initialTouchX = event.getRawX();
initialTouchY = event.getRawY();
return true;
case MotionEvent.ACTION_UP:
int Xdiff = (int) (event.getRawX() - initialTouchX);
int Ydiff = (int) (event.getRawY() - initialTouchY);
//The check for Xdiff <10 && YDiff< 10 because sometime elements moves a little while clicking.
//So that is click event.
if (Xdiff < 10 && Ydiff < 10) {
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);
}
}
return true;
case MotionEvent.ACTION_MOVE:
//Calculate the X and Y coordinates of the view.
params.x = initialX + (int) (event.getRawX() - initialTouchX);
params.y = initialY + (int) (event.getRawY() - initialTouchY);
//Update the layout with new X & Y coordinate
mWindowManager.updateViewLayout(mFloatingView, params);
return true;
}
return false;
}
});
}
/**
* Detect if the floating view is collapsed or expanded.
*
* #return true if the floating view is collapsed.
*/
private boolean isViewCollapsed() {
return mFloatingView == null || mFloatingView.findViewById(R.id.collapse_view).getVisibility() == View.VISIBLE;
}
#Override
public void onDestroy() {
super.onDestroy();
if (mFloatingView != null) mWindowManager.removeView(mFloatingView);
}
}
I am not able to figure out anomalous behaviour help me out.
Start your service as forground.
https://developer.android.com/reference/android/app/Service.html#startForeground(int, android.app.Notification)
Since you want your service to run continuously you will have to override the onStartCommand method and return START_STICKY
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
For started services, there are two additional major modes of operation they can decide to run in, depending on the value they return from onStartCommand(): START_STICKY is used for services that are explicitly started and stopped as needed, while START_NOT_STICKY or START_REDELIVER_INTENT are used for services that should only remain running while processing any commands sent to them. See the linked documentation for more detail on the semantics.
https://developer.android.com/reference/android/app/Service.html
So , I have one fragment in which I have two buttons.
I want to get this button position in this fragment. So, I'm trying to do this:
Button button;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
final View w = inflater.inflate(R.layout.fragment_buttons, container, false);
button = (Button)w.findViewById(R.id.button);
final ViewTreeObserver obs = button.getViewTreeObserver();
obs.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
#Override
public boolean onPreDraw () {
Rect r = locateView(w.findViewById(R.id.button));
return true;
}
});
return w;
}
And this is how I'm getting button position
public Rect locateView(View view) {
Rect loc = new Rect();
int[] location = new int[2];
if (view == null) {
return loc;
}
view.getLocationOnScreen(location);
loc.left = location[0];
loc.top = location[1];
loc.right = loc.left + view.getWidth();
loc.bottom = loc.top + view.getHeight();
return loc;
}
However , problem is that onPreDraw is never called. What I'm doing wrong?
I've just figured out how to solve this problem.
button = (Button)w.findViewById(R.id.button);
ViewTreeObserver observer = button.getViewTreeObserver();
observer.addOnGlobalLayoutListener (new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
Rect r = locateView(button);
button.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
});
This code is working. However, I still don't have any idea why previous version didn't work.
I use the following code to draw GraphView on LinearLayout,whose parent is a RelativeLayout
the code for drawing GraphView on LinearLayout
mLinearView = (LinearLayout) findViewById(R.id.LinearView);//ChildLayout
mRelativeView = (RelativeLayout) findViewById(R.id.RelativeLay);//ParentLayout
YearXYGraph mYearGraph = new YearXYGraph();
final GraphicalView mGraphView = mYearGraph.execution(
MainActivity.this, mGirlHeightYearFirstGrade,
mGirlHeightYearSecondGrade,
mGirlHeightYearThirdGrade,
mGirlHeightYearFourthGrade,
mGirlHeightYearFifthGrade, mGirlWeightYearFirstGrade,
mGirlWeightYearSecondGrade, mGirlWeightYearThirdGrade,
mGirlWeightYearFourthGrade, mGirlWeightYearFifthGrade);
mLinearView.addView(mGraphView);
onclicking LinearLayout I'm Showing a popup,code follows
mGraphView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
double[] xy = mGraphView.toRealPoint(0);
p = new Point();
p.x = (int) xy[0];
p.y = (int) xy[1];
if (p != null){
showPopup(MainActivity.this, p);
}
}
});
Im also using onClick event on ParentLayout to get some coordinate
mRelativeView.setOnTouchListener(new RelativeLayout.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
System.out.println("in--");
p1 = new Point();
p1.x = (int) event.getX();
p1.y = (int) event.getY();
System.out.println("x--"+p1.x);
return false;
}
});
code for Showing popup
// The method that displays the popup.
private void showPopup(final Activity context, Point p) {
int popupWidth = 75;
int popupHeight = 40;
// Inflate the popup_layout.xml
LinearLayout viewGroup = (LinearLayout) context.findViewById(R.id.popup);
LayoutInflater layoutInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = layoutInflater.inflate(R.layout.popup_layout, viewGroup);
// Creating the PopupWindow
final PopupWindow popup = new PopupWindow(context);
popup.setContentView(layout);
popup.setWidth(popupWidth);
popup.setHeight(popupHeight);
popup.setFocusable(true);
Rect location = new Rect();
location.left =p1.x;
location.top = p1.y;
location.right = location.left + popup.getWidth();
location.bottom = location.top + popup.getHeight();
/* // Some offset to align the popup a bit to the right, and a bit down, relative to button's position.
int OFFSET_X = 30;
int OFFSET_Y = 30;*/
// Clear the default translucent background
popup.setBackgroundDrawable(new BitmapDrawable());
// Displaying the popup at the specified location, + offsets.
// popup.showAtLocation(layout, Gravity.TOP|Gravity.LEFT, location.left , location.bottom );
popup.showAtLocation(layout, Gravity.TOP|Gravity.LEFT, location.left , location.bottom );
// Getting a reference to Close button, and close the popup when clicked.
TextView firstView = (TextView) layout.findViewById(R.id.textView1);
firstView.setText(p.x + " , " +p.y);
firstView.setTextColor(Color.WHITE);
}
problem is onClickEvent not detected on ParentLayout,,Child Layout detects OnClick,please provide some suggestions
I am trying to make a popup window appear above/below an item that is clicked inside of a ListView.
However, the problem is that the View that is coming in from the OnItemClick method is only giving me its X & Y values relative to the ListView itself. I also checked the ListView and that is also giving me x=0 y=0 despite the fact that there are other views above it.
I ran through all the values in hierarchyviewer, but didn't see the values I was looking for. (And not I'm having major problems getting it to work again).
Any advice?
#Override
public void onListItemClick(ListView listView, View view, int position, long id) {
LayoutInflater inflater = getLayoutInflater(null);
PopupWindow quickRail = new PopupWindow(
inflater.inflate(R.layout.quanitity_controls, null), view.getMeasuredWidth(),
view.getMeasuredHeight());
int[] location = {
0, 0
};
// This doesn't place this window right on top of the view
quickRail.showAtLocation(view, Gravity.CENTER, 0, location[1]);
}
Both items in the list are making the Popup appear in the same place.
This should work
//Activity windows height
int totalHeight = getWindowManager().getDefaultDisplay().getHeight();
int[] location = new int[2];
v.getLocationOnScreen(location);
The location array should have the x and y values of the view.
'v' is the view object passed on the onItemClickListener.
Im adding some parts I used for my project. It might be helpful. I had an actionbar on the top of the listview and this code seemed to work fine.
The requirement was to bring a small menu either on top or below a list item. So when an item is selected, I check if the selected list item is in the upper half of the screen, if so put the menu below the list item otherwise put it on top of the list item.
Here's the code
ListItem click code
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position
, long id) {
showQuickActionMenu(position,view);
}
});
private void showQuickActionMenu(int pos, View v){
LayoutInflater inflater =
(LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//This is just a view with buttons that act as a menu.
View popupView = inflater.inflate(R.layout.ticket_list_menu, null);
popupView.findViewById(R.id.menu_view).setTag(pos);
popupView.findViewById(R.id.menu_change_status).setTag(pos);
popupView.findViewById(R.id.menu_add_note).setTag(pos);
popupView.findViewById(R.id.menu_add_attachment).setTag(pos);
window = PopupHelper.newBasicPopupWindow(TicketList.this);
window.setContentView(popupView);
int totalHeight = getWindowManager().getDefaultDisplay().getHeight();
int[] location = new int[2];
v.getLocationOnScreen(location);
if (location[1] < (totalHeight / 2.0)) {
PopupHelper.showLikeQuickAction(window, popupView, v
, getWindowManager(),0,0,PopupHelper.UPPER_HALF);
} else {
PopupHelper.showLikeQuickAction(window, popupView, v
, getWindowManager(),0, 0,PopupHelper.LOWER_HALF);
}
}
This the PopupHelper class I use
public class PopupHelper {
public static final int UPPER_HALF = 0;
public static final int LOWER_HALF = 1;
public static PopupWindow newBasicPopupWindow(Context context) {
final PopupWindow window = new PopupWindow(context);
// when a touch even happens outside of the window
// make the window go away
window.setTouchInterceptor(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_OUTSIDE) {
window.dismiss();
return true;
}
return false;
}
});
window.setWidth(WindowManager.LayoutParams.WRAP_CONTENT);
window.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
window.setTouchable(true);
window.setFocusable(true);
window.setOutsideTouchable(true);
window.setBackgroundDrawable(
new ColorDrawable(android.R.color.darker_gray));
return window;
}
/**
* Displays like a QuickAction from the anchor view.
*
* #param xOffset
* offset in the X direction
* #param yOffset
* offset in the Y direction
*/
public static void showLikeQuickAction(PopupWindow window, View root,
View anchor, WindowManager windowManager, int xOffset
,int yOffset,int section) {
//window.setAnimationStyle(R.style.Animations_GrowFromBottomRight);
int[] location = new int[2];
anchor.getLocationOnScreen(location);
Rect anchorRect = new Rect(location[0], location[1], location[0] +
anchor.getWidth(), location[1] + anchor.getHeight());
root.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
int rootWidth = root.getMeasuredWidth();
int rootHeight = root.getMeasuredHeight();
int screenWidth = windowManager.getDefaultDisplay().getWidth();
int screenHeight = windowManager.getDefaultDisplay().getHeight();
int xPos = ((screenWidth - rootWidth) / 2) + xOffset;
int yPos = anchorRect.top - rootHeight + yOffset;
xPos = (screenWidth - rootWidth);
if(section == UPPER_HALF){
yPos = anchorRect.top + anchor.getMeasuredHeight();
} else {
yPos = anchorRect.top - rootHeight;
}
window.showAtLocation(anchor, Gravity.NO_GRAVITY, xPos, yPos);
}
}
for those who stick on this issue
try use this code snippet
popWindow.showAsDropDown(v);//v is your listview or recyclerview item Element that clicked.
hope this help.
Try this and see if it works..
private void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
// pre-condition
return;
}
int totalHeight = 0;
int desiredWidth = MeasureSpec.makeMeasureSpec(listView.getWidth(), MeasureSpec.AT_MOST);
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, listView);
listItem.measure(desiredWidth, MeasureSpec.UNSPECIFIED);
totalHeight += listItem.getMeasuredHeight();
}
}
//here listItem.getMeasuredHeight() will get u the height of each list item...U can get ur y position by height*clickedPosition