ImageView click is not working on custom layout creatd in android service.
public class CallService extends Service {
String incomingnumber;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
incomingnumber = intent.getExtras().getString("incomingnumber");
System.out.println("=== onStartCommand incomingnumber : " + incomingnumber);
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onCreate() {
super.onCreate();
final Context context = getApplicationContext();
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ViewGroup mView = (ViewGroup) inflater.inflate(R.layout.testactivity, null);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
ImageView imgCallPick = mView.findViewById(R.id.imgCallPick);
ImageView imgCaller = mView.findViewById(R.id.imgCaller);
imgCaller.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
System.out.println("===== imgCaller");
return false;
}
});
wm.addView(mView, params);
} }
i just create custom layout in service, the layout contain a diff view but the Imageview click not working. is there any solution for that, then help me.
Thanks
From this answer: Android - ImageView On Click
Add in your xml layout:
android:clickable="true"
This issue is due to use of deprecated param
WindowManager.LayoutParams.TYPE_PHONE
For getting touch events
Use this if you want a colored background
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.RGB_565);
Use this if you want a transparent background
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSPARENT);
Everything else remains same :)
Related
I am trying to make a Android app with a service (Floating widget). Since I am not a pro-programmer, I did not use touch listener to change position of that widget for lot of reasons. But I want user to have options to change position (some preferred locations only) of that widget, and that options will be available in an activity which invoked the service. I am passing data as intent extra from my activity to service, which is to be obtained from service onStartCommand(). The problem I am facing now- I am unable to use data obtained from onStartCommand() in onCreate(). Seems the service is created before onStartCommand() is called and I am getting null pointer exception as some of my variables are not obtaining values from onStartCommand(). I have checked, that these variables are getting values when I use any clickable objects (e.g: press any button view in service), I used a dummy toast for this.
Please share your valuable opinion on how to overcome this problem.
public class MainFloatingWidget extends Service {
private WindowManager windowManager;
private View myFloatingView, myCollapsedView, myExpandedView;
private WindowManager.LayoutParams params;
private String position;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
myFloatingView = LayoutInflater.from(this).inflate(R.layout.layout_main_floating_widget, null);
params = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT);
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
windowManager.addView(myFloatingView, params);
myCollapsedView = myFloatingView.findViewById(R.id.collapsedViewMainService);
myExpandedView = myFloatingView.findViewById(R.id.expandedViewMainService);
myCollapsedView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
myCollapsedView.setVisibility(View.GONE);
myExpandedView.setVisibility(View.VISIBLE);
return true;
}
});
myExpandedView.findViewById(R.id.buttonBack).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
myCollapsedView.setVisibility(View.VISIBLE);
myExpandedView.setVisibility(View.GONE);
}
});
myExpandedView.findViewById(R.id.buttonClose).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
windowManager.removeView(myFloatingView);
stopSelf();
}
});
if(position.equals("Right-Middle")){
params.gravity = Gravity.END | Gravity.CENTER;
}else if(position.equals("Right-Top")){
params.gravity = Gravity.END | Gravity.TOP;
}else if(position.equals("Right-Bottom")){
params.gravity = Gravity.END | Gravity.BOTTOM;
}else if(position.equals("Left-Middle")){
params.gravity = Gravity.START | Gravity.CENTER;
}else if(position.equals("Left-Top")){
params.gravity = Gravity.START | Gravity.TOP;
}else if(position.equals("Left-Bottom")){
params.gravity = Gravity.START | Gravity.BOTTOM;
}else{
params.gravity = Gravity.CENTER;
}
windowManager.updateViewLayout(myFloatingView, params);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
position = (String) intent.getExtras().get("POSITION");
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
super.onDestroy();
}
}
onCreate will call before onStartCommand and only call one time when Service init so you should move your code handle position to inside onStartCommand
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
params = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT);
position = (String) intent.getExtras().get("POSITION");
if(position.equals("Right-Middle")){
params.gravity = Gravity.END | Gravity.CENTER;
}else if(position.equals("Right-Top")){
params.gravity = Gravity.END | Gravity.TOP;
}else if(position.equals("Right-Bottom")){
params.gravity = Gravity.END | Gravity.BOTTOM;
}else if(position.equals("Left-Middle")){
params.gravity = Gravity.START | Gravity.CENTER;
}else if(position.equals("Left-Top")){
params.gravity = Gravity.START | Gravity.TOP;
}else if(position.equals("Left-Bottom")){
params.gravity = Gravity.START | Gravity.BOTTOM;
}else{
params.gravity = Gravity.CENTER;
}
windowManager.updateViewLayout(myFloatingView, params);
return super.onStartCommand(intent, flags, startId);
}
I am making a custom screen call app which will work in services i need two button in services i call that buttons but button click not working in services what i do now?
Service Class
public class MyService extends Service {
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
private View view;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("inez","inez onCreate");
super.onCreate();
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
0,
0,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
0,
// WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.LEFT | Gravity.TOP;
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.activity_main,null);
TextView textview = (TextView) view.findViewById(R.id.text1);
textview.setText("Someone is calling: " + intent.getStringExtra("incomingNumber"));
textview.setBackgroundColor(Color.YELLOW);
wm.addView(view, params);
return START_STICKY;
}
public void onDestroy() {
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.removeView(view);
}
}
Below code snippet only shows view but click on buttons not working. I have tried all solution but nothing seems to work. Another service have same code fragment with different layout works.
public int onStartCommand(final Intent intent, int flags, int startId) {
LayoutInflater inflater = (LayoutInflater)getApplicationContext().getSystemService(LAYOUT_INFLATER_SERVICE);
if (inflater!=null)
v = inflater.inflate(R.layout.layout_accept_sos, null);
close = v.findViewById(R.id.close);
close.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
onDestroy();
}
});
getDirection = v.findViewById(R.id.getDirection);
getDirection.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent intent1=new Intent();
intent1.setAction("open_map");
sendBroadcast(intent1);
// onDestroy();
}
});
params = new WindowManager.LayoutParams(LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, LayoutParams.FLAG_ALT_FOCUSABLE_IM | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, PixelFormat.TRANSLUCENT);
params.gravity = Gravity.LEFT | Gravity.TOP;
params.x = 0;
params.y = 0;
wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
wm.addView(v, params);
return START_STICKY;
}
You need to use WindowManager.FLAG_NOT_FOCUSABLE to make it clickable.
params = new WindowManager.LayoutParams(LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
More description available at https://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#FLAG_NOT_FOCUSABLE
I have a service from which I want to show a layout using a window manager which I successfully implemented but I need to do 2 things I want to access a button in layout and prevent from outside touch. How do I do that
final WindowManager windowManager=(WindowManager)getSystemService(WINDOW_SERVICE);
LayoutInflater inflater=(LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);
final RelativeLayout layout=(RelativeLayout) inflater.inflate(R.layout.sheet,null);
cancel = layout.findViewById(R.id.img_cancel);
cancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
windowManager.removeViewImmediate(layout);
}
});
WindowManager.LayoutParams p = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.RGBA_8888);
p.gravity = Gravity.BOTTOM;
windowManager.addView(layout,p);
Add these flags
WindowManager.LayoutParams p = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? LayoutParams.TYPE_APPLICATION_OVERLAY : LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.RGBA_8888);
Window window = this.getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
Override onTouchEvent() of dialog
public boolean onTouchEvent(MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_OUTSIDE){
System.out.println("TOuch outside the dialog ******************** ");
}
return false;
}
here is the service that i have called to display view above locked screen.i dont want to unlock lock screen i want something that whatsapp and skype use for their calling screen.such that screen is not unlocked.
public class Display extends Service {
private static WindowManager wm;
private static RelativeLayout ly;
private WindowManager.LayoutParams params;
#Override
public void onCreate() {/
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
LayoutInflater vi;
vi = LayoutInflater.from(this);
ly = (RelativeLayout) vi.inflate(R.layout.display, null);
wm = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT |
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
/*ALSO TRIED USING WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON*/
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.RGBA_8888);
params.gravity = Gravity.TOP | Gravity.LEFT;
params.x = 0;
params.y = 300;
ly.setLayoutParams(params);
TextView tv = (TextView) ly.findViewById(R.id.annotationTextView);
tv.setText("check");
wm.addView(ly, params);
return START_NOT_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
}
}
but the screen was appearing below locked screen.
params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.WRAP_CONTENT,
// WindowManager.LayoutParams.TYPE_SYSTEM_ALERT |
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED,
PixelFormat.RGBA_8888);
worked for me but i was not able to touch on it so still unsuccessful