Question

I am making an emoticon app like Emojidom https://play.google.com/store/apps/details?id=com.plantpurple.emojidom

When i try to access my app from WeChat, i cannot do that.. but i can see that emojidom app is accessible from WeChat. I have added all the necessary premissions in my app for picking up images but still it doesn't show up in wechat.. It shows up in whatsapp though. I want it like this.. see screenshot enter image description here

In the top of this chat window in wechat, we can see the emojidom icon, but i cant get mine to appear there... how to do so... any idea? I think i need to write a service to monitor when wechat comes in foreground. Any idea how to write such a service which monitors when a specific application comes to foreground?

Was it helpful?

Solution

First of all, i dont know if you are doing it this way, but what Emojidom does here is not including an icon in the action bar, instead, it draws itself on top of your apps, as a floating icon. A well known example of this, is the Facebook Messenger App, that draws icons for active chats floating in the screen. To achieve this, you can follow this tutorial: http://www.piwai.info/chatheads-basics/

Second, Emojidom only draws itself when a eligible app is in the foreground. We are lucky, since we have a method to detect what app is in the foreground.

for this, we create a method like this:

private RunningAppProcessInfo getForegroundApp() {
    RunningAppProcessInfo temp;

     ActivityManager   mActivityManager = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE);

    Iterator <RunningAppProcessInfo> i =  mActivityManager.getRunningAppProcesses().iterator();
    while(i.hasNext()){
        temp = i.next();
        if(temp.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND){
           return temp;
        }
    }
    return null;
}

If you check the RunningAppProcessInfo class, it is easy to know the name of the package, since you can easily check all the package names (for instannce in the play website) you can prepare a list of packages of the apps you want to consider, and put the list in a variable in your app.

Third. I dont know in wechat, but in whatsapp, the icon only is displayed when a chat is open (i.e. you cannot see it in the list of chats or configuration screens).

For this, you can check what activity is actually running in the active app, we can use this method, that will check if the package name of any of the running tasks, is the same of the foreground app, and returning the info

private ComponentName getRunningActivity(RunningAppProcessInfo target){

    ActivityManager.RunningTaskInfo info;


    ActivityManager    mActivityManager = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE);

    Iterator <ActivityManager.RunningTaskInfo> i =  mActivityManager.getRunningTasks(100).iterator();

    while(i.hasNext()){
        info=i.next();
        if(info.baseActivity.getPackageName().equals(target.processName)){
            return info.topActivity;

        }
    }

    return null;
}

Take a look at the ComponentName class to get the information you need.

To know what activity represents every screen of every app, you can try to find out on google, or make a simple app to list all the running task on your own mobile, and run all the apps that you want to check

OTHER TIPS

I can suggest a crazy root to take the program and DisAssembleit to learn how it does it. To get my help in doing that get in touch: limelect at gmail dot com

This code is check is your app on background. You can modify it for yor needs: https://stackoverflow.com/a/11787496/2521931

Try below code

public class ChatHeadService extends Service {

    private WindowManager windowManager;
    private ImageView chatHead;
    private static final String TAG = "ChatheadService";
    private Timer timer;
    private static final int delay = 500; // delay for .5 sec before first start
    private static final int period = 500; // repeat check every .5 sec.
    Intent mIntent;
    WindowManager.LayoutParams params;
    ActivityManager activityManager;
    @Override public IBinder onBind(Intent intent) {
        Log.i("called", "onBind");
        return null;
    }

    @Override public void onCreate() {
        super.onCreate();
        Log.i("called", "onCreate");
        windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        chatHead = new ImageView(this);
        chatHead.setImageResource(R.drawable.app_icon);    
       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;
        activityManager = (ActivityManager) this.getSystemService(Context.ACTIVITY_SERVICE);

        //handleCommand(intent);
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i("called", "onStartCommand");
        mIntent=intent;
        handleCommand(intent);
        return START_NOT_STICKY;
    }

    // handles a Start command
    private void handleCommand(Intent intent) {
        Log.d(TAG, "service is starting");
        if (timer == null) {
            timer = new Timer();
            timer.schedule(new TimerTask() {
                public void run() {
                    checkActivityForeground();
                }
            }, delay, period);
        }
    }

    protected void checkActivityForeground() {
ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            final List<ActivityManager.RunningAppProcessInfo> processInfos = am
                    .getRunningAppProcesses();
            ActivityManager.RunningAppProcessInfo processInfo = processInfos
                    .get(0);
            // for (ActivityManager.RunningAppProcessInfo processInfo : processInfos) {
            if (processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
                // getting process at 0th index means our application is on top on all apps or currently open 
                appPackageName = (Arrays.asList(processInfo.pkgList).get(0));
            }
            // }
        }
        else {
            List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);
            ComponentName componentInfo = null;
            componentInfo = taskInfo.get(0).topActivity;
            appPackageName = componentInfo.getPackageName();
        }


        Handler handler = new Handler(Looper.getMainLooper());
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {



                if(appPackageName.contains("com.whatsapp")){
                     if(chatHead.isShown()==false){
                         windowManager.addView(chatHead, params);
                         }

                }else{
                     if ((chatHead != null) && chatHead.isShown()){
                         windowManager.removeView(chatHead);
                     }
                }


            }
        }, 500);

        }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy");
        Handler handler = new Handler(Looper.getMainLooper());
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                if ((chatHead != null) && chatHead.isShown()){
                    windowManager.removeView(chatHead);
                }
            }
        }, 500);
        timer.cancel();
    }
}

In the manifest add

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

In your activity class start the service as

startService(new Intent(MainActivity.this, ChatHeadService.class));
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top