Chat-Heads-Like Popup window - android

I searched the web for how to make a popup window like Facebook's Chat Heads.
I found the following code: http://www.piwai.info/chatheads-basics/
public class ChatHeadService extends Service {
private WindowManager windowManager;
private ImageView chatHead;
#Override public IBinder onBind(Intent intent) {
// Not used
return null;
}
#Override public void onCreate() {
super.onCreate();
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
chatHead = new ImageView(this);
chatHead.setImageResource(R.drawable.ic_launcher);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP | Gravity.LEFT;
params.x = 0;
params.y = 100;
windowManager.addView(chatHead, params);
}
#Override
public void onDestroy() {
super.onDestroy();
if (chatHead != null) windowManager.removeView(chatHead);
}
}
In my Main Activity:
startService(new Intent(context, ChatHeadService.class));
And I use the permission:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
But I don't get the popup notification. Not even his icon.
Can you help me an say what's wrong?
Thanks.

Check if you have added your service to AndroidManifest.xml
<service android:name=".ChatHeadService" ></service>

Try Copy/Paste this in your project or you can create a new project and copy/paste this into it(with the required imports).
MainActivity.class
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
// Method to start the service
public void startService(View view) {
startService(new Intent(getBaseContext(), ChatHeadService.class));
}
// Method to stop the service
public void stopService(View view) {
stopService(new Intent(getBaseContext(), ChatHeadService.class));
}
}
ChatHeadService.class
public class CloseChatHead extends Service {
private WindowManager windowManager;
private ImageView close;
#Override
public IBinder onBind(Intent intent) {
// Not used
return null;
}
WindowManager.LayoutParams mParams;
public WindowManager.LayoutParams getParams(){
return mParams;
}
#Override
public void onCreate() {
super.onCreate();
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
close = new ImageView(this);
close.setImageResource(R.drawable.circle_close);
final WindowManager.LayoutParams params1 = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params1.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
//params1.x = 0;
//params1.y = 100;
mParams=params1;
close.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:
Toast.makeText(getApplicationContext(),"ACTION_DOWN 2",Toast.LENGTH_SHORT).show();
initialX = params1.x;
initialY = params1.y;
initialTouchX = event.getRawX();
initialTouchY = event.getRawY();
return true;
case MotionEvent.ACTION_UP:
return true;
case MotionEvent.ACTION_MOVE:
params1.x = initialX
+ (int) (event.getRawX() - initialTouchX);
params1.y = initialY
+ (int) (event.getRawY() - initialTouchY);
windowManager.updateViewLayout(close, params1);
return true;
}
return false;
}
});
windowManager.addView(close, params1);
}
#Override
public void onDestroy() {
super.onDestroy();
if (close != null)
windowManager.removeView(close);
}
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.chathead.MainActivity" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="#+id/btnStartService"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="startService"
android:text="start_service" />
<Button
android:id="#+id/btnStopService"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="stopService"
android:text="stop_service" />
</LinearLayout>
</RelativeLayout>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.chathead"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="21" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".ChatHeadService" />
<service android:name=".CloseChatHead" />
</application>
</manifest>
Reference for the same: http://www.piwai.info/chatheads-basics/

Related

Layout not showed with good dimension when user click on overlay button

