org.noise_planet.noisecapture.MainActivity.java Source code

Java tutorial

Introduction

Here is the source code for org.noise_planet.noisecapture.MainActivity.java

Source

/*
 * This file is part of the NoiseCapture application and OnoMap system.
 *
 * The 'OnoMaP' system is led by Lab-STICC and Ifsttar and generates noise maps via
 * citizen-contributed noise data.
 *
 * This application is co-funded by the ENERGIC-OD Project (European Network for
 * Redistributing Geospatial Information to user Communities - Open Data). ENERGIC-OD
 * (http://www.energic-od.eu/) is partially funded under the ICT Policy Support Programme (ICT
 * PSP) as part of the Competitiveness and Innovation Framework Programme by the European
 * Community. The application work is also supported by the French geographic portal GEOPAL of the
 * Pays de la Loire region (http://www.geopal.org).
 *
 * Copyright (C) IFSTTAR - LAE and Lab-STICC  CNRS UMR 6285 Equipe DECIDE Vannes
 *
 * NoiseCapture is a free software; you can redistribute it and/or modify it under the terms of the
 * GNU General Public License as published by the Free Software Foundation; either version 3 of
 * the License, or(at your option) any later version. NoiseCapture is distributed in the hope that
 * it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.You should have received a copy of the GNU General Public License along with this
 * program; if not, write to the Free Software Foundation,Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301  USA or see For more information,  write to Ifsttar,
 * 14-20 Boulevard Newton Cite Descartes, Champs sur Marne F-77447 Marne la Vallee Cedex 2 FRANCE
 *  or write to scientific.computing@ifsttar.fr
 */

package org.noise_planet.noisecapture;

