Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added extra checks and option to save result to SharedPreferences #15

Merged
merged 18 commits into from
Mar 13, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 64 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,6 @@ dependencies {
```

## Usage
Add **CHECK_LICENSE** permission to your app's Manifest:
```xml
<uses-permission android:name="com.android.vending.CHECK_LICENSE"/>
```

### Verify Google Play Licensing (LVL)
Google Play offers a licensing service that lets you enforce licensing policies for applications that you publish on Google Play. With Google Play Licensing, your application can query Google Play to obtain the licensing status for the current user.
Expand Down Expand Up @@ -88,6 +84,58 @@ new PiracyChecker(this)

**BE CAREFUL!!** This is a really restrictive technique since it will block your app from being installed using another market or directly installing the .apk on the device. It isn't recommended for most cases.

### Verify the use of certain pirate apps
If you want to check if user has pirate apps installed, you can use this code.
It will check for: Lucky Patcher, Freedom and CreeHack.

```Java
new PiracyChecker(this)
.enableLPFCheck(true)
.start();
```

If you want to check if user has third-party store apps installed, you can use this code.
It will check for: Aptoide, BlackMart, Mobogenie, 1Mobile, GetApk, GetJar and SlideMe.

```Java
new PiracyChecker(this)
.enableStoresCheck(true)
.start();
```

### Verify if app is a debug build.
```Java
new PiracyChecker(this)
.enableDebugCheck(true)
.start();
```

### Verify if app is being run in an emulator
```Java
new PiracyChecker(this)
.enableEmulatorCheck(true)
.start();
```

### Save the result of the license check in `SharedPreferences`

There are two ways to do this:

Define the `SharedPreferences` and the name of the preference where you want to save the result.
```Java
new PiracyChecker(this)
.saveResultToSharedPreferences(preferences, "valid_license");
.start();
```

Define the `SharedPreferences` name and the name of the preference where you want to save the result.
```Java
new PiracyChecker(this)
.saveResultToSharedPreferences("my_app_preferences", "valid_license");
.start();
```


## Customizations
Adding a callback to the builder allows you to customize what will happen when the license has been checked and manage the license check errors if the user is not allowed to use the app. Keep in mind that when using this method **you must be aware of blocking the app from unauthorized users**.

Expand All @@ -103,13 +151,18 @@ Use the builder and add following:
}

@Override
public void dontAllow(PiracyCheckerError error) {
public void dontAllow(@NonNull PiracyCheckerError error, @Nullable PirateApp app) {
// You can either do something specific when the user is not allowed to use the app
// Or manage the error, using the 'error' parameter, yourself (Check errors at {@link PiracyCheckerError}).

// Additionally, if you enabled the check of pirate apps and/or third-party stores, the 'app' param
// is the app that has been detected on device. App can be null, and when null, it means no pirate app or store was found,
// or you disabled the check for those apps.
// This allows you to let users know the possible reasons why license is been invalid.
}

@Override
public void onError(PiracyCheckerError error) {
public void onError(@NonNull PiracyCheckerError error) {
// This method is not required to be implemented/overriden but...
// You can either do something specific when an error occurs while checking the license,
// Or manage the error, using the 'error' parameter, yourself (Check errors at {@link PiracyCheckerError}).
Expand All @@ -119,10 +172,8 @@ Use the builder and add following:

## ProGuard
```
-keep class com.google.**
-keep class autovalue.shaded.com.google.**
-dontwarn com.google.**
-dontwarn autovalue.shaded.com.google.**
-keep class com.github.javiersantos.**
-dontwarn com.github.javiersantos.**
-keep public class com.android.vending.licensing.ILicensingService
```

Expand All @@ -134,11 +185,13 @@ Sure. You can use as many validation methods in the builder as you want. For exa
new PiracyChecker(this)
.enableGooglePlayLicensing("BASE_64_LICENSE_KEY")
.enableSigningCertificate("YOUR_APK_SIGNATURE")
.enableLPFCheck(true)
.saveResultToSharedPreferences("my_app_preferences", "valid_license");
.start();
```

## License
Copyright 2016 Javier Santos
Copyright 2017 Javier Santos

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
4 changes: 1 addition & 3 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
xmlns:tools="http://schemas.android.com/tools"
package="com.github.javiersantos.piracychecker.demo">

<uses-permission android:name="com.android.vending.CHECK_LICENSE"/>

<application
android:allowBackup="true"
android:fullBackupContent="true"
Expand All @@ -30,4 +28,4 @@
android:label="@string/action_about"/>
</application>

</manifest>
</manifest>
3 changes: 3 additions & 0 deletions library/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,8 @@
# public *;
#}

# Lib
-keep class com.github.javiersantos.**
-dontwarn com.github.javiersantos.**
# LVL
-keep public class com.android.vending.licensing.ILicensingService
7 changes: 4 additions & 3 deletions library/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.github.javiersantos.piracychecker" >
<uses-permission android:name="com.android.vending.CHECK_LICENSE"/>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.github.javiersantos.piracychecker">

<uses-permission android:name="com.android.vending.CHECK_LICENSE"/>
</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,19 @@
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.os.Environment;
import android.support.v7.app.AlertDialog;
import android.util.Base64;

import com.github.javiersantos.piracychecker.R;
import com.github.javiersantos.piracychecker.enums.InstallerID;
import com.github.javiersantos.piracychecker.enums.PirateApp;

import java.io.File;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
Expand Down Expand Up @@ -45,7 +49,6 @@ public void onClick(DialogInterface dialogInterface, int i) {

static String getCurrentSignature(Context context) {
String res = "";

try {
PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context
.getPackageName(), PackageManager.GET_SIGNATURES);
Expand All @@ -56,7 +59,6 @@ static String getCurrentSignature(Context context) {
}
} catch (PackageManager.NameNotFoundException | NoSuchAlgorithmException ignored) {
}

return res.trim();
}

Expand All @@ -76,4 +78,70 @@ static boolean verifyInstallerId(Context context, List<InstallerID> installerID)
return installer != null && validInstallers.contains(installer);
}

}
@SuppressLint("SdCardPath")
static PirateApp getPirateApp(Context context, boolean lpf, boolean stores) {
if (!lpf && !stores) return null;
for (PirateApp app : PiracyCheckerUtils.getApps()) {
if ((lpf && app.isLPF()) || (stores && !app.isLPF())) {
StringBuilder builder = new StringBuilder();
for (String s : app.getPack()) {
builder.append(s);
}
String pack = builder.toString();
PackageManager pm = context.getPackageManager();
try {
PackageInfo info = pm.getPackageInfo(pack, PackageManager.GET_META_DATA);
if (info != null) return app;
} catch (PackageManager.NameNotFoundException ignored1) {
try {
Intent intent = pm.getLaunchIntentForPackage(pack);
if (PiracyCheckerUtils.isIntentAvailable(context, intent)) {
return app;
}
} catch (Exception ignored2) {
try {
if (PiracyCheckerUtils.hasPermissions(context)) {
File file1 = new File("/data/app/" + pack + "-1/base.apk");
File file2 = new File("/data/app/" + pack + "-2/base.apk");
File file3 = new File("/data/app/" + pack + ".apk");
File file4 = new File("/data/data/" + pack + ".apk");
File file5 = new File("/data/data/" + pack);
File file6 = new File(context.getFilesDir().getPath() + pack +
".apk");
File file7 = new File(context.getFilesDir().getPath() + pack);
File file8 = new File(Environment.getExternalStorageDirectory() +
"/Android/data/" + pack);
if (file1.exists() || file2.exists() || file3.exists() ||
file4.exists() || file5.exists() || file6.exists() ||
file7.exists() || file8.exists()) {
return app;
}
}
} catch (Exception ignored3) {
}
}
}
}
}
return null;
}

static boolean isInEmulator() {
try {
boolean goldfish = PiracyCheckerUtils.getSystemProperty("ro.hardware")
.contains("goldfish");
boolean emu = PiracyCheckerUtils.getSystemProperty("ro.kernel.qemu").length() > 0;
boolean sdk = PiracyCheckerUtils.getSystemProperty("ro.product.model").equals("sdk");
if (emu || goldfish || sdk) {
return true;
}
} catch (Exception ignored) {
}
return false;
}

static boolean isDebug(Context context) {
return ((context.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0);
}

}
Loading