I have an Android app with a Service to Overlay a button on Android (like Facebook chat bubble).
I want to show a layout (overlay.xml) when the user click on the icon but I can't show the layout with the good dimension.
This is my result :
This is my OverlayShowingService.class :
public class OverlayShowingService extends Service {
private WindowManager windowManager;
private ImageView chatHead;
private Boolean _enable = true;
#Override
public IBinder onBind(Intent intent) {
_enable=false;
return null;
}
#Override
public void onCreate() {
super.onCreate();
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
chatHead = new ImageView(this);
chatHead.setImageResource(R.mipmap.ic_launcher);
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP | Gravity.LEFT;
params.x = 0;
params.y = 100;
windowManager.addView(chatHead, params);
chatHead.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
LayoutInflater layoutInflater = (LayoutInflater)getBaseContext()
.getSystemService(LAYOUT_INFLATER_SERVICE);
View popupView = layoutInflater.inflate(R.layout.overlay, null);
final PopupWindow popupWindow = new PopupWindow(popupView,
LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
popupWindow.update();
Button btnDismiss = (Button)popupView.findViewById(R.id.dismiss);
Button endService= (Button) popupView.findViewById(R.id.endService);
endService.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
stopSelf();
Toast.makeText(getApplicationContext(), "Service Terminated", Toast.LENGTH_LONG).show();
}
});
btnDismiss.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
Toast.makeText(getApplicationContext(), "Popup Terminated", Toast.LENGTH_LONG).show();
popupWindow.dismiss();
_enable=true;
}
});
if(_enable){
popupWindow.showAsDropDown(chatHead, 50, -30);
_enable=false;
}
else if(!_enable) {
Log.d("FALSE", "FALSE");
}
}
});
try {
chatHead.setOnTouchListener(new View.OnTouchListener() {
private WindowManager.LayoutParams paramsF = params;
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:
initialX = paramsF.x;
initialY = paramsF.y;
initialTouchX = event.getRawX();
initialTouchY = event.getRawY();
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_MOVE:
paramsF.x = initialX + (int) (event.getRawX() - initialTouchX);
paramsF.y = initialY + (int) (event.getRawY() - initialTouchY);
windowManager.updateViewLayout(chatHead, paramsF);
break;
}
return false;
}
});
} catch (Exception ignored) {}
}
#Override
public void onDestroy() {
super.onDestroy();
if (chatHead != null) windowManager.removeView(chatHead);
}
}
This is the layout overlay.xml :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:orientation="vertical"
android:layout_margin="5dp"
android:background="#545454">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="It's a PopupWindow"
android:textSize="40sp"
android:textColor="#ffffff" />
<Button
android:id="#+id/dismiss"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Dismiss Popup"
android:textColor="#ffffff" />
<Button
android:id="#+id/endService"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Finish Service"
android:textColor="#ffffff" />
</LinearLayout>
Edit: This is an alternate approach that mimics a popup window. I have kept the first answer with a altert dialog approach after the following explanation and code. Either way will work, but this new way may be preferable since it looks more like a popup window.
This approach simply adds the overlay.xml layout into a view that is place on the screen just like the chatHead view is.
OverlayShowingService.java
public class OverlayShowingService extends Service {
private WindowManager windowManager;
private ImageView chatHead;
private Boolean _enable = true;
#Override
public IBinder onBind(Intent intent) {
_enable = false;
return null;
}
#Override
public void onCreate() {
super.onCreate();
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
chatHead = new ImageView(this);
chatHead.setImageResource(R.mipmap.ic_launcher);
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP | Gravity.LEFT;
windowManager.addView(chatHead, params);
chatHead.post(new Runnable() {
#Override
public void run() {
params.x = (int) chatHead.getBottom() + 50;
params.y = (int) chatHead.getRight() - 30;
}
});
chatHead.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
LayoutInflater layoutInflater = (LayoutInflater) getBaseContext()
.getSystemService(LAYOUT_INFLATER_SERVICE);
final View popupView = layoutInflater.inflate(R.layout.overlay, null);
final PopupWindow popupWindow = new PopupWindow(popupView,
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
popupWindow.update();
Button btnDismiss = (Button) popupView.findViewById(R.id.dismiss);
Button endService = (Button) popupView.findViewById(R.id.endService);
endService.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
windowManager.removeViewImmediate(popupView);
stopSelf();
Toast.makeText(getApplicationContext(), "Service Terminated", Toast.LENGTH_LONG).show();
}
});
btnDismiss.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
Toast.makeText(getApplicationContext(), "Popup Terminated", Toast.LENGTH_LONG).show();
// popupWindow.dismiss();
windowManager.removeViewImmediate(popupView);
_enable = true;
}
});
if (_enable) {
windowManager.addView(popupView, params);
// popupWindow.showAsDropDown(chatHead, 50, -30);
_enable = false;
} else if (!_enable) {
Log.d("FALSE", "FALSE");
}
}
});
try {
chatHead.setOnTouchListener(new View.OnTouchListener() {
private WindowManager.LayoutParams paramsF = params;
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:
initialX = paramsF.x;
initialY = paramsF.y;
initialTouchX = event.getRawX();
initialTouchY = event.getRawY();
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_MOVE:
paramsF.x = initialX + (int) (event.getRawX() - initialTouchX);
paramsF.y = initialY + (int) (event.getRawY() - initialTouchY);
windowManager.updateViewLayout(chatHead, paramsF);
break;
}
return false;
}
});
} catch (Exception ignored) {
}
}
#Override
public void onDestroy() {
super.onDestroy();
if (chatHead != null) windowManager.removeView(chatHead);
}
}
The first approach using an alert dialog.
Your code works as-is for API 21 and below. Something changed with API 22 that is prohibiting what you want to do.
I think the primary issue is with the popup and the service environment. I have modified your code to use an AlertDialog with the type TYPE_SYSTEM_ALERT. Although the styling is not what you want, it does work otherwise. You may be able to get it to style differently if you play with it a little.
Another alternative would be to start an activity from your service. An activity-based approach will present you with a more pliable (and forgiving) environment to do what you want with the UI. (This is not as straight-forward as one may think.)
Below is the code that works as a system-level alert. Here is a screen shot.
OverlayShowingService
chatHead.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
final AlertDialog alertDialog = new AlertDialog.Builder(arg0.getContext(),
R.style.Theme_AppCompat_Dialog_Alert).create();
LayoutInflater layoutInflater = (LayoutInflater) getBaseContext()
.getSystemService(LAYOUT_INFLATER_SERVICE);
final View popupView = layoutInflater.inflate(R.layout.overlay, null);
alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
alertDialog.setView(popupView);
Button btnDismiss = (Button) popupView.findViewById(R.id.dismiss);
Button endService = (Button) popupView.findViewById(R.id.endService);
endService.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
alertDialog.dismiss();
stopSelf();
Toast.makeText(getApplicationContext(), "Service Terminated", Toast.LENGTH_LONG).show();
}
});
btnDismiss.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
Toast.makeText(getApplicationContext(), "Popup Terminated", Toast.LENGTH_LONG).show();
alertDialog.dismiss();
}
});
alertDialog.show();
}
});
As I stated in my first answer, you are having this issue with API 22 and later. Your code works OK for API 21 and earlier.
You are running afoul of changes made to PopupWindow in API level 22. See this documentation.
Fix issue #17789629: PopupWindow overlaps with navigation bar.
The Lollipop release introduced a feature that allowed
apps to extend under the navigation bar. This also means
any popup window that is anchored to the bottom of its
parent window will overlap with the navigation bar if the
parent window is extending underneath the navigation bar.
This change introduces a new window flag
(FLAG_LAYOUT_ATTACHED_IN_DECOR) that allows the app to
specify if the popup window should be attached to the decor
frame of the parent window thereby avoiding an overlap
with the screen decorations.
By default the flag is set on SDK version LOLLIPOP_MR1 or
greater and cleared on lesser SDK versions.
You can turn off this flag with the setAttachedInDecor method of PopupWindow.
Add the following code to OverlayShowingService.java after popupWindow.update() in the OnClickListener and you should be good to go.
// Turn off this functionality introduced in API 22.
// See documentation for FLAG_LAYOUT_ATTACHED_IN_DECOR in
// WindowManager.LayoutParams
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
popupWindow.setAttachedInDecor(false);
}

