user5340656
user5340656

Reputation:

ChatHead Service is Not Working in Lollipop and Marshmallow on Nexus devices

I am Working on a service which will draw a overlay icon on some predefined applications e.g. WhatsApp, FB Messenger, Instagram etc. we set their packages predefined so that our service can detect.

*Its Working Totally Fine on till 19API (Before and Equal to Kitkat Api level)

But its not working on Lollipop and Marshmallow we are testing on Nexus 5,6,5x,6p and Hawaii Devices P8.

in these devices we got error E/Surface: getSlotFromBufferLocked: unknown buffer: 0x9db36030

Don't Know what does it mean and what the issue behind. Please Help me Here is my Service Code below

public class ChatHeadService extends Service implements OnClickListener {

private WindowManager windowManager;
private ImageView chatHead;
private LayoutParams params;
private Context context;
private BroadcastReceiver mReceiver;
private OnTouchListener mOnTouchlistener;
private Runnable handleIconVisibility;
private Handler mHandler;
private boolean mIsIconAttached;
public final String TAG = "CRAR";
private String mIm;

public ChatHeadService() {

    handleIconVisibility = new Runnable() {

        @Override
        public void run() {
            if (getResumedStatus()) {
                addTopIcon();
            } else {
                removeTopIcon();
            }
            mHandler.postDelayed(handleIconVisibility, 500L);
        }
    };
    mReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(
                    "android.intent.action.SCREEN_OFF")) {
                stopTick();
            } else if (intent.getAction().equals(
                    "android.intent.action.SCREEN_ON")) {
                startTick();
            }
        }
    };

    mOnTouchlistener = new OnTouchListener() {
        private int initialX;
        private int initialY;
        private float initialTouchX;
        private float initialTouchY;

        @SuppressLint("ClickableViewAccessibility")
        @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();
            // case MotionEvent.ACTION_UP:
            // case MotionEvent.ACTION_MOVE:
            // params.x = initialX
            // + (int) (event.getRawX() - initialTouchX);
            // params.y = initialY
            // + (int) (event.getRawY() - initialTouchY);
            // windowManager.updateViewLayout(chatHead, params);
            // }
            Intent intent = new Intent(context, HomeActivity.class);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.putExtra("im_name", mIm);
            context.startActivity(intent);
            return true;

        }
    };
}

private String[] getActivePackages() {
    ActivityManager am = (ActivityManager) context
            .getSystemService(Context.ACTIVITY_SERVICE);
    final Set<String> activePackages = new HashSet<String>();
    final List<ActivityManager.RunningAppProcessInfo> processInfos = am
            .getRunningAppProcesses();
    for (ActivityManager.RunningAppProcessInfo processInfo : processInfos) {
        if (processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
            activePackages.addAll(Arrays.asList(processInfo.pkgList));
        }
    }
    return activePackages.toArray(new String[activePackages.size()]);
}

private boolean isImResumedForLollipop() {
    String[] activePackages = getActivePackages();
    if (activePackages != null) {
        for (String activePackage : activePackages) {
            // WhatsApp
            if (activePackage.equals("com.whatsapp")
                    || activePackage.equals("com.whatsapp.HomeActivity")
                    || activePackage.equals("com.whatsapp.Conversation")) {
                mIm = activePackage;
                return true;
            }
            // Viber
            if (activePackage.equals("com.viber.voip")) {
                mIm = activePackage;
                return true;
            }
            // WeChat
            if (activePackage.equals("com.tencent.mm")) {
                mIm = activePackage;
                return true;
            }

            // Facebook Massenger
            if (activePackage
                    .equals("com.facebook.orca.auth.StartScreenActivity")
                    || activePackage
                            .equals("com.facebook.orca.creation.CreateThreadActivity")
                    || activePackage
                            .equals("com.facebook.messenger.neue.MainActivity")
                    || activePackage
                            .equals("com.facebook.orca.threadview.ThreadViewActivity")) {
                mIm = activePackage;
                return true;
            }

            // Tango
            if (activePackage.equals("com.sgiggle.production")) {
                mIm = activePackage;
                return true;
            }

            // MMS
            if (activePackage.equalsIgnoreCase("com.android.mms")) {
                mIm = activePackage;
                return true;
            }

            // Textra
            if (activePackage.equals("com.textra")) {
                mIm = activePackage;
                return true;
            }

            // Hangout
            if (activePackage.equals("com.google.android.talk")) {
                mIm = activePackage;
                return true;
            }

            // Line
            if (activePackage.equals("jp.naver.line.android")) {
                mIm = activePackage;
                return true;
            }

            // IMO
            if (activePackage.equals("com.imo.android.imoim")) {
                mIm = activePackage;
                return true;
            }

            // SKYPE
            if (activePackage.equals("com.skype.raider")) {
                mIm = activePackage;
                return true;
            }

            // KIK
            if (activePackage.equals("kik.android")) {
                mIm = activePackage;
                return true;
            }

            // Google Messenger
            if (activePackage.equals("com.google.android.apps.messaging")) {
                mIm = activePackage;
                return true;
            }

            // Instagram
            if (activePackage.equals("com.instagram.android")
                    || activePackage.equals("com.instagram.selfupdate")
                    || activePackage
                            .equals("com.instagram.android.activity.MainTabActivity")) {
                mIm = activePackage;
                return true;
            }

            // YAHOO Messenger
            if (activePackage.equals("com.yahoo.mobile.client.android.im")) {
                mIm = activePackage;
                return true;
            }

            // HIKE
            if (activePackage.equals("com.bsb.hike")) {
                mIm = activePackage;
                return true;
            }

            // BBM
            if (activePackage.equals("com.bbm")) {
                mIm = activePackage;
                return true;
            }

            // ICQ
            if (activePackage.equals("com.icq.mobile.client")) {
                mIm = activePackage;
                return true;
            }

            // Nimbuzz
            if (activePackage.equals("com.nimbuzz")) {
                mIm = activePackage;
                return true;
            }
            // Twitter
            if (activePackage.equals("com.twitter.android")
                    || activePackage
                            .equals("com.twitter.android.DMActivity")) {
                mIm = activePackage;
                return true;
            }
        }
    }

    return false;
}

