ota.otaupdates.MainActivity.java Source code

Java tutorial

Introduction

Here is the source code for ota.otaupdates.MainActivity.java

Source

/**
 * Project: OTAUpdates
 *
 * @author berkantkz, TimSchumi
 * License: GNU General Public License, Version 3
 * <p>
 * Copyright 2017 Berkant Korkmaz, Tim Schumacher
 * <p>
 * This program is 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.
 * <p>
 * This program 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, see <http://www.gnu.org/licenses/>.
 *
 * Only the Main Program is covered by this License. Other modules/items which
 * are included/used may have other Licenses
 */
package ota.otaupdates;

import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.DialogInterface;
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.ConnectivityManager;
import android.net.ParseException;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.Snackbar;
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.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.ProgressBar;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Locale;

import ota.otaupdates.utils.Constants;
import ota.otaupdates.utils.MD5;
import ota.otaupdates.utils.Utils;
import eu.chainfire.libsuperuser.Shell;

import static ota.otaupdates.utils.Constants.DL_PATH;

public class MainActivity extends AppCompatActivity {

    private static final int PERMISSION_REQUEST_CODE = 1;
    private static final int RESULT_SETTINGS = 1;
    final StringBuilder build_url = new StringBuilder();
    final StringBuilder build_dl_url = new StringBuilder();
    final StringBuilder delta_url = new StringBuilder();
    final StringBuilder delta_dl_url = new StringBuilder();
    static ArrayList<OTAUpdates> otaList;
    OTAUpdatesAdapter adapter;
    Snackbar sb_network;
    Snackbar sb_no_su;
    static SharedPreferences sharedPreferences;
    ProgressBar pb;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);

        if (sharedPreferences.getBoolean("force_english", false)) {
            Locale myLocale = new Locale("en");
            Resources res = getResources();
            DisplayMetrics dm = res.getDisplayMetrics();
            Configuration conf = res.getConfiguration();
            conf.locale = myLocale;
            res.updateConfiguration(conf, dm);
        }

        if (sharedPreferences.getBoolean("apptheme_light", false))
            setTheme(R.style.AppTheme_Light);
        else
            setTheme(R.style.AppTheme_Dark);

        setContentView(R.layout.activity_main);

        build_url
                .append((Utils.doesPropExist(Constants.URL_PROP)) ? Utils.getProp(Constants.URL_PROP)
                        : getString(R.string.download_url))
                .append("/api/").append(Build.DEVICE).append("/").append(Build.TIME / 1000);

        build_dl_url.append((Utils.doesPropExist(Constants.URL_PROP)) ? Utils.getProp(Constants.URL_PROP)
                : getString(R.string.download_url)).append("/builds/");

        delta_url.append((Utils.doesPropExist(Constants.URL_PROP) ? Utils.getProp(Constants.URL_PROP)
                : getString(R.string.download_url))).append("/delta/").append(Build.VERSION.INCREMENTAL);

        delta_dl_url.append((Utils.doesPropExist(Constants.URL_PROP)) ? Utils.getProp(Constants.URL_PROP)
                : getString(R.string.download_url)).append("/deltas/");

        otaList = new ArrayList<>();
        get_builds();
        pb = (ProgressBar) findViewById(R.id.pb);
        pb.setVisibility(View.VISIBLE);

        final ListView ota_list = (ListView) findViewById(R.id.ota_list);

        adapter = new OTAUpdatesAdapter(getApplicationContext(), R.layout.row, otaList);
        ota_list.setAdapter(adapter);

        final CoordinatorLayout coordinator_root = (CoordinatorLayout) findViewById(R.id.coordinator_root);
        ota_list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, final int position, long id) {
                final String url = build_dl_url.toString() + otaList.get(position).getOta_filename();

                if (Build.VERSION.SDK_INT >= 23 && !checkPermission())
                    allow_write_sd();
                else if (sharedPreferences.getBoolean("disable_mobile", true) && isMobileDataEnabled()) {
                    sb_network = Snackbar.make(coordinator_root, getString(R.string.disable_mobile_message),
                            Snackbar.LENGTH_SHORT);
                    sb_network.getView()
                            .setBackgroundColor(ContextCompat.getColor(MainActivity.this, R.color.colorSecond));
                    sb_network.show();
                } else {
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            create_notification(1, getString(R.string.app_name), getString(
                                    R.string.downloader_notification, otaList.get(position).getOta_filename()));
                            Utils.DownloadFromUrl(url, otaList.get(position).getOta_filename());
                            ((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).cancel(1);
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    if (MD5.checkMD5(otaList.get(position).getOta_md5(),
                                            new File(DL_PATH + otaList.get(position).getOta_filename()))
                                            || !sharedPreferences.getBoolean("md5_checking", true))
                                        trigger_autoinstall(DL_PATH + otaList.get(position).getOta_filename());
                                    else {
                                        new AlertDialog.Builder(MainActivity.this)
                                                .setTitle(getString(R.string.md5_title))
                                                .setMessage(getString(R.string.md5_message)).setNeutralButton(
                                                        R.string.button_ok, new DialogInterface.OnClickListener() {
                                                            public void onClick(DialogInterface dialog, int which) {
                                                            }
                                                        })
                                                .show();
                                    }
                                }
                            });
                        }
                    }).start();
                }
            }
        });

    }

    private void get_builds() {
        otaList.clear();
        new JSONAsyncTask().execute(delta_url.toString());
        new JSONAsyncTask().execute(build_url.toString());
    }

    private void allow_write_sd() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(getString(R.string.write_access));
        builder.setMessage(getString(R.string.write_access_message));
        builder.setPositiveButton(getString(R.string.button_ok), new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                if (Build.VERSION.SDK_INT >= 23 && !checkPermission()) {
                    // If user hasn't allowed yet, request the permission.
                    requestPermission();
                }
            }
        });
        AlertDialog alert = builder.create();
        alert.setCancelable(false);
        if (!checkPermission()) {
            // If user hasn't allowed yet, show requester dialog.
            alert.show();
        }
    }

    private void create_notification(int id, String title, String content) {
        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
                .setSmallIcon((android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP
                        ? R.drawable.app_icon_notification
                        : R.drawable.app_icon))
                .setContentTitle(title).setContentText(content);

        Intent resultIntent = new Intent(this, MainActivity.class);
        TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
        stackBuilder.addParentStack(MainActivity.class);
        stackBuilder.addNextIntent(resultIntent);
        PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
        mBuilder.setContentIntent(resultPendingIntent);
        NotificationManager mNotificationManager = (NotificationManager) getSystemService(
                Context.NOTIFICATION_SERVICE);
        mNotificationManager.notify(id, mBuilder.build());
    }

    private void trigger_autoinstall(final String file_path) {
        final SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
        final CoordinatorLayout coordinator_root = (CoordinatorLayout) findViewById(R.id.coordinator_root);
        if (sharedPreferences.getBoolean("enable_auto_install", true)) {
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle(getString(R.string.auto_install_title));
            builder.setMessage(getString(R.string.auto_install_message));
            builder.setPositiveButton(getString(R.string.button_yes), new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {

                    if (Shell.SU.available()) {
                        Shell.SU.run("rm -rf /cache/recovery/openrecoveryscript");
                        Shell.SU.run("echo \"install " + file_path + "\" >> /cache/recovery/openrecoveryscript");

                        if (sharedPreferences.getBoolean("wipe_cache", true))
                            Shell.SU.run("echo \"wipe cache\" >> /cache/recovery/openrecoveryscript");

                        if (sharedPreferences.getBoolean("wipe_dalvik", true))
                            Shell.SU.run("echo \"wipe dalvik\" >> /cache/recovery/openrecoveryscript");

                        if (sharedPreferences.getBoolean("auto_reboot", true))
                            Shell.SU.run("reboot recovery");
                    } else {
                        sb_no_su = Snackbar.make(coordinator_root, "SU access is not available",
                                Snackbar.LENGTH_SHORT);
                        sb_no_su.getView()
                                .setBackgroundColor(ContextCompat.getColor(MainActivity.this, R.color.colorSecond));
                        sb_no_su.show();
                    }
                }
            });
            builder.setNegativeButton(getString(R.string.button_no), new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                }
            });
            AlertDialog alert = builder.create();
            alert.setCancelable(false);
            alert.show();
        }
    }

    private boolean checkPermission() {
        int result = ContextCompat.checkSelfPermission(MainActivity.this,
                android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
        return result == PackageManager.PERMISSION_GRANTED;
    }

    /**
     * @return null if unconfirmed
     */
    public Boolean isMobileDataEnabled() {
        Object connectivityService = getSystemService(CONNECTIVITY_SERVICE);
        ConnectivityManager cm = (ConnectivityManager) connectivityService;

        try {
            Class<?> c = Class.forName(cm.getClass().getName());
            Method m = c.getDeclaredMethod("getMobileDataEnabled");
            m.setAccessible(true);
            return (Boolean) m.invoke(cm);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    private void requestPermission() {
        ActivityCompat.requestPermissions(MainActivity.this,
                new String[] { android.Manifest.permission.WRITE_EXTERNAL_STORAGE }, PERMISSION_REQUEST_CODE);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[],
            @NonNull int[] grantResults) {
        switch (requestCode) {
        case PERMISSION_REQUEST_CODE:
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Log.d(getString(R.string.app_name), "Permission granted. Files can be saved");
            } else {
                Log.e(getString(R.string.app_name), "Permission denied. The App won\'t work");
                finish();
            }
            break;
        }
    }

    class JSONAsyncTask extends AsyncTask<String, Void, Boolean> {

        CoordinatorLayout coordinator_root;
        Snackbar sb;
        ListView ota_list;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            coordinator_root = (CoordinatorLayout) findViewById(R.id.coordinator_root);
            sb = Snackbar.make(coordinator_root, getString(R.string.loading), Snackbar.LENGTH_SHORT);
            sb.getView().setBackgroundColor(ContextCompat.getColor(MainActivity.this, R.color.colorSecond));
            sb.show();
        }

        @Override
        protected Boolean doInBackground(String... urls) {
            try {
                HttpGet httppost = new HttpGet(urls[0]);
                HttpClient httpclient = new DefaultHttpClient();
                HttpResponse response = httpclient.execute(httppost);

                if (response.getStatusLine().getStatusCode() == 200) {
                    HttpEntity entity = response.getEntity();
                    String data = EntityUtils.toString(entity);
                    JSONArray jarray = new JSONArray(data);

                    for (int i = 0; i < jarray.length(); i++) {
                        JSONObject object = jarray.getJSONObject(i);

                        OTAUpdates dls = new OTAUpdates();

                        dls.setOta_filename(object.getString("filename"));
                        dls.setOta_timestamp(object.getString("timestamp"));
                        dls.setOta_md5(object.getString("md5sum"));

                        if (object.isNull("old_incremental")) {
                            dls.setOta_version(object.getString("version"));
                        } else {
                            dls.setOta_old_incremental(object.getString("old_incremental"));
                            dls.setDelta(true);
                        }

                        otaList.add(dls);

                    }
                    return true;
                }

            } catch (UnknownHostException e) {
                Log.e(getString(R.string.app_name), "No Network Connection");
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Snackbar mSnackbar = Snackbar.make(coordinator_root, getString(R.string.loading_failed),
                                Snackbar.LENGTH_SHORT);
                        mSnackbar.getView()
                                .setBackgroundColor(ContextCompat.getColor(MainActivity.this, R.color.colorSecond));
                        mSnackbar.show();
                    }
                });
            } catch (IOException | ParseException | JSONException e) {
                e.printStackTrace();
            }
            return false;

        }

        protected void onPostExecute(Boolean result) {
            adapter.notifyDataSetChanged();
            pb.setVisibility(View.INVISIBLE);
            ota_list = (ListView) findViewById(R.id.ota_list);
            ota_list.setVisibility((adapter.isEmpty()) ? View.GONE : View.VISIBLE);
            sb.getView().setBackgroundColor(ContextCompat.getColor(MainActivity.this, R.color.colorSecond));
            sb.show();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // show menu when menu button is pressed
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == R.id.action_refresh) {
            get_builds();
            pb.setVisibility(View.VISIBLE);
        } else if (item.getItemId() == R.id.action_settings) {
            Intent settings = new Intent(MainActivity.this, Settings.class);
            startActivityForResult(settings, RESULT_SETTINGS);
        }

        return true;
    }

}