package com.heyzap.sdk; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.URL; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import android.content.Context; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ResolveInfo; import android.content.pm.Signature; import android.graphics.Bitmap; import android.graphics.Rect; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.Uri; import android.os.Build; import android.os.Handler; import android.provider.Settings; import android.util.Log; import android.view.TouchDelegate; import android.view.View; class Utils { public static final String HEYZAP_PACKAGE = "com.heyzap.android"; private static final int LEADERBOARD_VERSION = 4006006; private static final int ACHIEVEMENTS_VERSION = 4012001; public static final int GAME_DETAILS_PACKAGE_VERSION = 4012002; // first version to support sending game_package in Intent extras to GameDetails private static float density = -1; static ExecutorService requestThread = Executors.newSingleThreadExecutor(); private static String deviceId = "unknown"; private static String packageName = "unknown"; private static HashMap<String, String> extraParams; public static String capitalize(String s) { return s.substring(0, 1).toUpperCase() + s.substring(1); } public static String truncate(String s, int limit) { if (s.length() > limit) { s = s.substring(0, limit) + "..."; } return s; } public static String getAppLabel(Context context) { CharSequence label = null; try { label = context.getPackageManager().getApplicationLabel(context.getPackageManager().getApplicationInfo(context.getPackageName(), 0)); } catch (NameNotFoundException e) { } return label == null ? null : label.toString(); } public static int daysBetween(Date d1, Date d2) { return Math.abs((int) ((d1.getTime() - d2.getTime()) / (60 * 60 * 24 * 1000))); } // Ensure the android market is installed public static boolean marketInstalled(Context context) { try { Intent marketIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=com.heyzap.android")); List<ResolveInfo> resolveInfo = context.getPackageManager().queryIntentActivities(marketIntent, PackageManager.MATCH_DEFAULT_ONLY); if (resolveInfo.isEmpty()) { return false; } } catch (Exception e) { return false; } return true; } static void load(Context context) { getDeviceId(context); // precache } public static String getPackageName(Context context) { if (packageName.equals("unknown") && context != null) { packageName = context.getPackageName(); } return packageName; } public static String getDeviceId(Context context) { if (deviceId.equals("unknown") && context != null) { // Load up the device id String product = Build.PRODUCT; String androidId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID); if (product != null && androidId != null) { deviceId = product + "_" + androidId; } } return deviceId; } // Check if the android version is high enough for the heyzap app public static boolean androidVersionSupported() { try { if (Integer.parseInt(Build.VERSION.SDK) < 7) { return false; } } catch (Exception e) { return false; } return true; } static void post(final String endpoint, final String postData, final ResponseHandler handler) { Handler uiHandlerTemp = null; try { uiHandlerTemp = new Handler(); } catch (RuntimeException e) { // ignore } final Handler uiHandler = uiHandlerTemp; requestThread.execute(new Runnable() { @Override public void run() { Throwable error = null; String response = null; try { // Open the connection URL url = new URL(endpoint); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); try { // Set up the connection conn.setDoOutput(true); // Write the post data to the stream OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream()); out.write(postData); out.flush(); out.close(); // Get the response response = convertStreamToString(conn.getInputStream()).trim(); if (handler != null) handler.onSuccess(response); } catch (IOException e) { // Ignore any file stream issues if (handler != null) handler.onFailure(e); } finally { conn.disconnect(); } } catch (IOException e) { // Ignore any connection failure when trying to open the // connection if (handler != null) handler.onFailure(e); } catch (UnsupportedOperationException e) { // Ignore any url building issues if (handler != null) handler.onFailure(e); } final Throwable fError = error; final String fResponse = response; Runnable post = new Runnable() { @Override public void run() { } }; } }); } private static String convertStreamToString(InputStream is) { BufferedReader reader = new BufferedReader(new InputStreamReader(is)); StringBuilder sb = new StringBuilder(); String line = null; try { while ((line = reader.readLine()) != null) { sb.append(line + "\n"); } } catch (IOException e) { e.printStackTrace(); } finally { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } return sb.toString(); } static HashMap<String, String> extraParams(Context context) { if (extraParams == null) { extraParams = new HashMap<String, String>(); extraParams.put("sdk_version", HeyzapAnalytics.HEYZAP_SDK_VERSION); extraParams.put("sdk_platform", HeyzapAnalytics.HEYZAP_SDK_PLATFORM); extraParams.put("android_version", Build.VERSION.SDK); extraParams.put("game_package", getPackageName(context)); extraParams.put("device_id", getDeviceId(context)); } return extraParams; } public static int dpToPx(Context context, int dp) { density = density > 0 ? density : context.getResources().getDisplayMetrics().density; return (int) (dp * density + 0.5f); } public static String getSignatureHash(Context context) { String hash = ""; try { Signature[] signatures = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES).signatures; byte[] sig = signatures[0].toByteArray(); hash = Base64.encodeToString(MessageDigest.getInstance("SHA-1").digest(sig), Base64.NO_WRAP); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (NameNotFoundException e) { e.printStackTrace(); } return hash; } public static String getAbsolutePath(Context context, String fileName) { return String.format("%s/files/%s", context.getCacheDir().getAbsolutePath(), fileName); } public static String saveBitmapToLocalFile(Context context, String fileName, Bitmap image) { try { if (fileName == null) throw new Exception("No filename."); if (image == null) throw new Exception("No image."); String absolutePath = getAbsolutePath(context, fileName); ByteArrayOutputStream bs = new ByteArrayOutputStream(); image.compress(Bitmap.CompressFormat.PNG, 0, bs); FileOutputStream outputStream = context.openFileOutput(fileName, Context.MODE_WORLD_READABLE | Context.MODE_WORLD_WRITEABLE); if (outputStream != null) { outputStream.write(bs.toByteArray()); } else { throw new Exception("Unable to open output file stream."); } return absolutePath; } catch (Exception e) { e.printStackTrace(); return null; } } public static int getScaledSize(Context context, int baseSize) { return getScaledSize(context, (float) baseSize); } public static int getScaledSize(Context context, float baseSize) { if (density <= 0) { density = context.getResources().getDisplayMetrics().density; } return (int) (density * baseSize); } public static int getInverseScaledSize(Context context, int pixels) { return getInverseScaledSize(context, (float) pixels); } public static int getInverseScaledSize(Context context, float pixels) { if (density <= 0) { density = context.getResources().getDisplayMetrics().density; } return (int) (pixels / density); } // wrapper is a view. inner is its only child, usually a button. inner has // click/touch listeners. this will make all clicks/touches on wrapper get // passed through to inner. even pressed states will work! public static void clickWrap(final Context context, final View wrapper, final View inner, final int extraPaddingDpTop, final int extraPaddingDpRight, final int extraPaddingDpBottom, final int extraPaddingDpLeft) { if (wrapper != null) { wrapper.post(new Runnable() { public void run() { final Rect r = new Rect(); wrapper.getHitRect(r); r.top -= Utils.getScaledSize(context, extraPaddingDpTop); r.right += Utils.getScaledSize(context, extraPaddingDpRight); r.bottom += Utils.getScaledSize(context, extraPaddingDpBottom); r.left -= Utils.getScaledSize(context, extraPaddingDpLeft); wrapper.setTouchDelegate(new TouchDelegate(r, inner)); } }); } } public static void clickWrap(Context context, View wrapper, View inner) { clickWrap(context, wrapper, inner, 0); } public static void clickWrap(Context context, View wrapper, View inner, int extraPaddingDp) { clickWrap(context, wrapper, inner, extraPaddingDp, extraPaddingDp, extraPaddingDp, extraPaddingDp); } static interface ResponseHandler { public void onSuccess(String response); public void onFailure(Throwable e); } static boolean heyzapIsInstalled(Context context) { return packageIsInstalled(HEYZAP_PACKAGE, context); } static int heyzapVersion(Context context) { PackageInfo pInfo; try { pInfo = context.getPackageManager().getPackageInfo(HEYZAP_PACKAGE, 0); int version = pInfo.versionCode; return version; } catch (NameNotFoundException e) { e.printStackTrace(); return -1; } } // true if Heyzap is installed and is new enough version to support // Leaderboards static boolean hasHeyzapLeaderboards(Context context) { return heyzapIsInstalled(context) && heyzapVersion(context) >= LEADERBOARD_VERSION; } // true if Heyzap is installed and is new enough version to support Leaderboards static boolean hasHeyzapAchievements(Context context) { return heyzapIsInstalled(context) && heyzapVersion(context) >= ACHIEVEMENTS_VERSION; } static boolean packageIsInstalled(String packageName, Context context) { boolean installed = false; try { PackageManager pm = context.getPackageManager(); Intent pi = pm.getLaunchIntentForPackage(packageName); if (pi != null) { List<ResolveInfo> list = pm.queryIntentActivities(pi, PackageManager.MATCH_DEFAULT_ONLY); if (list.size() > 0) { installed = true; } } } catch (Exception e) { } return installed; } private static boolean isAirplaneModeOn(Context context) { return Settings.System.getInt(context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 0) != 0; } public static boolean isOnline(Context context) { ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE); return (cm.getActiveNetworkInfo() != null && cm.getActiveNetworkInfo().isConnectedOrConnecting()) && !isAirplaneModeOn(context); } public static String hex(byte[] array) { StringBuffer sb = new StringBuffer(); for (int i = 0; i < array.length; ++i) { sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1,3)); } return sb.toString(); } public static String md5Hex(String message) { try { MessageDigest md = MessageDigest.getInstance("MD5"); return hex (md.digest(message.getBytes("CP1252"))); } catch (NoSuchAlgorithmException e) { } catch (UnsupportedEncodingException e) { } return null; } public static void installHeyzap(Context context, String additionalAnalyticsParam) { // Launch the android market String uri = String.format("market://details?id=%s&referrer=%s", HeyzapLib.HEYZAP_PACKAGE, HeyzapAnalytics.getAnalyticsReferrer(context, additionalAnalyticsParam)); Log.d("HeyzapSDK", "Sending player to market, uri: " + uri); Intent popup = new Intent(Intent.ACTION_VIEW, Uri.parse(uri)); popup.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK); context.startActivity(popup); } }