import android.Manifest;
import android.app.Activity;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.net.Uri;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.TaskStackBuilder;
import android.support.v4.content.ContextCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.app.AppCompatDelegate;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    static {
        AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
    }
    // Color for noise exposition representation
    public int[] NE_COLORS;
    public static final String RESULTS_RECORD_ID = "RESULTS_RECORD_ID";
    protected static final Logger MAINLOGGER = LoggerFactory.getLogger(MainActivity.class);
    private static final int NOTIFICATION_MAP = R.string.notification_goto_community_map_title;

    // For the list view
    public ListView mDrawerList;
    public DrawerLayout mDrawerLayout;
    public String[] mMenuLeft;
    public ActionBarDrawerToggle mDrawerToggle;
    private ProgressDialog progress;

    public static final int PERMISSION_RECORD_AUDIO_AND_GPS = 1;
    public static final int PERMISSION_WIFI_STATE = 2;
    public static final int PERMISSION_INTERNET = 3;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Resources res = getResources();
        NE_COLORS = new int[] { res.getColor(R.color.R1_SL_level), res.getColor(R.color.R2_SL_level),
                res.getColor(R.color.R3_SL_level), res.getColor(R.color.R4_SL_level),
                res.getColor(R.color.R5_SL_level) };
    }

    /**
     * If necessary request user to acquire permisions for critical ressources (gps and microphone)
     * @return True if service can be bind immediately. Otherwise the bind should be done using the
     * @see #onRequestPermissionsResult
     */
    protected boolean checkAndAskPermissions() {
        if (ContextCompat.checkSelfPermission(this,
                android.Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED
                || ContextCompat.checkSelfPermission(this,
                        Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                    android.Manifest.permission.RECORD_AUDIO)) {
                // After the user
                // sees the explanation, try again to request the permission.
                Toast.makeText(this, R.string.permission_explain_audio_record, Toast.LENGTH_LONG).show();
            }
            if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                    android.Manifest.permission.ACCESS_FINE_LOCATION)) {
                // After the user
                // sees the explanation, try again to request the permission.
                Toast.makeText(this, R.string.permission_explain_gps, Toast.LENGTH_LONG).show();
            }
            // Request the permission.
            ActivityCompat.requestPermissions(this, new String[] { android.Manifest.permission.RECORD_AUDIO,
                    android.Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION },
                    PERMISSION_RECORD_AUDIO_AND_GPS);
            return false;
        }
        return true;
    }

    @Override
    protected void onPause() {
        if (progress != null && progress.isShowing()) {
            try {
                progress.dismiss();
            } catch (IllegalArgumentException ex) {
                //Ignore
            }
        }
        super.onPause();
    }

    /**
     * @return Version information on this application
     * @throws PackageManager.NameNotFoundException
     */
    public static String getVersionString(Activity activity) throws PackageManager.NameNotFoundException {
        String versionName = activity.getPackageManager().getPackageInfo(activity.getPackageName(), 0).versionName;
        Date buildDate = new Date(BuildConfig.TIMESTAMP);
        String gitHash = BuildConfig.GITHASH;
        if (gitHash == null || gitHash.isEmpty()) {
            gitHash = "";
        } else {
            gitHash = gitHash.substring(0, 7);
        }
        return activity.getString(R.string.title_appversion, versionName,
                DateFormat.getDateInstance().format(buildDate), gitHash);
    }

    /**
     * If necessary request user to acquire permisions for critical ressources (gps and microphone)
     * @return True if service can be bind immediately. Otherwise the bind should be done using the
     * @see #onRequestPermissionsResult
     */
    protected boolean checkAndAskWifiStatePermission() {
        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_WIFI_STATE) != PackageManager.PERMISSION_GRANTED) {
            if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                    android.Manifest.permission.ACCESS_WIFI_STATE)) {
                // After the user
                // sees the explanation, try again to request the permission.
                Toast.makeText(this, R.string.permission_explain_access_wifi_state, Toast.LENGTH_LONG).show();
            }
            // Request the permission.
            ActivityCompat.requestPermissions(this, new String[] { android.Manifest.permission.ACCESS_WIFI_STATE },
                    PERMISSION_WIFI_STATE);
            return false;
        }
        return true;
    }

    void initDrawer(Integer recordId) {
        try {
            // List view
            mMenuLeft = getResources().getStringArray(R.array.dm_list_array);
            mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
            mDrawerList = (ListView) findViewById(R.id.left_drawer);
            // Set the adapter for the list view
            mDrawerList.setAdapter(new ArrayAdapter<String>(this, R.layout.drawer_list_item, mMenuLeft));
            // Set the list's click listener
            mDrawerList.setOnItemClickListener(new DrawerItemClickListener(recordId));
            // Display the List view into the action bar
            mDrawerToggle = new ActionBarDrawerToggle(this, /* host Activity */
                    mDrawerLayout, /* DrawerLayout object */
                    R.string.drawer_open, /* "open drawer" description */
                    R.string.drawer_close /* "close drawer" description */
            ) {
                /**
                 * Called when a drawer has settled in a completely closed state.
                 */
                public void onDrawerClosed(View view) {
                    super.onDrawerClosed(view);
                    getSupportActionBar().setTitle(getTitle());
                }

                /**
                 * Called when a drawer has settled in a completely open state.
                 */
                public void onDrawerOpened(View drawerView) {
                    super.onDrawerOpened(drawerView);
                    getSupportActionBar().setTitle(getString(R.string.title_menu));
                }
            };
            // Set the drawer toggle as the DrawerListener
            mDrawerLayout.setDrawerListener(mDrawerToggle);
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
            getSupportActionBar().setHomeButtonEnabled(true);

        } catch (Exception e) {
            MAINLOGGER.error(e.getLocalizedMessage(), e);
        }
    }

    // Drawer navigation
    void initDrawer() {
        initDrawer(null);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public void onBackPressed() {
        if (!(this instanceof MeasurementActivity)) {
            if (mDrawerLayout != null) {
                mDrawerLayout.closeDrawer(mDrawerList);
            }
            Intent im = new Intent(getApplicationContext(), MeasurementActivity.class);
            im.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startActivity(im);
            finish();
        } else {
            finish();
            // Show home
            Intent im = new Intent(Intent.ACTION_MAIN);
            im.addCategory(Intent.CATEGORY_HOME);
            im.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(im);
        }
    }

    private class DrawerItemClickListener implements ListView.OnItemClickListener {

        Integer recordId;

        public DrawerItemClickListener(Integer recordId) {
            this.recordId = recordId;
        }

        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

            switch (position) {
            case 0:
                // Measurement
                Intent im = new Intent(getApplicationContext(), MeasurementActivity.class);
                im.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                mDrawerLayout.closeDrawer(mDrawerList);
                startActivity(im);
                finish();
                break;
            case 1:
                // Comment
                Intent ir = new Intent(getApplicationContext(), CommentActivity.class);
                if (recordId != null && recordId >= 0) {
                    ir.putExtra(CommentActivity.COMMENT_RECORD_ID, recordId);
                }
                mDrawerLayout.closeDrawer(mDrawerList);
                startActivity(ir);
                finish();
                break;
            case 2:
                // Results
                ir = new Intent(getApplicationContext(), Results.class);
                if (recordId != null && recordId >= 0) {
                    ir.putExtra(RESULTS_RECORD_ID, recordId);
                }
                mDrawerLayout.closeDrawer(mDrawerList);
                startActivity(ir);
                finish();
                break;
            case 3:
                // History
                Intent a = new Intent(getApplicationContext(), History.class);
                startActivity(a);
                finish();
                mDrawerLayout.closeDrawer(mDrawerList);
                break;
            case 4:
                // Show the map
                Intent imap = new Intent(getApplicationContext(), MapActivity.class);
                if (recordId != null && recordId >= 0) {
                    imap.putExtra(Results.RESULTS_RECORD_ID, recordId);
                }
                startActivity(imap);
                finish();
                mDrawerLayout.closeDrawer(mDrawerList);
                break;
            case 5:
                Intent ics = new Intent(getApplicationContext(), CalibrationActivity.class);
                mDrawerLayout.closeDrawer(mDrawerList);
                startActivity(ics);
                finish();
                break;
            case 6:
                Intent ih = new Intent(getApplicationContext(), ViewHtmlPage.class);
                mDrawerLayout.closeDrawer(mDrawerList);
                ih.putExtra("pagetosee", getString(R.string.url_help));
                ih.putExtra("titletosee", getString(R.string.title_activity_help));
                startActivity(ih);
                finish();
                break;
            case 7:
                Intent ia = new Intent(getApplicationContext(), ViewHtmlPage.class);
                ia.putExtra("pagetosee", getString(R.string.url_about));
                ia.putExtra("titletosee", getString(R.string.title_activity_about));
                mDrawerLayout.closeDrawer(mDrawerList);
                startActivity(ia);
                finish();
                break;
            default:
                break;
            }
        }
    }

    @Override
    public void setTitle(CharSequence title) {
        CharSequence mTitle = title;
        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.setTitle(mTitle);
        }
    }

    @Override
    public void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        // Sync the toggle state after onRestoreInstanceState has occurred.
        if (mDrawerToggle != null) {
            mDrawerToggle.syncState();
        }
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        if (mDrawerToggle != null) {
            mDrawerToggle.onConfigurationChanged(newConfig);
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        if (mDrawerLayout != null) {
            mDrawerLayout.closeDrawers();
        }

        // Pass the event to ActionBarDrawerToggle, if it returns
        // true, then it has handled the app icon touch event
        if (mDrawerToggle != null && mDrawerToggle.onOptionsItemSelected(item)) {
            return true;
        }

        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        // Handle presses on the action bar items
        switch (item.getItemId()) {
        case R.id.action_settings:
            Intent is = new Intent(getApplicationContext(), SettingsActivity.class);
            startActivity(is);
            return true;
        /*
        case R.id.action_about:
            Intent ia = new Intent(getApplicationContext(),ViewHtmlPage.class);
            pagetosee=getString(R.string.url_about);
            titletosee=getString((R.string.title_activity_about));
            startActivity(ia);
            return true;
            */
        default:
            return super.onOptionsItemSelected(item);
        }

    }

    protected boolean isManualTransferOnly() {
        SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
        return !sharedPref.getBoolean("settings_data_transfer", true);
    }

    protected boolean isWifiTransferOnly() {
        SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
        return sharedPref.getBoolean("settings_data_transfer_wifi_only", false);
    }

    /**
     * Check the non-uploaded results and the connection states
     * Upload results if necessary
     */
    protected void checkTransferResults() {
        if (!isManualTransferOnly()) {
            MeasurementManager measurementManager = new MeasurementManager(this);
            if (!measurementManager.hasNotUploadedRecords()) {
                return;
            }
            if (isWifiTransferOnly()) {
                if (checkAndAskWifiStatePermission()) {
                    if (!checkWifiState()) {
                        return;
                    }
                } else {
                    // Transfer will begin when user validate check wifi rights
                    return;
                }
            }
            new Thread(new DoSendZipToServer(this)).start();
        }
    }

    /**
     * Ping largest internet dns access to check if internet is available
     * @return True if Internet is available
     */
    public boolean isOnline() {
        try {
            URL url = new URL(MeasurementUploadWPS.BASE_URL);
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            int code = urlConnection.getResponseCode();
            return code == 200 || code == 301 || code == 302;
        } catch (IOException e) {
            MAINLOGGER.error(e.getLocalizedMessage(), e);
        }
        return false;
    }

    /**
     * Transfer provided records
     */
    protected void doTransferRecords(List<Integer> selectedRecordIds) {
        runOnUiThread(new SendResults(this, selectedRecordIds));
    }

    /**
     * Transfer records without checking user preferences
     */
    protected void doTransferRecords() {
        if (!isOnline()) {
            MAINLOGGER.info("Not online, skip send of record");
            return;
        }
        MeasurementManager measurementManager = new MeasurementManager(this);
        List<Storage.Record> records = measurementManager.getRecords();
        final List<Integer> recordsToTransfer = new ArrayList<>();
        for (Storage.Record record : records) {
            // Auto send records only if the record is not in progress and if the user have
            // validated the Description activity
            if (record.getUploadId().isEmpty() && record.getTimeLength() > 0 && record.getNoisePartyTag() != null) {
                recordsToTransfer.add(record.getId());
            }
        }
        if (!recordsToTransfer.isEmpty()) {
            doTransferRecords(recordsToTransfer);
        }
    }

    protected static final class SendResults implements Runnable {
        private MainActivity mainActivity;
        private List<Integer> recordsToTransfer;

        public SendResults(MainActivity mainActivity, List<Integer> recordsToTransfer) {
            this.mainActivity = mainActivity;
            this.recordsToTransfer = recordsToTransfer;
        }

        public SendResults(MainActivity mainActivity, Integer... recordsToTransfer) {
            this.mainActivity = mainActivity;
            this.recordsToTransfer = Arrays.asList(recordsToTransfer);
        }

        @Override
        public void run() {
            // Export
            try {
                mainActivity.progress = ProgressDialog.show(mainActivity,
                        mainActivity.getText(R.string.upload_progress_title),
                        mainActivity.getText(R.string.upload_progress_message), true);
            } catch (RuntimeException ex) {
                // This error may arise on some system
                // The display of progression are not vital so cancel the crash by handling the
                // error
                MAINLOGGER.error(ex.getLocalizedMessage(), ex);
            }
            new Thread(new SendZipToServer(mainActivity, recordsToTransfer, mainActivity.progress,
                    new OnUploadedListener() {
                        @Override
                        public void onMeasurementUploaded() {
                            mainActivity.onTransferRecord();
                        }
                    })).start();
        }
    }

    protected void onTransferRecord() {
        // Nothing to do
    }

    /***
     * Checks that application runs first time and write flags at SharedPreferences
     * Need further codes for enhancing conditions
     * @return true if 1st time
     * see : http://stackoverflow.com/questions/9806791/showing-a-message-dialog-only-once-when-application-is-launched-for-the-first
     * see also for checking version (later) : http://stackoverflow.com/questions/7562786/android-first-run-popup-dialog
     * Can be used for checking new version
     */
    protected boolean CheckNbRun(String preferenceName, int maxCount) {
        SharedPreferences preferences = getPreferences(MODE_PRIVATE);
        SharedPreferences.Editor editor = preferences.edit();
        Integer NbRun = preferences.getInt(preferenceName, 1);
        if (NbRun > maxCount) {
            NbRun = 1;
        }
        editor.putInt(preferenceName, NbRun + 1);
        editor.apply();
        return (NbRun == 1);
    }

    protected void displayCommunityMapNotification() {
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
                .setSmallIcon(MeasurementService.getNotificationIcon())
                .setContentTitle(getString(R.string.notification_goto_community_map_title))
                .setContentText(getString(R.string.notification_goto_community_map)).setAutoCancel(true);
        NotificationCompat.BigTextStyle bigTextStyle = new NotificationCompat.BigTextStyle();
        bigTextStyle.setBigContentTitle(getString(R.string.notification_goto_community_map_title));
        bigTextStyle.bigText(getString(R.string.notification_goto_community_map));
        builder.setStyle(bigTextStyle);
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setData(Uri.parse("http://noise-planet.org/map_noisecapture"));
        TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
        stackBuilder.addParentStack(this);
        stackBuilder.addNextIntent(intent);
        builder.setContentIntent(stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT));
        NotificationManager mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        mNM.notify(NOTIFICATION_MAP, builder.build());
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
            @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
        case PERMISSION_WIFI_STATE: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                new Thread(new DoSendZipToServer(this)).start();
            } else {
                // permission denied
                // Ask again
                checkAndAskPermissions();
            }
        }
        }
    }

    private boolean checkWifiState() {

        // Check connection state
        WifiManager wifiMgr = (WifiManager) getSystemService(Context.WIFI_SERVICE);
        if (wifiMgr.isWifiEnabled()) { // WiFi adapter is ON
            WifiInfo wifiInfo = wifiMgr.getConnectionInfo();
            if (wifiInfo.getNetworkId() == -1) {
                return false; // Not connected to an access-Point
            }
            // Connected to an Access Point
            return true;
        } else {
            return false; // WiFi adapter is OFF
        }
    }

    public static final class DoSendZipToServer implements Runnable {
        MainActivity mainActivity;

        public DoSendZipToServer(MainActivity mainActivity) {
            this.mainActivity = mainActivity;
        }

        @Override
        public void run() {
            mainActivity.doTransferRecords();
        }
    }

    public static final class SendZipToServer implements Runnable {
        private Activity activity;
        private List<Integer> recordsId = new ArrayList<>();
        private ProgressDialog progress;
        private final OnUploadedListener listener;

        public SendZipToServer(Activity activity, int recordId, ProgressDialog progress,
                OnUploadedListener listener) {
            this.activity = activity;
            this.recordsId.add(recordId);
            this.progress = progress;
            this.listener = listener;
        }

        public SendZipToServer(Activity activity, Collection<Integer> records, ProgressDialog progress,
                OnUploadedListener listener) {
            this.activity = activity;
            this.recordsId.addAll(records);
            this.progress = progress;
            this.listener = listener;
        }

        @Override
        public void run() {
            MeasurementUploadWPS measurementUploadWPS = new MeasurementUploadWPS(activity);
            try {
                for (Integer recordId : recordsId) {
                    measurementUploadWPS.uploadRecord(recordId);
                }
                if (listener != null) {
                    activity.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            listener.onMeasurementUploaded();
                        }
                    });
                }
            } catch (final IOException ex) {
                MAINLOGGER.error(ex.getLocalizedMessage(), ex);
                activity.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(activity, ex.getLocalizedMessage(), Toast.LENGTH_LONG).show();
                    }
                });
            } finally {
                if (progress != null && progress.isShowing()) {
                    try {
                        progress.dismiss();
                    } catch (IllegalArgumentException ex) {
                        //Ignore
                    }
                }
            }
        }
    }

    public interface OnUploadedListener {
        void onMeasurementUploaded();
    }

    // Choose color category in function of sound level
    public static int getNEcatColors(double SL) {

        int NbNEcat;

        if (SL > 75.) {
            NbNEcat = 0;
        } else if (SL > 65) {
            NbNEcat = 1;
        } else if (SL > 55) {
            NbNEcat = 2;
        } else if (SL > 45) {
            NbNEcat = 3;
        } else {
            NbNEcat = 4;
        }
        return NbNEcat;
    }

    public static double getDouble(SharedPreferences sharedPref, String key, double defaultValue) {
        try {
            return Double.valueOf(sharedPref.getString(key, String.valueOf(defaultValue)));
        } catch (NumberFormatException ex) {
            return defaultValue;
        }
    }

    public static int getInteger(SharedPreferences sharedPref, String key, int defaultValue) {
        try {
            return Integer.valueOf(sharedPref.getString(key, String.valueOf(defaultValue)));
        } catch (NumberFormatException ex) {
            return defaultValue;
        }
    }
}