Skip to main content

Simple Custom System Overlay Alert in Android

System Overlay Alert


Here is Custom Alert Layout

overlay.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="200dp"
    android:layout_margin="0dp"
      >

    <TextView
        android:id="@+id/textview_info"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal|top"
        android:text="info"
        android:textColor="#FFF"
        android:textAppearance="?android:attr/textAppearanceLarge" />

  <TextView
          android:id="@+id/textview_info2"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_alignBaseline="@+id/textview_info"
      android:layout_alignBottom="@+id/textview_info"
      android:layout_alignParentRight="true"
      android:gravity="center_horizontal|top"
      android:text="."
      android:textAppearance="?android:attr/textAppearanceLarge"
      android:textColor="#f70000" />



</RelativeLayout>



OverlayShowActivity .java

/**
* Activity Page for Calling Overlay Class
*/
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;

public class OverlayShowActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
startService(new Intent(this, OverlayService.class)); //Call the Overlay Service
finish();
}
}

OverlayHideActivity.java

/**
* Overlay Service Cancel
*/
import android.app.Activity;
mport android.os.Bundle;

public class OverlayHideActivity extends Activity {
        @Override
protected void onCreate(Bundle savedInstanceState) {
               super.onCreate(savedInstanceState);
OverlayService.stop(); //Stop the Overlay Service
finish();
}
 
}



AlertOverlayService .java

/**
*
*/
import android.app.Notification;
import android.app.PendingIntent;
import android.content.Intent;

public class AlertOverlayService extends OverlayService {

public static OverlayService instance; //create instances
        private OverlayView overlayView;

@Override
public void onCreate() {
super.onCreate();
instance = this;
overlayView = new OverlayView(this); //Call OverlayView Page
}

@Override
public void onDestroy() {
super.onDestroy();
if (overlayView != null) {
overlayView.destory();
}

}

static public void stop() {
if (instance != null) {
instance.stopSelf();
}
}

@Override
protected Notification foregroundNotification(int notificationId) { //Notification for Overlay Service
Notification notification;

notification = new Notification(R.drawable.ic_launcher, getString(R.string.title_notification), System.currentTimeMillis());

notification.flags = notification.flags | Notification.FLAG_ONGOING_EVENT | Notification.FLAG_ONLY_ALERT_ONCE;

notification.setLatestEventInfo(this, getString(R.string.title_notification), getString(R.string.message_notification), notificationIntent());

return notification;
}


private PendingIntent notificationIntent() { //Cancel the Overlay service
Intent intent = new Intent(this, SampleOverlayHideActivity.class);

PendingIntent pending = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

return pending;
}

}


OverlayService .java

/*
*Service Class for System Alert Service
*/
import android.app.Notification;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;

public class OverlayService extends Service {

protected boolean foreground = false;
protected boolean cancelNotification = false;
protected int id = 0;

protected Notification foregroundNotification(int notificationId) {
return null;
}

public void moveToForeground(int id, boolean cancelNotification) {
moveToForeground(id, foregroundNotification(id), cancelNotification);
}

public void moveToForeground(int id, Notification notification, boolean cancelNotification) {
if (! this.foreground && notification != null) {
this.foreground = true;
this.id = id;
this.cancelNotification = cancelNotification;

super.startForeground(id, notification);
} else if (this.id != id && id > 0 && notification != null) {
this.id = id;
((NotificationManager) getSystemService(NOTIFICATION_SERVICE)).notify(id, notification);
}
}


public void moveToBackground(int id, boolean cancelNotification) {
foreground = false;
id = 0;
super.stopForeground(cancelNotification);
}

public void moveToBackground(int id) {
moveToBackground(id, cancelNotification);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}

@Override
public IBinder onBind(Intent intent) {
return null;
}

}



AlertOverlayView .java
/**
*View Class For Custom OverlayViews
*/

import android.annotation.SuppressLint;
import android.view.Gravity;
import android.view.MotionEvent;
import android.widget.TextView;

