We have a taxi app which has been quite successful in Europe. But recently one of our competitors has started checking if our app is installed and if it is, theirs won't run until the user uninstalls our app from their phone.
We initially did a few manual updates with a different package name to bypass their check but they are using a manual scan, i.e:
- They get a list of installed package names from user's phone
- List is sent to their servers
- Someone checks the names and flags our package name
- flags are pushed to their apps and once again we are blocked
They do not distribute their app via Play Store so we can't file a complaint about them to Google. Is there any other possibility to bypass this check? for example renaming the package name at runtime? We are losing users currently as the competitor has more orders (customers) for their drivers and most of our users would uninstall our app in order to use theirs.
UPDATE: Decided to decompile their app and see what they are doing there, I was wrong about their stategy, they have hardcoded our company and application name into their forbiddenApps preferences. Below is the code they are using, particularly the refineForbiddenSet()
method is where our app gets flagged as far as I can see.
public class ForbiddenAppHelper
{
public ForbiddenAppHelper()
{
}
public static void UninstallApp(Context context, String s)
{
context.startActivity(new Intent("android.intent.action.DELETE", Uri.fromParts("package", s, null)));
}
public static boolean forbiddenAppsExist(Context context, String s)
{
return getForbidden(context, s).size() != 0;
}
public static Drawable getAppIcon(Context context, String s)
{
PackageManager packagemanager = context.getPackageManager();
Drawable drawable;
try
{
drawable = packagemanager.getApplicationIcon(s);
}
catch (android.content.pm.PackageManager.NameNotFoundException namenotfoundexception)
{
namenotfoundexception.printStackTrace();
return null;
}
return drawable;
}
public static String getAppName(Context context, PackageManager packagemanager, String s)
{
if (packagemanager == null)
{
packagemanager = context.getPackageManager();
}
ApplicationInfo applicationinfo1 = packagemanager.getApplicationInfo(s, 0);
ApplicationInfo applicationinfo = applicationinfo1;
_L1:
android.content.pm.PackageManager.NameNotFoundException namenotfoundexception;
Object obj;
if (applicationinfo != null)
{
obj = packagemanager.getApplicationLabel(applicationinfo);
} else
{
obj = "(unknown)";
}
return (String)obj;
namenotfoundexception;
applicationinfo = null;
goto _L1
}
public static ArrayList getApplicationList(Context context)
{
ArrayList arraylist = new ArrayList();
PackageManager packagemanager = context.getPackageManager();
List list = packagemanager.getInstalledPackages(0);
int i = 0;
do
{
if (i >= list.size())
{
return arraylist;
}
PackageInfo packageinfo = (PackageInfo)list.get(i);
if (packageinfo.versionName != null)
{
String s = packageinfo.packageName;
arraylist.add(new InstalledApplication(packageinfo.applicationInfo.loadLabel(packagemanager).toString(), s));
}
i++;
} while (true);
}
private static ArrayList getForbidden(Context context, String s)
{
HashSet hashset;
StringTokenizer stringtokenizer;
ArrayList arraylist;
hashset = new HashSet();
stringtokenizer = new StringTokenizer(s, ";");
arraylist = new ArrayList();
arraylist = getApplicationList(context);
_L3:
boolean flag = stringtokenizer.hasMoreTokens();
if (flag) goto _L2; else goto _L1
_L1:
return refineFobiddenSet(arraylist, hashset);
_L2:
hashset.add(stringtokenizer.nextToken());
goto _L3
Exception exception;
exception;
Crashlytics.logException(exception);
goto _L1
}
public static String[] getForbiddenApps(Context context, String s)
{
ArrayList arraylist = getForbidden(context, s);
return (String[])arraylist.toArray(new String[arraylist.size()]);
}
private static ArrayList refineFobiddenSet(ArrayList arraylist, HashSet hashset)
{
ArrayList arraylist1 = new ArrayList();
Iterator iterator = hashset.iterator();
do
{
if (!iterator.hasNext())
{
return new ArrayList(new HashSet(arraylist1));
}
String s = (String)iterator.next();
Iterator iterator1 = arraylist.iterator();
while (iterator1.hasNext())
{
InstalledApplication installedapplication = (InstalledApplication)iterator1.next();
if (installedapplication.name.equals(s) || installedapplication.pname.equals(s))
{
arraylist1.add(installedapplication.pname);
}
}
} while (true);
}
}