private boolean getResumedStatus() {
    if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT_WATCH) {
        return isImResumedForLollipop();
    } else {
        return isImResumed();
    }
}

@SuppressWarnings("deprecation")
private boolean isImResumed() {
    try {
        ActivityManager am = (ActivityManager) context
                .getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningTaskInfo> alltasks = am
                .getRunningTasks(1);
        for (ActivityManager.RunningTaskInfo aTask : alltasks) {
            Log.d("TAG", aTask.topActivity.getClassName());
            Log.d("TAG", aTask.topActivity.getPackageName());
            String className = aTask.topActivity.getClassName();
            // WhatsApp
            if (className.equals("com.whatsapp.Conversation")
                    || className.equals("com.whatsapp")) {
                mIm = aTask.topActivity.getPackageName();
                return true;
            }
            // Viber
            if (className
                    .equals("com.viber.voip.messages.ui.ConversationActivity")) {
                mIm = aTask.topActivity.getPackageName();
                return true;
            }
            // WeChat
            if (className.equals("com.tencent.mm.ui.LauncherUI")) {
                mIm = aTask.topActivity.getPackageName();
                return true;
            }

            // Facebook Massenger
            if (className
                    .equals("com.facebook.orca.auth.StartScreenActivity")
                    || className
                            .equals("com.facebook.orca.creation.CreateThreadActivity")
                    || className
                            .equals("com.facebook.messenger.neue.MainActivity")
                    || className
                            .equals("com.facebook.orca.threadview.ThreadViewActivity")) {
                mIm = aTask.topActivity.getPackageName();
                return true;
            }

            // Tango
            if (className
                    .equals("com.sgiggle.app.screens.tc.ConversationDetailActivitySWIG")) {
                mIm = aTask.topActivity.getPackageName();
                return true;
            }

            // MMS
            if (aTask.topActivity.getPackageName().equalsIgnoreCase(
                    "com.android.mms")) {
                mIm = aTask.topActivity.getPackageName();
                return true;
            }

            // Textra
            if (className.equals("com.mplus.lib.ui.main.Main")
                    || className
                            .equals("com.mplus.lib.ui.convo.ConvoActivity")) {
                mIm = aTask.topActivity.getPackageName();
                return true;
            }

            // Hangout
            if (className
                    .equals("com.google.android.apps.hangouts.phone.ConversationActivity")) {
                mIm = aTask.topActivity.getPackageName();
                return true;
            }

            // Line
            if (className
                    .equals("jp.naver.line.android.activity.chathistory.ChatHistoryActivity")) {
                mIm = aTask.topActivity.getPackageName();
                return true;
            }

            // IMO
            if (className
                    .equals("com.imo.android.imoim.activities.IMActivity")) {
                mIm = aTask.topActivity.getPackageName();
                return true;
            }

            // SKYPE
            if (className.equals("com.skype.android.app.chat.ChatActivity")) {
                mIm = aTask.topActivity.getPackageName();
                return true;
            }

            // KIK
            if (className.equals("kik.android.chat.activity.ChatActivity")) {
                mIm = aTask.topActivity.getPackageName();
                return true;
            }

            // Google Messenger
            if (className
                    .equals("com.google.android.apps.messaging.ui.ConversationListActivity")) {
                mIm = aTask.topActivity.getPackageName();
                return true;
            }

            // Instagram
            if (className
                    .equals("com.instagram.android.activity.MainTabActivity")) {
                mIm = aTask.topActivity.getPackageName();
                return true;
            }

            // YAHOO Messenger
            if (className
                    .equals("com.yahoo.mobile.client.android.im.ConversationActivity")) {
                mIm = aTask.topActivity.getPackageName();
                return true;
            }

            // HIKE
            if (className
                    .equals("com.bsb.hike.chatthread.ChatThreadActivity")) {
                mIm = aTask.topActivity.getPackageName();
                return true;
            }

            // BBM
            if (className.equals("com.bbm.ui.activities.MainActivity")) {
                mIm = aTask.topActivity.getPackageName();
                return true;
            }

            // ICQ
            if (className
                    .equals("ru.mail.instantmessanger.flat.chat.IcqFlatChatActivity")) {
                mIm = aTask.topActivity.getPackageName();
                return true;
            }

            // Nimbuzz
            if (className.equals("com.nimbuzz.ChatView")) {
                mIm = aTask.topActivity.getPackageName();
                return true;
            }
            // Twitter
            if (className.equals("com.twitter.android")
                    || className.equals("com.twitter.android.DMActivity")) {
                mIm = aTask.topActivity.getPackageName();
                return true;
            }

        }
    } catch (Throwable t) {
        Log.i(TAG, "Throwable caught: " + t.getMessage(), t);
    }
    return false;
}

private void addTopIcon() {
    if (mIsIconAttached) {
        return;
    } else {
        drawIconView();
        mIsIconAttached = true;
        return;
    }
}

@SuppressLint("RtlHardcoded")
private void drawIconView() {
    params = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
            ViewGroup.LayoutParams.WRAP_CONTENT, LayoutParams.TYPE_PHONE,
            LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT);

    if (mIm.equalsIgnoreCase("com.twitter.android")
            || mIm.equals("com.twitter.android.composer.ComposerActivity")) {
        params.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
        params.y = 10;
        params.x = -160;
    } else {
        params.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
        params.y = 10;
    }

    windowManager.addView(chatHead, params);
}

@SuppressLint("RtlHardcoded")
private void reDrawIconView() {
    int i = getResources().getConfiguration().orientation;
    Log.d("TAG", "" + i);
    params = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
            ViewGroup.LayoutParams.WRAP_CONTENT, LayoutParams.TYPE_PHONE,
            LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT);
    params.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
    params.y = 10;
    windowManager.updateViewLayout(chatHead, params);
}

private void removeTopIcon() {
    if (!mIsIconAttached) {
        return;
    } else {
        removeIconView();
        mIsIconAttached = false;
        return;
    }
}

private void removeIconView() {
    if (windowManager != null && chatHead != null) {
        windowManager.removeViewImmediate(chatHead);
        return;
    }
}

private void stopTick() {
    if (mHandler != null) {
        mHandler.removeCallbacks(handleIconVisibility);
        return;
    } else {
        Log.d("TAG", "mHandler is null");
        return;
    }
}

private void startTick() {
    if (mHandler != null) {
        mHandler.removeCallbacks(handleIconVisibility);
        mHandler.postDelayed(handleIconVisibility, 1000L);
        return;
    } else {
        Log.d("TAG", "mHandler is null");
        return;
    }
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    if (mIsIconAttached) {
        reDrawIconView();
    }
    super.onConfigurationChanged(newConfig);
}

private void init() {
    chatHead = new ImageView(context);
    chatHead.setImageResource(R.drawable.chat_head);
    chatHead.setOnTouchListener(mOnTouchlistener);
    Log.e("Chat head", "On touch listner triggered");
    chatHead.setOnClickListener(this);
    Log.e("Chat head", "click listner triggered");

    mHandler = new Handler();
}

private void registerIntentReceiver() {
    IntentFilter intentfilter = new IntentFilter();
    intentfilter.addAction("android.intent.action.SCREEN_ON");
    intentfilter.addAction("android.intent.action.SCREEN_OFF");
    registerReceiver(mReceiver, intentfilter);
}

private void unregisterIntentReceiver() {
    unregisterReceiver(mReceiver);
}

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

@Override
public void onCreate() {
    windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
    context = this;
    registerIntentReceiver();
    init();
    super.onCreate();
}

@Override
public void onDestroy() {
    stopTick();
    unregisterIntentReceiver();
    mHandler = null;
    super.onDestroy();
}

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

@Override
public void onClick(View v) {

    Log.e("Chat head", "on clickview function triggerd complete");

}

}

Any Help would be great...

Upvotes: 3

Views: 692

Answers (1)

MBH
MBH

Reputation: 16609

For Lollipop:

it works for me. But You have to add this permission in your mainfest.

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

Anyway you can check if you got the permission before drowing:

if (Settings.canDrawOverlays(context)) {
    // Here you go, you can draw you chathead view
}

For Marshmallow

Since it needs an extra permission, It does not work directly. I tried to find the settings and send user there. I found that you can send the user from your app directly to the permission page in the settings with this intent .

ACTION_MANAGE_OVERLAY_PERMISSION

montioned on in the documentation of Settings.canDrawOverlays(context) page

this may be helpful for you:

Android System overlay window - StackOverflow

UPDATE: This is the documentation of canDrawOverlays:

Checks if the specified context can draw on top of other apps. As of API level 23, an app cannot draw on top of other apps unless it declares the SYSTEM_ALERT_WINDOW permission in its manifest, and the user specifically grants the app this capability. To prompt the user to grant this approval, the app must send an intent with the action ACTION_MANAGE_OVERLAY_PERMISSION, which causes the system to display a permission management screen.

Settings.canDrawOverlays(context) documentation

Hope this helps.

Upvotes: 0

Related Questions