How to add more views, buttons to activity

I have a problem. I make a class DrawingView with button etc. and on activity i call it
public class PaintActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DrawingView view=new DrawingView(this);
setContentView(view);
addContentView(view.btnEraseAll, view.params);
}
and here is my configuration
class DrawingView extends View {
private Paint brush = new Paint();
private Path path = new Path();
public Button btnEraseAll, btnAccept, btnBack;
public ViewGroup.LayoutParams params;
public DrawingView(Context context) {
super(context);
brush.setAntiAlias(true);
brush.setColor(Color.BLACK);
brush.setStyle(Paint.Style.STROKE);
brush.setStrokeJoin(Paint.Join.ROUND);
brush.setStrokeWidth(22f);
btnEraseAll = new Button(context);
btnEraseAll.setText("Clear");
btnAccept = new Button(context);
btnAccept.setText("Accept");
btnBack = new Button(context);
btnBack.setText("Back");
params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
btnEraseAll.setLayoutParams(params);
btnAccept.setLayoutParams(params);
btnBack.setLayoutParams(params);
btnEraseAll.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
path.reset();
postInvalidate();
}
});
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawPath(path, brush);
}
public boolean onTouchEvent(MotionEvent event) {
float pointX = event.getX();
float pointY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
path.moveTo(pointX, pointY);
return true;
case MotionEvent.ACTION_MOVE:
path.lineTo(pointX, pointY);
break;
default:
return false;
}
postInvalidate();
return false;
}
}
but how i can add more buttons(i have 3) to activity main?
here i add button
addContentView(view.btnEraseAll, view.params);
But i want add this buttons too
btnAccept, btnBack;
can anyone help me? I want to add 3 buttons in view.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="#drawable/monitor"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/MyCustomActionBar">
<activity
android:name=".MainActivity"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".WiFiServiceDiscoveryActivity" />
<activity android:name=".PaintActivity" />
</application>
</manifest>
I refactored some of your code to make it easier to undertand.
I also extracted the buttons in .xml instead of creating them programmatically because it is much easier. I also extracted the DrawingView to a separate class. I also tested it so it works for sure.
public class PaintActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_paint);
final DrawingView drawingView = (DrawingView) findViewById(R.id.drawing_canvas);
View clearBtn = findViewById(R.id.btn_clear);
clearBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
drawingView.reset();
}
});
}
}
class DrawingView extends View {
private Paint brush = new Paint();
private Path path = new Path();
public DrawingView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
brush.setAntiAlias(true);
brush.setColor(Color.BLACK);
brush.setStyle(Paint.Style.STROKE);
brush.setStrokeJoin(Paint.Join.ROUND);
brush.setStrokeWidth(22f);
}
public void reset() {
path.reset();
postInvalidate();
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawPath(path, brush);
}
public boolean onTouchEvent(MotionEvent event) {
float pointX = event.getX();
float pointY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
path.moveTo(pointX, pointY);
return true;
case MotionEvent.ACTION_MOVE:
path.lineTo(pointX, pointY);
break;
default:
return false;
}
postInvalidate();
return false;
}
}
activity_paint.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent">
<com.example.myapplication.DrawingView
android:id="#+id/drawing_canvas"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<Button
android:id="#+id/btn_clear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:text="Clear"/>
<Button
android:id="#+id/btn_accept"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:text="Accept"/>
<Button
android:id="#+id/btn_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:text="Back"/>
</RelativeLayout>
ids.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="btn_clear" type="id"/>
<item name="btn_accept" type="id"/>
<item name="btn_back" type="id"/>
</resources>
You can also download the entire project from here: http://expirebox.com/download/130bc35765d0d4704c0e105627077281.html

