com.fairphone.updater.UpdaterService.java Source code

Java tutorial

Introduction

Here is the source code for com.fairphone.updater.UpdaterService.java

Source

/*
 * Copyright (C) 2013 Fairphone Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.fairphone.updater;

import android.app.DownloadManager;
import android.app.DownloadManager.Request;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.app.TaskStackBuilder;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.BitmapFactory;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.os.Environment;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

public class UpdaterService extends Service {

    private static final String TAG = UpdaterService.class.getSimpleName();
    private static final String PREFERENCE_DATE_LAST_TIME_CHECKED = "LastTimeUpdateChecked";
    private DownloadManager mDownloadManager;
    private DownloadBroadCastReceiver mDownloadBroadCastReceiver;

    private long mLatestFileDownloadId;

    private SharedPreferences mSharedPreferences;
    private SimpleDateFormat mDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss", Locale.getDefault());

    final static long DAY_IN_MILLIS = 1000 * 60 * 60 * 24;
    private static final int MAX_DAYS_BEFORE_CHECKING = 8;

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        mSharedPreferences = getApplicationContext()
                .getSharedPreferences(FairphoneUpdater.FAIRPHONE_UPDATER_PREFERENCES, MODE_PRIVATE);

        if (isFileStillValid()) {
            checkVersionValidation(getApplicationContext());
        } else if (hasInternetConnection()) {
            // remove the old file if its still there for some reason
            removeLatestFile(getApplicationContext());

            setupDownloadManager();

            // start the download of the latest file
            startDownloadLatest();
        }

        return Service.START_NOT_STICKY;
    }

    private void removeLatestFile(Context context) {
        VersionParserHelper.removeFiles(context);

        updateLastChecked("2013.01.01 00:00:00");
    }

    private boolean isFileStillValid() {
        Date lastTimeChecked = getLastTimeCheckedDate();

        int diffInDays = (int) ((System.currentTimeMillis() - lastTimeChecked.getTime()) / DAY_IN_MILLIS);

        return diffInDays < MAX_DAYS_BEFORE_CHECKING;
    }

    private Date getLastTimeCheckedDate() {

        String lastTimeDatePreference = mSharedPreferences.getString(PREFERENCE_DATE_LAST_TIME_CHECKED,
                "2013.01.01 00:00:00");

        Date lastTimeDate = null;
        try {
            lastTimeDate = mDateFormat.parse(lastTimeDatePreference);
        } catch (ParseException e) {
            Calendar cal = Calendar.getInstance();
            cal.add(Calendar.YEAR, -1);

            lastTimeDate = cal.getTime();
        }

        return lastTimeDate;
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    public void startDownloadLatest() {
        Resources resources = getApplicationContext().getResources();

        // set the download for the latest version on the download manager
        Request request = createDownloadRequest(resources.getString(R.string.downloadUrl),
                resources.getString(R.string.versionFilename) + resources.getString(R.string.versionFilename_zip));
        mLatestFileDownloadId = mDownloadManager.enqueue(request);
    }

    private void setNotification() {

        Context context = getApplicationContext();

        NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

        NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
                .setSmallIcon(R.drawable.fairphone_updater_tray_icon_small)
                .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.fairphone_updater_tray_icon))
                .setContentTitle(context.getResources().getString(R.string.app_name))
                .setContentText(getResources().getString(R.string.fairphoneUpdateMessage));

        Intent resultIntent = new Intent(context, FairphoneUpdater.class);
        TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);

        stackBuilder.addParentStack(FairphoneUpdater.class);

        stackBuilder.addNextIntent(resultIntent);
        PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);

        builder.setContentIntent(resultPendingIntent);

        Notification notificationWhileRunnig = builder.build();

        // Add notification
        manager.notify(0, notificationWhileRunnig);

    }

    private Request createDownloadRequest(String url, String fileName) {

        Request request = new Request(Uri.parse(url));
        Environment.getExternalStoragePublicDirectory(
                Environment.getExternalStorageDirectory() + VersionParserHelper.UPDATER_FOLDER).mkdirs();

        request.setDestinationInExternalPublicDir(VersionParserHelper.UPDATER_FOLDER, fileName);
        request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);
        request.setAllowedOverRoaming(false);

        Resources resources = getApplicationContext().getResources();
        request.setTitle(resources.getString(R.string.downloadUpdateTitle));

        return request;
    }

    private boolean hasInternetConnection() {

        ConnectivityManager manager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

        boolean is3g = manager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).isConnectedOrConnecting();

        boolean isWifi = manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI).isConnectedOrConnecting();

        return isWifi || is3g;
    }

    private void setupDownloadManager() {
        mDownloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);

        mDownloadBroadCastReceiver = new DownloadBroadCastReceiver();

        getApplicationContext().registerReceiver(mDownloadBroadCastReceiver,
                new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
    }

    private void removeBroadcastReceiver() {
        getApplicationContext().unregisterReceiver(mDownloadBroadCastReceiver);
    }

    private void checkVersionValidation(Context context) {

        Version latestVersion = VersionParserHelper.getLastestVersion(getApplicationContext());
        Version currentVersion = VersionParserHelper.getDeviceVersion(getApplicationContext());

        if (latestVersion != null) {

            String versionName = null;
            String versionNumber = null;
            String versionUrl = null;
            String versionMd5 = null;
            String versionAndroid = null;

            if (latestVersion.isNewerVersionThan(currentVersion)) {
                // save the version in the share preferences
                versionName = latestVersion.getName();
                versionNumber = latestVersion.getNumber();
                versionUrl = latestVersion.getDownloadLink();
                versionMd5 = latestVersion.getMd5Sum();
                versionAndroid = latestVersion.getAndroid();

                setNotification();
            } else {
                VersionParserHelper.removeLatestVersionFile(getApplicationContext());
            }

            Editor editor = mSharedPreferences.edit();

            editor.putString(FairphoneUpdater.PREFERENCE_NEW_VERSION_NAME, versionName);
            editor.putString(FairphoneUpdater.PREFERENCE_NEW_VERSION_NUMBER, versionNumber);
            editor.putString(FairphoneUpdater.PREFERENCE_NEW_VERSION_MD5_SUM, versionMd5);
            editor.putString(FairphoneUpdater.PREFERENCE_NEW_VERSION_URL, versionUrl);
            editor.putString(FairphoneUpdater.PREFERENCE_NEW_VERSION_ANDROID, versionAndroid);

            editor.commit();

            removeLatestFileDownload(context);
        }
    }

    private void removeLatestFileDownload(Context context) {
        if (mLatestFileDownloadId != 0) {
            mDownloadManager.remove(mLatestFileDownloadId);
            mLatestFileDownloadId = 0;
        }
        VersionParserHelper.removeFiles(context);
    }

    private float parseVersion(String number) {
        String finalNumber = number.replaceAll("\\.", "");
        return Float.parseFloat(finalNumber);
    }

    private void updateLastChecked(String date) {
        Editor editor = mSharedPreferences.edit();
        editor.putString(PREFERENCE_DATE_LAST_TIME_CHECKED, date);

        editor.commit();
    }

    private class DownloadBroadCastReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            DownloadManager.Query query = new DownloadManager.Query();

            query.setFilterById(mLatestFileDownloadId);
            Cursor cursor = mDownloadManager.query(query);

            if (cursor.moveToFirst()) {
                int columnIndex = cursor.getColumnIndex(DownloadManager.COLUMN_STATUS);
                int status = cursor.getInt(columnIndex);

                if (status == DownloadManager.STATUS_SUCCESSFUL) {

                    String filePath = mDownloadManager.getUriForDownloadedFile(mLatestFileDownloadId).getPath();

                    String targetPath = Environment.getExternalStorageDirectory()
                            + VersionParserHelper.UPDATER_FOLDER;

                    if (RSAUtils.checkFileSignature(context, filePath, targetPath)) {
                        updateLastChecked(mDateFormat.format(Calendar.getInstance().getTime()));
                        checkVersionValidation(context);
                    } else {
                        //invalid file
                        removeLatestFileDownload(context);
                    }
                }
            }

            cursor.close();

            removeBroadcastReceiver();
        }
    }
}