Android ChatHead Tutorial

Step 1: Setup an Android Project

Android ChatHead requires “SYSTEM_ALERT_WINDOW” permission which is available since API level 1, so minimum API 7 is fine.

Just next, next next… and create a blank activity 🙂

Step 2: Add ChatHead Service

If you want to know more details about ChatHead service. Read this article by Pierre-Yves Ricau.
Create a ChatHead Class that extends Service.

public class ChatHeadService extends Service {

    private WindowManager windowManager;
    private List<View> chatHeads;
    private LayoutInflater inflater;

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

    @Override
    public void onCreate() {
        super.onCreate();
        windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        inflater = LayoutInflater.from(this);
        chatHeads = new ArrayList<View>();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        final View chatHead = inflater.inflate(R.layout.service_chat_head, null);

        TextView txt_title = (TextView) chatHead.findViewById(R.id.txt_title);
        TextView txt_text = (TextView) chatHead.findViewById(R.id.txt_text);

        txt_title.setText(intent.getStringExtra("title"));
        txt_text.setText(intent.getStringExtra("text"));

        chatHead.findViewById(R.id.btn_dismiss).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                windowManager.removeView(chatHead);
            }
        });

        final WindowManager.LayoutParams params = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_PHONE, 0, PixelFormat.TRANSLUCENT);

        params.gravity = Gravity.CENTER;

        chatHead.findViewById(R.id.txt_title).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:
                        initialX = params.x;
                        initialY = params.y;
                        initialTouchX = event.getRawX();
                        initialTouchY = event.getRawY();
                        return true;
                    case MotionEvent.ACTION_UP:
                        return true;
                    case MotionEvent.ACTION_MOVE:
                        params.x = initialX + (int) (event.getRawX() - initialTouchX);
                        params.y = initialY + (int) (event.getRawY() - initialTouchY);
                        windowManager.updateViewLayout(chatHead, params);
                        return true;
                }
                return false;
            }
        });

        addChatHead(chatHead, params);

        return super.onStartCommand(intent, flags, startId);
    }

    public void addChatHead(View chatHead, LayoutParams params) {
        chatHeads.add(chatHead);
        windowManager.addView(chatHead, params);
    }

    public void removeChatHead(View chatHead) {
        chatHeads.remove(chatHead);
        windowManager.removeView(chatHead);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        for (View chatHead : chatHeads) {
            removeChatHead(chatHead);
        }
    }
}

Create ChatHead layout file.

/res/layout/service_chat_head.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">

    <TextView
            android:id="@+id/txt_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#d0bb0000"
            android:padding="12dp"
            android:text="Medium Text"
            android:textColor="#d0ffffff"
            android:textSize="16sp"
            android:textStyle="bold"/>

    <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#d0ff0000"
            android:orientation="vertical">

        <View
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:background="#d0ffffff"/>

        <TextView
                android:id="@+id/txt_text"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="12dp"
                android:text="TextView"
                android:textColor="#d0ffffff"/>

        <Button
                android:id="@+id/btn_dismiss"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="6dp"
                android:text="Dismiss"
                android:textColor="#d0ffffff"
                android:textStyle="bold"/>
    </LinearLayout>

</LinearLayout>

Add ChatHeadService to AndroidManifest.xml

<service android:name=”com.gbinghan.androidchathead.ChatHeadService” ></service>

Add SYSTEM_ALERT_WINDOW to AndroidManifest.xml

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

Your AndroidManifest.xml should look like this.

Step 3: Add a button to launch the service 🙂

Add OnClickListener in Activity file java/com/gbinghan/androidchathead/MainActivity.java.

findViewById(R.id.button1).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, ChatHeadService.class);
intent.putExtra(“title”, “Hello”);
intent.putExtra(“text”, “ChatHead”);
startService(intent);
}
});

Add the button in layout file /res/layout/activity_main.xml.

    <Button
android:id=”@+id/button1″
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_alignLeft=”@+id/textView1″
android:layout_below=”@+id/textView1″
android:text=”Button”/>

Step 4: Run!

You should see this on your emulator/device.

Note:
If you use different package name, remember to replace all instance of “gbinghan”.

References:
http://www.piwai.info/chatheads-basics/
https://github.com/venator85/ChatHeads/blob/master/src/com/example/chatheads/MainActivity.java