public class AlertOverlayView extends OverlayView {

private TextView info,info1;

public SampleOverlayView(OverlayService service) {
super(service, R.layout.overlay 1); //Calling the custom alert xml

}

@SuppressLint("Override")
public int getGravity() {
return Gravity.TOP + Gravity.RIGHT; //alert position
}

@Override
protected void onInflateView() { //view items
info = (TextView) this.findViewById(R.id.textview_info);
info1 = (TextView) this.findViewById(R.id.textview_info2);
}

@Override
protected void refreshViews() {
info.setText("Alert1");
info1.setText("Alert2");
}

@Override
protected void onTouchEvent_Up(MotionEvent event) {
}

@Override
protected void onTouchEvent_Move(MotionEvent event) {
}

@Override
protected void onTouchEvent_Press(MotionEvent event) {
}

@Override
public boolean onTouchEvent_LongPress() {
return true;
}
}


OverlayView .java

import android.content.Context;
import android.graphics.PixelFormat;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.RelativeLayout;

public abstract class OverlayView extends RelativeLayout {

protected WindowManager.LayoutParams layoutParams;

private int layoutResId;
private int notificationId = 0;

public OverlayView(OverlayService service, int layoutResId, int notificationId) {
super(service);

this.layoutResId = layoutResId;
this.notificationId = notificationId;

this.setLongClickable(true);

this.setOnLongClickListener(new View.OnLongClickListener() {

@Override
public boolean onLongClick(View v) {
return onTouchEvent_LongPress();
}
});

load();
}

public OverlayService getService() {
return (OverlayService) getContext();
}

public int getLayoutGravity() {
// Override this to set a custom Gravity for the view.

return Gravity.CENTER;
}

private void setupLayoutParams() {
layoutParams = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT);

layoutParams.gravity = getLayoutGravity();

onSetupLayoutParams();

}

protected void onSetupLayoutParams() {
// Override this to modify the initial LayoutParams. Be sure to call
// super.setupLayoutParams() first.
}

private void inflateView() {
// Inflates the layout resource, sets up the LayoutParams and adds the
// View to the WindowManager service.

LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);

inflater.inflate(layoutResId, this);

onInflateView();

}

protected void onInflateView() {
// Override this to make calls to findViewById() to setup references to
// the views that were inflated.
// This is called automatically when the object is created right after
// the resource is inflated.
}

public boolean isVisible() {
// Override this method to control when the Overlay is visible without
// destroying it.
return true;
}

public void refreshLayout() {
// Call this to force the updating of the view's layout.

if (isVisible()) {
removeAllViews();
inflateView();

onSetupLayoutParams();

((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)).updateViewLayout(this, layoutParams);

refresh();
}

}

protected void addView() {
setupLayoutParams();

((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)).addView(this, layoutParams);

super.setVisibility(View.GONE);
}

protected void load() {
inflateView();
addView();
refresh();
}

protected void unload() {
((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)).removeView(this);

removeAllViews();
}

protected void reload() {
unload();

load();
}

public void destory() {
((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)).removeView(this);
}

public void refresh() {
// Call this to update the contents of the Overlay.

if (!isVisible()) {
setVisibility(View.GONE);
} else {
setVisibility(View.VISIBLE);

refreshViews();
}
}

protected void refreshViews() {
// Override this method to refresh the views inside of the Overlay. Only
// called when Overlay is visible.
}

protected boolean showNotificationHidden() {
// Override this to configure the notification to remain even when the
// overlay is invisible.
return true;
}

protected boolean onVisibilityToChange(int visibility) {
// Catch changes to the Overlay's visibility in order to animate

return true;
}

protected View animationView() {
return this;
}

protected void hide() {
// Set visibility, but bypass onVisibilityToChange()
super.setVisibility(View.GONE);
}

protected void show() {
// Set visibility, but bypass onVisibilityToChange()

super.setVisibility(View.VISIBLE);
}