PopUpWindow not showing Webview when start from service

I am trying to display a webview inside popupwindow which is being displayed by a service. When a user
touch on an image displayed by a service then a popupwindow should appear displaying a webview in it.
The code for the whole process is given below:
ChatHeadService.java
public class ChatHeadService extends Service {
private WindowManager windowManager;
float screenWidth=0, screenHeight=0;
private ImageView chatHead;
WindowManager.LayoutParams params;
WebView popUpWebView;
private static final int MAX_CLICK_DURATION = 200;
private long startClickTime;
private GestureDetector gestureDetector;
#Override public IBinder onBind(Intent intent) {
// Not used
return null;
}
#Override public void onCreate() {
super.onCreate();
screenWidth= getResources().getDisplayMetrics().widthPixels;
screenHeight= getResources().getDisplayMetrics().heightPixels;
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP | Gravity.LEFT;
params.x = 0;
params.y = 0;
chatHead = new ImageView(this);
chatHead.setImageResource(R.drawable.ic_launcher);
windowManager.addView(chatHead, params);
addChatHeadListener();
}
public void addChatHeadListener(){
chatHead.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
showPopUpWindow();
}
});
}
public void showPopUpWindow(){
LayoutInflater layoutInflater = (LayoutInflater)getBaseContext()
.getSystemService(LAYOUT_INFLATER_SERVICE);
View popupView = layoutInflater.inflate(R.layout.popupwindow, null);
final PopupWindow popupWindow = new PopupWindow(popupView,
(int)screenWidth,
(int)screenHeight);
popupWindow.setFocusable(true);
popupWindow.setBackgroundDrawable (new BitmapDrawable());
popUpWebView = (WebView) popupView.findViewById(R.id.idWebView1);
popUpWebView.getSettings().setJavaScriptEnabled(true);
popUpWebView.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});
popupWindow.showAsDropDown(chatHead, 0, 0);
popUpWebView.loadUrl("http://wwww.google.co.in");
}
}
And here is my xml file
popupwindow.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#ffffff" >
<WebView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ffffff"
android:id="#+id/idWebView1"/>
</LinearLayout>
Problem is nothing displayed when i clicked on the icon but when i use textview instead of webview
it diplayed textview successfully.

