From 245942ff1450c8d11456a1a7134d4314baf18778 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Wed, 20 Jun 2018 19:07:20 +0100 Subject: [PATCH] added method to MainActivity to obtain a device ID (#182) --- .travis.yml | 6 +- buildozer.spec.sample | 4 +- buildozer.spec.travis | 4 +- .../java/io/lbry/browser/MainActivity.java | 104 ++++++++++++++++-- 4 files changed, 99 insertions(+), 19 deletions(-) diff --git a/.travis.yml b/.travis.yml index 332e8962..1bba4c05 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,13 +28,13 @@ install: - mkdir -p cd ~/.buildozer/android/platform/ - wget -q 'https://dl.google.com/android/repository/android-ndk-r13b-linux-x86_64.zip' -P ~/.buildozer/android/platform/ - wget -q 'https://dl.google.com/android/android-sdk_r23-linux.tgz' -P ~/.buildozer/android/platform/ -- wget -q 'https://dl.google.com/android/repository/android-23_r02.zip' -P ~/.buildozer/android/platform/ +- wget -q 'https://dl.google.com/android/repository/platform-26_r02.zip' -P ~/.buildozer/android/platform/ - wget -q 'https://dl.google.com/android/repository/build-tools_r26.0.1-linux.zip' -P ~/.buildozer/android/platform/ - unzip -qq ~/.buildozer/android/platform/android-ndk-r13b-linux-x86_64.zip -d ~/.buildozer/android/platform/ - tar -xf ~/.buildozer/android/platform/android-sdk_r23-linux.tgz -C ~/.buildozer/android/platform/ - mv ~/.buildozer/android/platform/android-sdk-linux ~/.buildozer/android/platform/android-sdk-23 -- unzip -qq ~/.buildozer/android/platform/android-23_r02.zip -d ~/.buildozer/android/platform/android-sdk-23/platforms -- mv ~/.buildozer/android/platform/android-sdk-23/platforms/android-6.0 ~/.buildozer/android/platform/android-sdk-23/platforms/android-23 +- unzip -qq ~/.buildozer/android/platform/platform-26_r02.zip -d ~/.buildozer/android/platform/android-sdk-23/platforms +- mv ~/.buildozer/android/platform/android-sdk-23/platforms/android-8.0.0 ~/.buildozer/android/platform/android-sdk-23/platforms/android-26 - mkdir -p ~/.buildozer/android/platform/android-sdk-23/build-tools - unzip -qq ~/.buildozer/android/platform/build-tools_r26.0.1-linux.zip -d ~/.buildozer/android/platform/android-sdk-23/build-tools - mv ~/.buildozer/android/platform/android-sdk-23/build-tools/android-8.0.0 ~/.buildozer/android/platform/android-sdk-23/build-tools/26.0.1 diff --git a/buildozer.spec.sample b/buildozer.spec.sample index 4707c06e..1545f054 100644 --- a/buildozer.spec.sample +++ b/buildozer.spec.sample @@ -86,10 +86,10 @@ fullscreen = 0 #android.presplash_color = #FFFFFF # (list) Permissions -android.permissions = ACCESS_NETWORK_STATE,BLUETOOTH,INTERNET,READ_EXTERNAL_STORAGE,WRITE_EXTERNAL_STORAGE +android.permissions = ACCESS_NETWORK_STATE,BLUETOOTH,INTERNET,READ_EXTERNAL_STORAGE,READ_PHONE_STATE,WRITE_EXTERNAL_STORAGE # (int) Android API to use -android.api = 23 +android.api = 26 # (int) Minimum API required android.minapi = 21 diff --git a/buildozer.spec.travis b/buildozer.spec.travis index 4707c06e..1545f054 100644 --- a/buildozer.spec.travis +++ b/buildozer.spec.travis @@ -86,10 +86,10 @@ fullscreen = 0 #android.presplash_color = #FFFFFF # (list) Permissions -android.permissions = ACCESS_NETWORK_STATE,BLUETOOTH,INTERNET,READ_EXTERNAL_STORAGE,WRITE_EXTERNAL_STORAGE +android.permissions = ACCESS_NETWORK_STATE,BLUETOOTH,INTERNET,READ_EXTERNAL_STORAGE,READ_PHONE_STATE,WRITE_EXTERNAL_STORAGE # (int) Android API to use -android.api = 23 +android.api = 26 # (int) Minimum API required android.minapi = 21 diff --git a/src/main/java/io/lbry/browser/MainActivity.java b/src/main/java/io/lbry/browser/MainActivity.java index 6d86dff9..0cfac89c 100644 --- a/src/main/java/io/lbry/browser/MainActivity.java +++ b/src/main/java/io/lbry/browser/MainActivity.java @@ -4,8 +4,6 @@ import android.os.Build; import android.os.Bundle; import android.app.Activity; import android.app.ActivityManager; -import android.support.v4.app.ActivityCompat; -import android.support.v4.content.ContextCompat; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; @@ -14,6 +12,9 @@ import android.content.SharedPreferences; import android.Manifest; import android.net.Uri; import android.provider.Settings; +import android.support.v4.app.ActivityCompat; +import android.support.v4.content.ContextCompat; +import android.telephony.TelephonyManager; import android.widget.Toast; import com.brentvatne.react.ReactVideoPackage; @@ -26,18 +27,30 @@ import com.facebook.react.shell.MainReactPackage; import io.lbry.browser.reactpackages.LbryReactPackage; import io.lbry.browser.reactmodules.DownloadManagerModule; +import java.io.UnsupportedEncodingException; +import java.math.BigInteger; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Random; + public class MainActivity extends Activity implements DefaultHardwareBackBtnHandler { private static final int OVERLAY_PERMISSION_REQ_CODE = 101; private static final int STORAGE_PERMISSION_REQ_CODE = 201; + private static final int PHONE_STATE_PERMISSION_REQ_CODE = 202; + private ReactRootView mReactRootView; private ReactInstanceManager mReactInstanceManager; public static final String SHARED_PREFERENCES_NAME = "LBRY"; + public static final String SALT_KEY = "salt"; + + public static final String DEVICE_ID_KEY = "deviceId"; + /** * Flag which indicates whether or not the service is running. Will be updated in the * onResume method. @@ -52,16 +65,11 @@ public class MainActivity extends Activity implements DefaultHardwareBackBtnHand protected void onCreate(Bundle savedInstanceState) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { // Request external storage permission on Android version >= 6 - if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { - // Should we show an explanation? - if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) { - Toast.makeText(this, - "LBRY requires access to your device storage to be able to download files and media.", Toast.LENGTH_LONG).show(); - } else { - ActivityCompat.requestPermissions(this, - new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE }, STORAGE_PERMISSION_REQ_CODE); - } - } + checkPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, + STORAGE_PERMISSION_REQ_CODE, + "LBRY requires access to your device storage to be able to download files and media.", + this); + checkPhoneStatePermission(this); } super.onCreate(savedInstanceState); @@ -120,9 +128,61 @@ public class MainActivity extends Activity implements DefaultHardwareBackBtnHand finish(); } break; + + case PHONE_STATE_PERMISSION_REQ_CODE: + if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + // Permission granted + acquireDeviceId(this); + } else { + // Permission not granted. Simply show a message. + Toast.makeText(this, + "No permission granted to read your device state. Rewards cannot be claimed.", Toast.LENGTH_LONG).show(); + } + break; } } + public static String acquireDeviceId(Context context) { + TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); + String id = null; + try { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + id = telephonyManager.getImei(); // GSM + if (id == null) { + id = telephonyManager.getMeid(); // CDMA + } + } else { + id = telephonyManager.getDeviceId(); + } + + } catch (SecurityException ex) { + // Maybe the permission was not granted? Try to acquire permission + checkPhoneStatePermission(context); + } catch (Exception ex) { + // id could not be obtained. Display a warning that rewards cannot be claimed. + } + + if (id == null || id.trim().length() == 0) { + Toast.makeText(context, "Rewards cannot be claimed because we could not identify your device.", Toast.LENGTH_LONG).show(); + } + + try { + MessageDigest md = MessageDigest.getInstance("SHA-384"); + md.update(id.getBytes("UTF-8")); + String hash = new BigInteger(1, md.digest()).toString(16); + + SharedPreferences sp = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE); + SharedPreferences.Editor editor = sp.edit(); + editor.putString(DEVICE_ID_KEY, hash); + editor.commit(); + } catch (NoSuchAlgorithmException | UnsupportedEncodingException ex) { + // SHA-384 not found, UTF-8 encoding not supported + Toast.makeText(context, "Rewards cannot be claimed because we could not identify your device.", Toast.LENGTH_LONG).show(); + } + + return id; + } + @Override public void invokeDefaultOnBackPressed() { super.onBackPressed(); @@ -188,6 +248,26 @@ public class MainActivity extends Activity implements DefaultHardwareBackBtnHand super.onNewIntent(intent); } + private static void checkPermission(String permission, int requestCode, String rationale, Context context) { + if (ContextCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) { + // Should we show an explanation? + if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, permission)) { + Toast.makeText(context, rationale, Toast.LENGTH_LONG).show(); + } else { + ActivityCompat.requestPermissions((Activity) context, new String[] { permission }, requestCode); + } + } + } + + private static void checkPhoneStatePermission(Context context) { + // Request read phone state permission + checkPermission(Manifest.permission.READ_PHONE_STATE, + PHONE_STATE_PERMISSION_REQ_CODE, + "LBRY requires optional access to be able to identify your device for rewards. " + + "You cannot claim rewards without this permission.", + context); + } + private boolean isServiceRunning(Class serviceClass) { ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); for (ActivityManager.RunningServiceInfo serviceInfo : manager.getRunningServices(Integer.MAX_VALUE)) {