Skip to content

Instantly share code, notes, and snippets.

@tyvsmith
Last active October 26, 2018 19:15
  • Star 14 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save tyvsmith/6188014 to your computer and use it in GitHub Desktop.
If you have multiple Android apps that need to report to the same Crashlytics app endpoint. This allows overriding the package name that Crashlytics discovers and reports.
public class MyApp extends Application {
private final String PACKAGE="me.tysmith.app";
@Override
public void onCreate() {
super.onCreate();
Crashlytics.start(new CrashContextWrapper(this, PACKAGE));
}
}
package com.evernote.crash;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.pm.PackageManager;
/**
* Wraps ContextWrapper to fake one package name for another to crashlytics
*/
public class CrashContextWrapper extends ContextWrapper {
private String mOveridePackageName;
/**
* @param base Context
* @param packageName package Name to overide with
*/
public CrashContextWrapper(Context base, String packageName) {
super(base);
mOveridePackageName = packageName;
}
/**
* @return the overide package name
*/
@Override
public String getPackageName() {
return mOveridePackageName;
}
/**
* @return Application Context Wrapped in CrashContextWrapper
*/
@Override
public Context getApplicationContext() {
return new CrashContextWrapper(super.getApplicationContext(), mOveridePackageName);
}
/**
* @return PackageManager Wrapped in CrashPackageManager
*/
@Override
public PackageManager getPackageManager() {
return new CrashPackageManager(super.getPackageManager(), super.getPackageName(), mOveridePackageName);
}
}
package com.evernote.crash;
import android.annotation.TargetApi;
import android.content.ComponentName;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.*;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.graphics.drawable.Drawable;
import android.os.Build;
import java.util.List;
/**
* Wraps PackageManager to fake one package name for another to crashlytics
* Decorator Pattern
*/
public class CrashPackageManager extends PackageManager {
private final PackageManager mPackageManager;
private final String mPackageName;
private final String mOverridePackageName;
/**
*
* @param pm Real Package Manager
* @param packageName Real Package Name
* @param overridePackageName Faking Package Name
*/
CrashPackageManager(PackageManager pm, String packageName, String overridePackageName) {
mPackageManager = pm;
mPackageName = packageName;
mOverridePackageName = overridePackageName;
}
/**
* Only translate the overridden package name, the third party may need external lookups at some point
* @param packageName
* @return
*/
private String translatePackageName(String packageName) {
if(mOverridePackageName.equals(packageName)) {
return mPackageName;
} else {
return packageName;
}
}
/** Delegated Methods for Package Manager **/
public PackageInfo getPackageInfo(String packageName, int flags) throws PackageManager.NameNotFoundException {
return mPackageManager.getPackageInfo(translatePackageName(packageName), flags);
}
public String[] currentToCanonicalPackageNames(String[] names) {
return mPackageManager.currentToCanonicalPackageNames(names);
}
public String[] canonicalToCurrentPackageNames(String[] names) {
return mPackageManager.canonicalToCurrentPackageNames(names);
}
public Intent getLaunchIntentForPackage(String packageName) {
return mPackageManager.getLaunchIntentForPackage(translatePackageName(packageName));
}
public int[] getPackageGids(String packageName) throws PackageManager.NameNotFoundException {
return mPackageManager.getPackageGids(translatePackageName(packageName));
}
public PermissionInfo getPermissionInfo(String name, int flags) throws PackageManager.NameNotFoundException {
return mPackageManager.getPermissionInfo(name, flags);
}
public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) throws PackageManager.NameNotFoundException {
return mPackageManager.queryPermissionsByGroup(group, flags);
}
public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) throws PackageManager.NameNotFoundException {
return mPackageManager.getPermissionGroupInfo(name, flags);
}
public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
return mPackageManager.getAllPermissionGroups(flags);
}
public ApplicationInfo getApplicationInfo(String packageName, int flags) throws PackageManager.NameNotFoundException {
return mPackageManager.getApplicationInfo(translatePackageName(packageName), flags);
}
public ActivityInfo getActivityInfo(ComponentName component, int flags) throws PackageManager.NameNotFoundException {
return mPackageManager.getActivityInfo(component, flags);
}
public ActivityInfo getReceiverInfo(ComponentName component, int flags) throws PackageManager.NameNotFoundException {
return mPackageManager.getReceiverInfo(component, flags);
}
public ServiceInfo getServiceInfo(ComponentName component, int flags) throws PackageManager.NameNotFoundException {
return mPackageManager.getServiceInfo(component, flags);
}
@TargetApi(Build.VERSION_CODES.GINGERBREAD)
public ProviderInfo getProviderInfo(ComponentName component, int flags) throws PackageManager.NameNotFoundException {
return mPackageManager.getProviderInfo(component, flags);
}
public List<PackageInfo> getInstalledPackages(int flags) {
return mPackageManager.getInstalledPackages(flags);
}
public int checkPermission(String permName, String pkgName) {
return mPackageManager.checkPermission(permName, pkgName);
}
public boolean addPermission(PermissionInfo info) {
return mPackageManager.addPermission(info);
}
public boolean addPermissionAsync(PermissionInfo info) {
return mPackageManager.addPermissionAsync(info);
}
public void removePermission(String name) {
mPackageManager.removePermission(name);
}
public int checkSignatures(String pkg1, String pkg2) {
return mPackageManager.checkSignatures(pkg1, pkg2);
}
public int checkSignatures(int uid1, int uid2) {
return mPackageManager.checkSignatures(uid1, uid2);
}
public String[] getPackagesForUid(int uid) {
return mPackageManager.getPackagesForUid(uid);
}
public String getNameForUid(int uid) {
return mPackageManager.getNameForUid(uid);
}
public List<ApplicationInfo> getInstalledApplications(int flags) {
return mPackageManager.getInstalledApplications(flags);
}
public String[] getSystemSharedLibraryNames() {
return mPackageManager.getSystemSharedLibraryNames();
}
public FeatureInfo[] getSystemAvailableFeatures() {
return mPackageManager.getSystemAvailableFeatures();
}
public boolean hasSystemFeature(String name) {
return mPackageManager.hasSystemFeature(name);
}
public ResolveInfo resolveActivity(Intent intent, int flags) {
return mPackageManager.resolveActivity(intent, flags);
}
public List<ResolveInfo> queryIntentActivities(Intent intent, int flags) {
return mPackageManager.queryIntentActivities(intent, flags);
}
public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller, Intent[] specifics, Intent intent, int flags) {
return mPackageManager.queryIntentActivityOptions(caller, specifics, intent, flags);
}
public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) {
return mPackageManager.queryBroadcastReceivers(intent, flags);
}
public ResolveInfo resolveService(Intent intent, int flags) {
return mPackageManager.resolveService(intent, flags);
}
public List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
return mPackageManager.queryIntentServices(intent, flags);
}
public ProviderInfo resolveContentProvider(String name, int flags) {
return mPackageManager.resolveContentProvider(name, flags);
}
public List<ProviderInfo> queryContentProviders(String processName, int uid, int flags) {
return mPackageManager.queryContentProviders(processName, uid, flags);
}
public InstrumentationInfo getInstrumentationInfo(ComponentName className, int flags) throws PackageManager.NameNotFoundException {
return mPackageManager.getInstrumentationInfo(className, flags);
}
public List<InstrumentationInfo> queryInstrumentation(String targetPackage, int flags) {
return mPackageManager.queryInstrumentation(targetPackage, flags);
}
public Drawable getDrawable(String packageName, int resid, ApplicationInfo appInfo) {
return mPackageManager.getDrawable(translatePackageName(packageName), resid, appInfo);
}
public Drawable getActivityIcon(ComponentName activityName) throws PackageManager.NameNotFoundException {
return mPackageManager.getActivityIcon(activityName);
}
public Drawable getActivityIcon(Intent intent) throws PackageManager.NameNotFoundException {
return mPackageManager.getActivityIcon(intent);
}
public Drawable getDefaultActivityIcon() {
return mPackageManager.getDefaultActivityIcon();
}
public Drawable getApplicationIcon(ApplicationInfo info) {
return mPackageManager.getApplicationIcon(info);
}
public Drawable getApplicationIcon(String packageName) throws PackageManager.NameNotFoundException {
return mPackageManager.getApplicationIcon(translatePackageName(packageName));
}
@TargetApi(Build.VERSION_CODES.GINGERBREAD)
public Drawable getActivityLogo(ComponentName activityName) throws PackageManager.NameNotFoundException {
return mPackageManager.getActivityLogo(activityName);
}
@TargetApi(Build.VERSION_CODES.GINGERBREAD)
public Drawable getActivityLogo(Intent intent) throws PackageManager.NameNotFoundException {
return mPackageManager.getActivityLogo(intent);
}
@TargetApi(Build.VERSION_CODES.GINGERBREAD)
public Drawable getApplicationLogo(ApplicationInfo info) {
return mPackageManager.getApplicationLogo(info);
}
@TargetApi(Build.VERSION_CODES.GINGERBREAD)
public Drawable getApplicationLogo(String packageName) throws PackageManager.NameNotFoundException {
return mPackageManager.getApplicationLogo(translatePackageName(packageName));
}
public CharSequence getText(String packageName, int resid, ApplicationInfo appInfo) {
return mPackageManager.getText(translatePackageName(packageName), resid, appInfo);
}
public XmlResourceParser getXml(String packageName, int resid, ApplicationInfo appInfo) {
return mPackageManager.getXml(translatePackageName(packageName), resid, appInfo);
}
public CharSequence getApplicationLabel(ApplicationInfo info) {
return mPackageManager.getApplicationLabel(info);
}
public Resources getResourcesForActivity(ComponentName activityName) throws PackageManager.NameNotFoundException {
return mPackageManager.getResourcesForActivity(activityName);
}
public Resources getResourcesForApplication(ApplicationInfo app) throws PackageManager.NameNotFoundException {
return mPackageManager.getResourcesForApplication(app);
}
public Resources getResourcesForApplication(String appPackageName) throws PackageManager.NameNotFoundException {
return mPackageManager.getResourcesForApplication(appPackageName);
}
public PackageInfo getPackageArchiveInfo(String archiveFilePath, int flags) {
return mPackageManager.getPackageArchiveInfo(archiveFilePath, flags);
}
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
public void verifyPendingInstall(int id, int verificationCode) {
mPackageManager.verifyPendingInstall(id, verificationCode);
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
public void extendVerificationTimeout(int id, int verificationCodeAtTimeout, long millisecondsToDelay) {
mPackageManager.extendVerificationTimeout(id, verificationCodeAtTimeout, millisecondsToDelay);
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void setInstallerPackageName(String targetPackage, String installerPackageName) {
mPackageManager.setInstallerPackageName(targetPackage, installerPackageName);
}
public String getInstallerPackageName(String packageName) {
return mPackageManager.getInstallerPackageName(translatePackageName(packageName));
}
public void addPackageToPreferred(String packageName) {
mPackageManager.addPackageToPreferred(translatePackageName(packageName));
}
public void removePackageFromPreferred(String packageName) {
mPackageManager.removePackageFromPreferred(translatePackageName(packageName));
}
public List<PackageInfo> getPreferredPackages(int flags) {
return mPackageManager.getPreferredPackages(flags);
}
public void addPreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity) {
mPackageManager.addPreferredActivity(filter, match, set, activity);
}
public void clearPackagePreferredActivities(String packageName) {
mPackageManager.clearPackagePreferredActivities(translatePackageName(packageName));
}
public int getPreferredActivities(List<IntentFilter> outFilters, List<ComponentName> outActivities, String packageName) {
return mPackageManager.getPreferredActivities(outFilters, outActivities, translatePackageName(packageName));
}
public void setComponentEnabledSetting(ComponentName componentName, int newState, int flags) {
mPackageManager.setComponentEnabledSetting(componentName, newState, flags);
}
public int getComponentEnabledSetting(ComponentName componentName) {
return mPackageManager.getComponentEnabledSetting(componentName);
}
public void setApplicationEnabledSetting(String packageName, int newState, int flags) {
mPackageManager.setApplicationEnabledSetting(translatePackageName(packageName), newState, flags);
}
public int getApplicationEnabledSetting(String packageName) {
return mPackageManager.getApplicationEnabledSetting(translatePackageName(packageName));
}
public boolean isSafeMode() {
return mPackageManager.isSafeMode();
}
}
@Jiboo
Copy link

Jiboo commented May 11, 2015

You can use the provided Fabric.Builder with the newest Fabric's Crashlytics to override the app identifier, if not provided it defaults to context.getPackageName().

Fabric.with(new Fabric.Builder(context).kits(new Crashlytics()).appIdentifier("com.stuff.overridden").build());

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment