fr.shywim.antoinedaniel.utils.Utils.java Source code

Java tutorial

Introduction

Here is the source code for fr.shywim.antoinedaniel.utils.Utils.java

Source

/*
 * Copyright (c) 2015 Matthieu Harl
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

package fr.shywim.antoinedaniel.utils;

import android.content.ContentValues;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Handler;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.RelativeLayout;

import com.crashlytics.android.Crashlytics;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.games.Games;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import fr.shywim.antoinedaniel.R;
import fr.shywim.antoinedaniel.provider.ProviderConstants;
import fr.shywim.antoinedaniel.provider.ProviderContract;
import fr.shywim.antoinedaniel.sync.AppState;

public class Utils {
    public GoogleApiClient apiClient;

    public final String SKU_DONATE = "donate100";

    public int totalSoundCount = 0;
    public int downloadedSoundCount = 0;

    public boolean animEnabled = true;
    public boolean taskRunning = false;
    public boolean soundPlaying = false;
    public boolean looping = false;
    public boolean explicitlySignedOut = false;
    public boolean signInFlowStarted = false;

    // Animations
    public static final RotateAnimation ventiloRotate = new RotateAnimation(0f, -359f, Animation.RELATIVE_TO_SELF,
            0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
    static {
        ventiloRotate.setRepeatMode(Animation.RESTART);
        ventiloRotate.setRepeatCount(Animation.INFINITE);
        ventiloRotate.setDuration(1000);
        ventiloRotate.setInterpolator(new LinearInterpolator());
    }
    public static final AlphaAnimation fadeInAnim = new AlphaAnimation(0f, 1f);
    static {
        fadeInAnim.setDuration(200);
        fadeInAnim.setFillAfter(true);
        fadeInAnim.setInterpolator(new LinearInterpolator());
    }
    public static final AlphaAnimation fadeOutAnim = new AlphaAnimation(1f, 0f);
    static {
        fadeOutAnim.setDuration(200);
        fadeOutAnim.setFillAfter(true);
        fadeOutAnim.setInterpolator(new LinearInterpolator());
    }

    public Random random = new Random();

    private static final Utils INSTANCE = new Utils();

    private Utils() {
    }

    public static Utils getInstance() {
        return INSTANCE;
    }

    /**
     * First part of the click animation.
     *
     * @param context Any context.
     * @param v View who will have the effect.
     * @param isRoot Whether the passed view is the ViewGroup parent.
     */
    public static void clickAnimDown(Context context, View v, boolean isRoot) {
        RelativeLayout root;
        if (isRoot)
            root = (RelativeLayout) v;
        else
            root = (RelativeLayout) v.getParent();
        final View rectView = new View(context);
        rectView.setId(R.id.rect_view_id);
        rectView.setVisibility(View.GONE);
        rectView.setBackgroundResource(R.drawable.square);
        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(v.getMeasuredWidth(),
                v.getMeasuredHeight());
        params.addRule(RelativeLayout.ALIGN_TOP, v.getId());
        rectView.setLayoutParams(params);
        AlphaAnimation rectAnim = new AlphaAnimation(0f, 0.4f);
        rectAnim.setFillAfter(true);
        rectAnim.setInterpolator(new AccelerateInterpolator());
        rectAnim.setDuration(150);
        rectAnim.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
                rectView.setVisibility(View.VISIBLE);
            }

            @Override
            public void onAnimationEnd(Animation animation) {

            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });
        root.addView(rectView);
        rectView.startAnimation(rectAnim);
    }

    /**
     * Second part of the click animation.
     *
     * @param v View who will have the effect.
     * @param isRoot Whether the passed view is the ViewGroup parent.
     */
    public static void clickAnimUp(View v, boolean isRoot) {
        RelativeLayout root;
        if (isRoot)
            root = (RelativeLayout) v;
        else
            root = (RelativeLayout) v.getParent();
        final View rectView = root.findViewById(R.id.rect_view_id);
        if (rectView != null) {
            AlphaAnimation rectAnim = new AlphaAnimation(0.4f, 0f);
            rectAnim.setFillAfter(true);
            rectAnim.setInterpolator(new DecelerateInterpolator());
            rectAnim.setDuration(150);
            rectAnim.setAnimationListener(new Animation.AnimationListener() {
                @Override
                public void onAnimationStart(Animation animation) {

                }

                @Override
                public void onAnimationEnd(Animation animation) {
                    new Handler().post(new Runnable() {
                        @Override
                        public void run() {
                            ViewGroup parent = (ViewGroup) rectView.getParent();
                            rectView.setVisibility(View.GONE);
                            if (parent != null)
                                parent.removeView(rectView);
                        }
                    });
                }

                @Override
                public void onAnimationRepeat(Animation animation) {

                }
            });
            rectView.clearAnimation();
            rectView.startAnimation(rectAnim);
        }
    }

    /**
     * Delete the application's cache directory.
     *
     * @param context application's context
     * @return whether the directory has been successfully deleted or not
     */
    public static boolean deleteCacheDir(Context context) {
        try {
            File dir = context.getCacheDir();
            if (dir != null && dir.isDirectory()) {
                return deleteDir(dir);
            }
        } catch (Exception e) {
            Crashlytics.logException(e);
        }
        return false;
    }

    /**
     * Delete a directory.
     *
     * @param dir the directory to delete
     * @return whether the directory has been successfully deleted or not
     */
    @SuppressWarnings("ObjectAllocationInLoop")
    public static boolean deleteDir(File dir) {
        String[] children = dir.list();
        if (children != null) {
            for (String aChildren : children) {
                File file = new File(dir, aChildren);
                //noinspection ResultOfMethodCallIgnored
                file.delete();
            }
        }
        return dir.delete();
    }

    /**
     * Copy a file from one place (src) to another (dst).
     *
     * @param src Source File.
     * @param dst Destination File.
     * @throws IOException
     */
    public static void copy(File src, File dst) throws IOException {
        InputStream in = new FileInputStream(src);
        OutputStream out = new FileOutputStream(dst);

        // Transfer bytes from in to out
        byte[] buf = new byte[1024];
        int len;
        while ((len = in.read(buf)) > 0) {
            out.write(buf, 0, len);
        }
        in.close();
        out.close();
    }

    public static boolean getInformationFromCdn(Context context, String soundname, String page, boolean force) {
        List<NameValuePair> nameValuePairs = new ArrayList<>(1);
        nameValuePairs.add(new BasicNameValuePair("sound_id", soundname));
        nameValuePairs.add(new BasicNameValuePair("page", page));
        String paramString = URLEncodedUtils.format(nameValuePairs, "utf-8");
        String url = context.getResources().getString(R.string.api_get_one_sound) + '?' + paramString;
        final HttpClient httpclient = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet(url);
        try {
            HttpResponse response = httpclient.execute(httpGet);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                String result = EntityUtils.toString(response.getEntity());
                JSONObject jo = new JSONObject(result);
                if (!prepareDownloadFromCdn(context, jo.getString("soundname"), jo.getString("imagename"),
                        jo.getString("description"), jo.getString("link"),
                        Integer.parseInt(jo.getString("version")), force)) {
                    return false;
                } else
                    jo.getString("version");
            }
        } catch (IOException | JSONException e) {
            Crashlytics.logException(e);
        }
        return true;
    }

    public static boolean prepareDownloadFromCdn(Context context, String soundName, String imageName,
            String description, String link, int version, boolean force) throws IOException {
        String extImgPath = context.getExternalFilesDir(null) + "/img/";
        String extSndPath = context.getExternalFilesDir(null) + "/snd/";

        File sndDir = new File(context.getExternalFilesDir(null) + "/snd");
        if (!sndDir.exists())
            if (!sndDir.mkdirs())
                return false;
        File imgDir = new File(context.getExternalFilesDir(null) + "/img");
        if (!imgDir.exists())
            if (!imgDir.mkdirs())
                return false;

        File file = new File(extSndPath + soundName + ".ogg");
        if (!downloadFileFromCdn(context, file, soundName, "snd/", ".ogg", force)) {
            //noinspection ResultOfMethodCallIgnored
            file.delete();
            return false;
        }

        file = new File(extImgPath + imageName + ".jpg");
        if (!downloadFileFromCdn(context, file, imageName, "img/", ".jpg", force)) {
            //noinspection ResultOfMethodCallIgnored
            file.delete();
            return false;
        }

        Uri uri = Uri.withAppendedPath(ProviderConstants.SOUND_NAME_URI, soundName);
        ContentValues cv = new ContentValues();
        cv.put(ProviderContract.SoundEntry.COLUMN_SOUND_NAME, soundName);
        cv.put(ProviderContract.SoundEntry.COLUMN_IMAGE_NAME, imageName);
        cv.put(ProviderContract.SoundEntry.COLUMN_DESC, description);
        cv.put(ProviderContract.SoundEntry.COLUMN_LINK, link);
        cv.put(ProviderContract.SoundEntry.COLUMN_NAME_VERSION, version);
        if (uri != null) {
            context.getContentResolver().update(uri, cv, null, null);
            return true;
        } else
            return false;
    }

    /**
     * Download a file from the CDN server.
     * (Note to self: all last three params could be determined by {@link java.io.File#getPath})
     * @param context Any context.
     * @param dst Local {@link java.io.File} to save.
     * @param fileName Name of the distant file to download.
     * @param folder Folder of the distant file to download.
     * @param ext Extension of the distant file to download.
     * @return true if file has been successfully downloaded, false in any other case.
     */
    public static boolean downloadFileFromCdn(Context context, File dst, String fileName, String folder, String ext,
            boolean force) throws IOException {
        int count;
        InputStream input;
        FileOutputStream output;
        final String cdnLink = context.getResources().getString(R.string.cdn_link);

        if (force || !dst.exists()) {
            if (force || dst.createNewFile()) {
                URL url = new URL(cdnLink + folder + fileName + ext);
                input = new BufferedInputStream(url.openStream(), 4096);
                byte data[] = new byte[2048];
                output = new FileOutputStream(dst);
                while ((count = input.read(data)) != -1) {
                    output.write(data, 0, count);
                }
                output.flush();
                input.close();
                output.close();
            } else {
                return false;
            }
        }
        return true;
    }

    /**
     * Check if an internet connection is available
     *
     * @param context activity's context
     * @return true if a connection is available
     */
    public static boolean isNetworkAvailable(Context context) {
        ConnectivityManager connectivityManager = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
        return activeNetworkInfo != null && activeNetworkInfo.isConnectedOrConnecting();
    }

    /**
     * Unlock an achievement if it is not already unlocked
     *
     * @param context Any context.
     * @param resid Achievement's id.
     */
    public void unlockAchievement(Context context, int resid) {
        String id = context.getString(resid);
        if (apiClient != null && this.apiClient.isConnected()) {
            AnalyticsUtils.sendEvent(context.getString(R.string.ana_cat_game),
                    context.getString(R.string.ana_act_unique_achiev), id);
            Games.Achievements.unlock(apiClient, id);
        }
    }

    /**
     * Increment an achievement.
     *
     * @param context Any context.
     * @param resid Achievement's id.
     */
    public void incrementAchievement(Context context, int resid) {
        String id = context.getString(resid);
        if (apiClient != null && apiClient.isConnected()) {
            Games.Achievements.increment(apiClient, id, 1);
        }
    }

    /**
     * Send a score only if it beats the user's best.
     *
     * @param context Any context.
     * @param resid Leaderboard's id.
     * @param score Player's score.
     */
    public void sendScore(Context context, int resid, long score) {
        AppState appState = AppState.getInstance();
        String id = context.getString(resid);
        if (apiClient != null && this.apiClient.isConnected() && (!AppState.getInstance().bestScores.containsKey(id)
                || (Long.parseLong(AppState.getInstance().bestScores.get(id)) < score))) {
            appState.bestScores.put(id, Long.toString(score));
            appState.changed = true;
            Games.Leaderboards.submitScore(apiClient, id, score);
        }
    }

    /**
     * @return Application's version code from the {@code PackageManager}.
     */
    public static int getAppVersion(Context context) {
        try {
            PackageManager manager = context.getPackageManager();
            PackageInfo packageInfo = null;
            if (manager != null)
                packageInfo = manager.getPackageInfo(context.getPackageName(), 0);
            int version = 0;
            if (packageInfo != null)
                version = packageInfo.versionCode;
            return version;
        } catch (PackageManager.NameNotFoundException e) {
            // should never happen
            throw new RuntimeException("Could not get package name: " + e);
        }
    }
}