How to make a Facebook Messenger-like notification like this in Android - android

I want to implement notifications like the one in the following image.
Notification appears any time. I think it's of course a background service waiting for new messages from the server then shows this. What I think this is an activity implemented as dialog with this custom UI. Am I correct? And is it a normal startActivity method from the service? And how do I do the transition animation to make it appears slowly from left to right with zooming when show up?

Check out this link http://www.piwai.info/chatheads-basics. He provides information about how to add them on your screen.
The trick is to add a View to the WindowManager like following code
private WindowManager windowManager;
private ImageView chatHead;
public void addView()
{
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
chatHead = new ImageView(this);
chatHead.setImageResource(R.drawable.android_head);
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);
}
Don't forget to add the permission <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

Related

Cant set webview as top with windowmanager - application get killed

protected void onCreate(Bundle savedInstanceState) {
AuthSingleton.getInstance().log("MainActivity: onCreate");
getApplication().registerActivityLifecycleCallbacks(myActivityLifecycleCallbacks);
AuthSingleton.getInstance().log("MainActivity: super.onCreate");
super.onCreate(savedInstanceState);
webView.setWebViewClient(new MyWebViewClient());
webView.setBackgroundColor(getResources().getColor(R.color.webViewBackground));
webView.loadUrl("file:///android_asset/csa_unavailable.html");
WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
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);
windowManager.addView(webView,params);
setContentView(R.layout.activity_main);
}
i cant get this code working in my mainactivity.
i have a working application and its mianactivity calls to webview and application continue to work in webview.
Now i want to make login screen as the topmost using windowmanager.
please help me with you have any sample code.
i want to do this minimum change to system.
Add These Lines before addin view
params.gravity = Gravity.TOP; //Initially view will be added to top
params.x = 0;
params.y = 0;

Bringing a view to the absolute front (even over alert dialogs)

I need one view to always be at the forefront, even over alert dialogs. I figured there might be two ways to achieve this:
Somehow create the alert dialog as part of an existing view, instead of being its own activity
Some sort of flag on the view to bring it to the front of everything including alert dialogs
Is this possible? If so how?
WindowManager with LayoutParams and Flag as TYPE_SYSTEM_ERROR. Shows over lockscreens too.
WindowManager windowManager = (WindowManager)getSystemService(WINDOW_SERVICE);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP | Gravity.LEFT;
params.x = 100; // position on screen (optional)
params.y = 100;
Add Views:
windowManager.addView(yourView, params);
Edit:
To avoid covering LockScreens: remove TYPE_SYSTEM_ERROR flag and add following:
WindowManager.LayoutParams.TYPE_PHONE
For this to work, you will need to add the following permission to your AndroidManifest.xml too:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
You don't need to request it at Runtime on most of devices except Android Marshmallow 6.0.0. There is a special way to request it than regular requests. It is checked using:
if (Settings.canDrawOverlays()) {
// you have permission
} else {
// send an intent with action "ACTION_MANAGE_OVERLAY_PERMISSION"
}

Android overlapping views when using WindowManager

I'm using WindowManager to add views to the users screen using an IntentService, as shown here:
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.BOTTOM | Gravity.CENTER;
params.x = 0;
params.y = 100;
windowManager.addView(cardView, params);
When I first launch the IntentService, the view is created as expected. However, when I re-launch the IntentService, a new view is added but the previous view remains.
How can I remove all the views that I have already added before adding a new view? I know that if I kill the IntentService then the views disappear, but how do I delete all other instances of my IntentService except the instance that I have just launched?
This is what it looks like when I first call the IntentService:
By the time the IntentService has been called multiple times, a shadow appears because there are so many view stacked on top of each other:
When the service ends, you need to remove your previous views in the onDestroy() function.
if(cardview!=null){
WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
windowManager.removeView(mView);
}

How to add an activity to WindowManager

I am writing an android library that needs to display an activity on top of the client app. After some reading up it seems that adding a new window is what I want to do so I added in this permission.
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
I then try to add an image view by doing this
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.BOTTOM | Gravity.LEFT;
params.x = 10;
params.y = 100;
ImageView imageview = new ImageView(this);
imageview.setImageResource(R.drawable.avatar);
windowManager.addView( imageview , params);
But what I want is to have my own activity on this new window on top of the client apps window. is this even possible? How would I do this?
Ok the correct approach to this appears to be to inflate the layout with in the service class and add it to the windowmanager that way. Then create a regular java class that can be used as the event listeners for the actions within that layout. I didnt need to use fragments or activities.
mRootLayout = (LinearLayout) LayoutInflater.from(context).
inflate(R.layout.myContainerXML, null);
MyListManager myListManager = new MyListManager(mRootLayout,context);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
PixelFormat.TRANSLUCENT);
ListView listView = (ListView) mRootLayout.findViewById(R.id.listView);
final MyListAdapter adapter = new MyListAdapter(activity,R.layout.list_row,(ArrayList)myListManager.getList());
listView.setAdapter(adapter);
windowManager.addView(mRootLayout, params);
If anyone has a better way I would love to hear it thanks

Switching between TYPE_SYSTEM_ALERT AND TYPE_SYSTEM_OVERLAY , and capturing the touch events not working properly

I made a View in service which runs always on top of every application in android.
Initially, the behaviour of service is TYPE_SYSTEM_ALERT .
WindowManager.LayoutParams layparams = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSLUCENT);
layparams .gravity = Gravity.CENTER_VERTICAL| Gravity.CENTER_HORIZONTAL;
wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.addView(serviceView, layparams );
I am changing the behaviour of service at run time means switching between TYPE_SYSTEM_ALERT AND TYPE_SYSTEM_OVERLAY on touch. Switch take place when I touch outside the view parameters and when touch inside the view parameters.
layparams .type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
Using updateViewLayout(serviceView, layparams )
PROBLEM: Is when I touch outside of view , the first touch just activate TYPE_SYSTEM_OVERLAY and after then outside app works fine. When TYPE_SYSTEM_OVERLAY is working , after that when you touch within the view it will trigger the action of object behind the view not the action of the view. But when u once touch the view TYPE_SYSTEM_ALERT will be applied and now the View will behave normally .
Current Implementation : I have to touch twice to work that particular thing when switch take place between layout parameters.
use this one... works perfectly on ICS and above
params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;//This one is necessary.
params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH |
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
params.gravity = Gravity.TOP | Gravity.RIGHT;
params.x = 0;
params.y = -params.height;
windowManager.addView(tile, params);
you can do this by calling updateViewLayout() on instance of WindowManager class.
wm = (WindowManager) getSystemService(WINDOW_SERVICE);
// create new layout params
WindowManager.LayoutParams newlayparams = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSLUCENT);
//update new layout
wm.updateViewLayout(serviceView, newlayparams);
Hope it help!

Categories

Resources