@Override
public void setVisibility(int visibility) {
if (visibility == View.VISIBLE) {
getService().moveToForeground(notificationId, !showNotificationHidden());
} else {
getService().moveToBackground(notificationId, !showNotificationHidden());
}

if (getVisibility() != visibility) {
if (onVisibilityToChange(visibility)) {
super.setVisibility(visibility);
}
}
}

protected int getLeftOnScreen() {
int[] location = new int[2];

getLocationOnScreen(location);

return location[0];
}

protected int getTopOnScreen() {
int[] location = new int[2];

getLocationOnScreen(location);

return location[1];
}

protected boolean isInside(View view, int x, int y) {
// Use this to test if the X, Y coordinates of the MotionEvent are
// inside of the View specified.

int[] location = new int[2];

view.getLocationOnScreen(location);

if (x >= location[0]) {
if (x <= location[0] + view.getWidth()) {
if (y >= location[1]) {
if (y <= location[1] + view.getHeight()) {
return true;
}
}
}
}

return false;
}

protected void onTouchEvent_Up(MotionEvent event) {

}

protected void onTouchEvent_Move(MotionEvent event) {

}

protected void onTouchEvent_Press(MotionEvent event) {

}

public boolean onTouchEvent_LongPress()
{
return false;
}

@Override
public boolean onTouchEvent(MotionEvent event) {

if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {

onTouchEvent_Press(event);

} else if (event.getActionMasked() == MotionEvent.ACTION_UP) {

onTouchEvent_Up(event);

} else if (event.getActionMasked() == MotionEvent.ACTION_MOVE) {

onTouchEvent_Move(event);

}

return super.onTouchEvent(event);

}

}


Manifest File

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="sample.ex.systemoverlay"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="8" />

    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:name="OverlayShowActivity"
            android:theme="@android:style/Theme.Dialog" >
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name="OverlayHideActivity"
            android:theme="@android:style/Theme.Dialog" >
        </activity>
     
        <service android:name="AlertOverlayService" >
        </service>
         
    </application>

</manifest>



Need Permission for System Alert window

    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />



Enjoy Coding ..!!

Comments

Popular posts from this blog

Bluetooth Chat Example

Manifest File <manifest xmlns:android="http://schemas.android.com/apk/res/android"       package="com.example.android.BluetoothChat"       android:versionCode="1"       android:versionName="1.0">     <uses-sdk minSdkVersion="7" />     <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />     <uses-permission android:name="android.permission.BLUETOOTH" />     <application android:label="@string/app_name"                  android:icon="@drawable/app_icon" >         <activity android:name=".BluetoothChat"                   android:label="@string/app_name"                   android:configChanges="orientation|keyboardHidden">             <intent-filter> ...

Custom TextView With Images in Android

Create a custom XML Tag with image and text 1) Class extends Textview import java . util . regex . Matcher ; import java . util . regex . Pattern ; import android . content . Context ; import android . text . Spannable ; import android . text . style . ImageSpan ; import android . util . AttributeSet ; import android . util . Log ; import android . widget . TextView ; public class TextViewWithImages extends TextView { public TextViewWithImages ( Context context , AttributeSet attrs , int defStyle ) { super ( context , attrs , defStyle ); } public TextViewWithImages ( Context context , AttributeSet attrs ) { super ( context , attrs ); } public TextViewWithImages ( Context context ) { super ( context ); } @Override public void setText ( CharSequence text , BufferType type ) { Spannable s = getTextWithImages ( getContext (), text ); super . setText...

AcceleroMeter Sensors with SurfaceMovements on Canvas

MainActivity.java import android.app.Activity; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.os.Bundle; import android.util.Log; import android.view.SurfaceHolder; import android.view.SurfaceView; public class MainActivity extends Activity implements SensorEventListener { float x, y, sensorX, sensorY; Bitmap ball; SensorManager sm; Sensor s; MyBringBackSurface ourSurfaceView; /**  * Canvas Movement  */ public class MyBringBackSurface extends SurfaceView implements Runnable {     SurfaceHolder ourHolder;     Thread ourThread = null;     boolean isRunning = false;     public MyBringBackSurface(Context context) {         super(context)...