0

I need to know when the screen gets visible in the app how can I get to know which activity is related to that screen. Especially if I'm using another SDK to get login screens. So I need to know the activity name and package name of those screens.

Currently, I have a method inside my BaseActivity class to log activity names when it navigates between screens. But when I click login button it opens another screen which belongs to that third part SDK.

   /**
     * Logs the component with activity name and method
     *
     * @param tag
     */
    private void logActivityInfo(String tag) {
        mLogService.logScreenInfo(this.getClass().getSimpleName() + tag);
    }

I think this can be solved if I have a trick to get activity name when I visible that screen. Because Android Profiler shows all activity names when moving between all screens. It would be great if someone can help me to find a way to solve this.

Zoe
  • 27,060
  • 21
  • 118
  • 148
Rajitha Perera
  • 1,581
  • 5
  • 26
  • 42
  • 1
    Just a guess, haven't verified it myself since I don't have third party apps using activities. Register a `registerActivityLifecycleCallbacks` in your Application class and in the `onActivityCreated` you can log the class name https://developer.android.com/reference/android/app/Application.html#registerActivityLifecycleCallbacks(android.app.Application.ActivityLifecycleCallbacks) – Zun Jun 24 '19 at 08:06
  • @Zun Thanks, mate. Actually, I have already implemented in my Application class. But it recorded only activities that have created by my self. I need to track some SDK related activities also. – Rajitha Perera Jun 24 '19 at 08:10

2 Answers2

1

You can use accessiblity service in Android to do this. I have a code thats working for me. You can try it out

package com.butterfly.instaliker;

public class WindowChangeDetectingService extends AccessibilityService 
{

@Override
protected void onServiceConnected() {
    super.onServiceConnected();

    //Configure these here for compatibility with API 13 and below.
    AccessibilityServiceInfo config = new AccessibilityServiceInfo();
    config.eventTypes = AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED;
    config.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;

    if (Build.VERSION.SDK_INT >= 16)
        //Just in case this helps
        config.flags = AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;

    setServiceInfo(config);
}

@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
    if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
        if (event.getPackageName() != null && event.getClassName() != null) {
            ComponentName componentName = new ComponentName(
                    event.getPackageName().toString(),
                    event.getClassName().toString()
            );

            ActivityInfo activityInfo = tryGetActivity(componentName);
            boolean isActivity = activityInfo != null;
            if (isActivity)
                if(componentName.flattenToShortString().equalsIgnoreCase(" com.instagram.android/com.instagram.mainactivity.MainActivity")){
                    scrollAndLike(event);
                }
                Log.i("CurrentActivity", componentName.flattenToShortString());
        }
    }
}

private void scrollAndLike(AccessibilityEvent event) {
    AccessibilityNodeInfo nodeInfo = event.getSource();
    Log.i("jude", "ACC::onAccessibilityEvent: nodeInfo=" + nodeInfo);
    if (nodeInfo == null) {
        return;
    }









}

private ActivityInfo tryGetActivity(ComponentName componentName) {
    try {
        return getPackageManager().getActivityInfo(componentName, 0);
    } catch (PackageManager.NameNotFoundException e) {
        return null;
    }
}

@Override
public void onInterrupt() {}
}

Your app should have the accessibility permission which you need the user to enable like

if (!isAccessibilitySettingsOn(getApplicationContext())) {
        Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
        startActivityForResult(intent,1000);
    }
    else{
        startService(new Intent(this,WindowChangeDetectingService.class));
    }

and

protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(requestCode == 1000){
            startService(new Intent(this,WindowChangeDetectingService.class));
    }
}


private boolean isAccessibilitySettingsOn(Context mContext) {
    String TAG = "jude";
    int accessibilityEnabled = 0;
    final String service = getPackageName() + "/" + WindowChangeDetectingService.class.getCanonicalName();
    try {
        accessibilityEnabled = Settings.Secure.getInt(
                mContext.getApplicationContext().getContentResolver(),
                android.provider.Settings.Secure.ACCESSIBILITY_ENABLED);
        Log.v(TAG, "accessibilityEnabled = " + accessibilityEnabled);
    } catch (Settings.SettingNotFoundException e) {
        Log.e(TAG, "Error finding setting, default accessibility to not found: "
                + e.getMessage());
    }
    TextUtils.SimpleStringSplitter mStringColonSplitter = new TextUtils.SimpleStringSplitter(':');

    if (accessibilityEnabled == 1) {
        Log.v(TAG, "***ACCESSIBILITY IS ENABLED*** -----------------");
        String settingValue = Settings.Secure.getString(
                mContext.getApplicationContext().getContentResolver(),
                Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
        if (settingValue != null) {
            mStringColonSplitter.setString(settingValue);
            while (mStringColonSplitter.hasNext()) {
                String accessibilityService = mStringColonSplitter.next();

                Log.v(TAG, "-------------- > accessibilityService :: " + accessibilityService + " " + service);
                if (accessibilityService.equalsIgnoreCase(service)) {
                    Log.v(TAG, "We've found the correct setting - accessibility is switched on!");
                    return true;
                }
            }
        }
    } else {
        Log.v(TAG, "***ACCESSIBILITY IS DISABLED***");
    }

    return false;
}

Source : https://stackoverflow.com/a/27642535/5182150

Jude Osbert K
  • 940
  • 9
  • 22
1

Maybe tracking activity life cycle events solves your problem here is some sample code.

    public class MyApplication extends Application
    implements Application.ActivityLifecycleCallbacks {

    private int numStarted;

    ...

    @Override
    public void onCreate() {
        ...
        registerActivityLifecycleCallbacks(this);
    }

    @Override
    public void onActivityStarted(Activity activity) {
        //some code
    }

    @Override
    public void onActivityStopped(Activity activity) {
        //some code
    }
}

because they will run in your application context so tracking them there should list them as well.

vikas kumar
  • 10,447
  • 2
  • 46
  • 52