how can i make menubar on top of all activity (like GameCIH)

im new in android.
here is the deal. i want make my activity be like GameCih menubar (like on top of all activity and i can go around apps and do whatever i want and menubar still on top)
but what i want to do is not exactly same with GameCIH . i want music player so i can play songs and show album art and moving player menu around of screen by touch.
here is my main activity :
public class MainActivity extends Activity implements OnTouchListener{
RelativeLayout rel;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
rel = (RelativeLayout) findViewById(R.id.myactivity);
rel.setOnTouchListener(this);
this.setFinishOnTouchOutside(false);
this.getWindow().setBackgroundDrawable(new ColorDrawable(0));
Window dialogWindow = this.getWindow();
// Make the dialog possible to be outside touch
dialogWindow.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
dialogWindow.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
Button btn =(Button)findViewById(R.id.button1);
btn.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
finish();
}
});
Thread th = new Thread(){
public void run (){
try {
while(true){
Thread.sleep(10000);
try{
Intent i=new Intent(getApplicationContext(),MainActivity.class);
//i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(i);
}catch(Exception ex){
Log.d("X",ex.getMessage());
}
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
th.start();
}
#Override
public void onBackPressed() {
// Do Here what ever you want do on back press;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onTouch(View arg0, MotionEvent arg1) {
// TODO Auto-generated method stub
if(rel==arg0){
switch(arg1.getAction())
{
case MotionEvent.ACTION_MOVE:
{
WindowManager.LayoutParams layoutParams = this.getWindow().getAttributes();
layoutParams.gravity = Gravity.TOP | Gravity.LEFT;
layoutParams.x = ((int) arg1.getRawX()-400);
layoutParams.y = ((int) arg1.getRawY()-200);
this.getWindow().setAttributes(layoutParams);
return true;
}
case MotionEvent.ACTION_UP:
{
WindowManager.LayoutParams layoutParams = this.getWindow().getAttributes();
layoutParams.gravity = Gravity.TOP | Gravity.LEFT;
layoutParams.x = ((int) arg1.getRawX()-400);
layoutParams.y = ((int) arg1.getRawY()-200);
this.getWindow().setAttributes(layoutParams);
return true;
}
case MotionEvent.ACTION_DOWN:
{
WindowManager.LayoutParams layoutParams = this.getWindow().getAttributes();
layoutParams.gravity = Gravity.TOP | Gravity.LEFT;
layoutParams.x = ((int) arg1.getRawX()-400);
layoutParams.y = ((int) arg1.getRawY()-200);
this.getWindow().setAttributes(layoutParams);
return true;
}
}
}
return false;
}
}
and xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/myactivity"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_world" />
<Button
android:id="#+id/button1"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="#+id/textView1"
android:text="End" />
<EditText
android:id="#+id/editText1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/button1"
android:layout_alignBottom="#+id/button1"
android:layout_alignLeft="#+id/textView1"
android:ems="10" >
<requestFocus />
</EditText>
</RelativeLayout>
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.dialogtest"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.dialogtest.MainActivity"
android:label="#string/app_name"
android:theme="#android:style/Theme.Holo.Dialog">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
gamecih
http://i.stack.imgur.com/RgivT.jpg
my app
http://i.stack.imgur.com/VvPcP.jpg
my problem is:
1 i cant get activitiy on top
2 can touch outside but in some application whene i touch nothing will happen
3 i used startActivity(i); to get activity on forground but it will restart and same issue in 2
your help is highly appreciated

Android: Overlay button onClick is never getting called

I have created an application that runs a service. The service basically has an Overlay button and the button on click does something. However, everytime, I click on the button, the application in the background of the button is responding. Please can someone help?
I have referred to link.
Here is my code:
Service code:
public class HUD extends Service implements OnTouchListener{
Button mButton;
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
String s;
s = "Hari";
return null;
}
#Override
public void onCreate() {
super.onCreate();
//mView = new HUDView(this);
mButton = new Button(this);
mButton.setText("Overlay button");
mButton.setOnTouchListener(this);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.RIGHT | Gravity.TOP;
params.setTitle("Load Average");
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.addView(mButton, params);
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(getBaseContext(),"onDestroy", Toast.LENGTH_LONG).show();
if(mButton != null)
{
((WindowManager) getSystemService(WINDOW_SERVICE)).removeView(mButton);
mButton = null;
}
}
#Override
public boolean onTouch(View v, MotionEvent event) {
Toast.makeText(this,"Overlay button event", Toast.LENGTH_SHORT).show();
return false;
}
}
The manifest has the following permission as well:
I tried changing the types to
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
Now, wherever I click, the touch event is getting called. Please can someone help me?
The problem is you are using WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY. I think since some Android 4.x it is not usable anymore. This is the way i realized an overlay Button:
public class OverlayButton extends Service implements OnTouchListener {
Button mButton;
WindowManager wm;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
mButton = new Button(this);
mButton.setText("Overlay button");
mButton.setTextColor(Color.BLACK);
mButton.setOnTouchListener(this);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(150,
150, WindowManager.LayoutParams.TYPE_PHONE, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, PixelFormat.TRANSLUCENT);
params.gravity = Gravity.LEFT | Gravity.CENTER;
wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.addView(mButton, params);
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(getBaseContext(), "onDestroy", Toast.LENGTH_LONG).show();
if (mButton != null) {
((WindowManager) getSystemService(WINDOW_SERVICE)).removeView(mButton);
mButton = null;
}
}
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
Log.d("OverlayButton onTouch", "touched the button");
stopSelf();
}
return true;
}
}
What i did is, i also gave him the ability to disappear again, if i touch him.
This is the way i let him appear:
getActivity().startService(new Intent(getActivity().getBaseContext(), OverlayButton.class));
but, if you start it from your Activity, just use:
startService(new Intent(this, OverlayButton.class));
And don't forget to set these in your manifest:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
And inside the tags also don't forget:
<service android:name="OverlayButton" ></service>
When you use this WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH flag, it is telling the app to watch for all touches outside of your view.
Try using WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL instead. This will intercept touches only on your view.
To confirm, you need to be using WindowManager.LayoutParams.TYPE_SYSTEM_ALERT to make the view clickable.

Categories

Resources