de.Maxr1998.xposed.maxlock.ui.settings.appslist.AppsListFragment.java Source code

Java tutorial

Introduction

Here is the source code for de.Maxr1998.xposed.maxlock.ui.settings.appslist.AppsListFragment.java

Source

/*
 * MaxLock, an Xposed applock module for Android
 * Copyright (C) 2014-2015  Maxr1998
 *
 * 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 any later version.
 *
 * 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/>.
 */

package de.Maxr1998.xposed.maxlock.ui.settings.appslist;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.app.Fragment;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.SearchView;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.RelativeLayout;
import android.widget.Toast;

import com.haibison.android.lockpattern.LockPatternActivity;

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import de.Maxr1998.xposed.maxlock.Common;
import de.Maxr1998.xposed.maxlock.R;
import de.Maxr1998.xposed.maxlock.Util;
import de.Maxr1998.xposed.maxlock.ui.SettingsActivity;
import xyz.danoz.recyclerviewfastscroller.sectionindicator.title.SectionTitleIndicator;
import xyz.danoz.recyclerviewfastscroller.vertical.VerticalRecyclerViewFastScroller;

public class AppsListFragment extends Fragment {

    private static List<Map<String, Object>> finalList;
    RecyclerView recyclerView;
    AlertDialog restoreDialog;
    VerticalRecyclerViewFastScroller fastScroller;
    SectionTitleIndicator sectionTitleIndicator;
    private ViewGroup rootView;
    private ProgressDialog progressDialog;
    private AppListAdapter mAdapter;
    private SharedPreferences pref;
    private SetupAppList task;
    private ArrayAdapter<String> restoreAdapter;

    public static void clearList() {
        finalList = null;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);
        setHasOptionsMenu(true);
        pref = getActivity().getSharedPreferences(Common.PREFS, Context.MODE_PRIVATE);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        rootView = new RelativeLayout(getActivity());
        if (finalList == null || finalList.isEmpty()) {
            progressDialog = new ProgressDialog(getActivity());
            progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            progressDialog.setCanceledOnTouchOutside(false);
            progressDialog.setCancelable(true);
            progressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
                @Override
                public void onCancel(DialogInterface dialogInterface) {
                    task.cancel(true);
                }
            });
            progressDialog.show();
            if (task == null)
                task = new SetupAppList();
            if (!task.getStatus().equals(AsyncTask.Status.RUNNING))
                task.execute();
        } else {
            setup();
        }
        return rootView;
    }

    private void setup() {
        mAdapter = new AppListAdapter(AppsListFragment.this, getActivity(), finalList);
        getActivity().getLayoutInflater().inflate(R.layout.fragment_appslist, rootView);
        recyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerView);
        recyclerView.setAdapter(mAdapter);
        if (/*Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH*/false) {
            fastScroller = (VerticalRecyclerViewFastScroller) rootView.findViewById(R.id.fast_scroller);
            sectionTitleIndicator = (SectionTitleIndicator) rootView
                    .findViewById(R.id.fast_scroller_section_title_indicator);
            fastScroller.setRecyclerView(recyclerView);
            recyclerView.setOnScrollListener(fastScroller.getOnScrollListener());
            fastScroller.setSectionIndicator(sectionTitleIndicator);
        }
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        if (progressDialog != null)
            progressDialog.dismiss();
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        super.onCreateOptionsMenu(menu, inflater);
        inflater.inflate(R.menu.applist_menu, menu);
        SearchView searchView = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.toolbar_search));
        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String s) {
                return false;
            }

            @Override
            public boolean onQueryTextChange(String s) {
                mAdapter.getFilter().filter(s);
                return true;
            }
        });
    }

    @SuppressLint("WorldReadableFiles")
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (pref.getBoolean(Common.ENABLE_PRO, false)) {
            final File prefsPackagesFileShort = new File(Common.PREFS_PACKAGES + ".xml");
            final File prefsPerAppFileShort = new File(Common.PREFS_PER_APP + ".xml");
            final File prefsPackagesFile = new File(getActivity().getApplicationInfo().dataDir + File.separator
                    + "shared_prefs" + File.separator + prefsPackagesFileShort);
            final File prefsPerAppFile = new File(getActivity().getApplicationInfo().dataDir + File.separator
                    + "shared_prefs" + File.separator + prefsPerAppFileShort);
            final File backupDir = new File(
                    Environment.getExternalStorageDirectory() + File.separator + "MaxLock_Backup");

            switch (item.getItemId()) {
            case R.id.toolbar_backup_list:
                File curTimeDir = new File(backupDir + File.separator
                        + new SimpleDateFormat("yyyy-MM-dd-HH.mm.ss", Locale.getDefault())
                                .format(new Date(System.currentTimeMillis()))
                        + File.separator);
                try {
                    if (prefsPackagesFile.exists()) {
                        FileUtils.copyFileToDirectory(prefsPackagesFile, curTimeDir);
                        if (prefsPerAppFile.exists())
                            FileUtils.copyFileToDirectory(prefsPerAppFile, curTimeDir);
                    } else
                        Toast.makeText(getActivity(), R.string.toast_no_files_to_backup, Toast.LENGTH_SHORT).show();
                } catch (IOException e) {
                    Toast.makeText(getActivity(), R.string.toast_backup_restore_exception, Toast.LENGTH_SHORT)
                            .show();
                    e.printStackTrace();
                }
                if (curTimeDir.exists() && new File(curTimeDir + File.separator + prefsPackagesFileShort).exists())
                    Toast.makeText(getActivity(), R.string.toast_backup_success, Toast.LENGTH_SHORT).show();
                return true;

            case R.id.toolbar_restore_list:
                List<String> list = new ArrayList<>(Arrays.asList(backupDir.list()));
                restoreAdapter = new ArrayAdapter<>(getActivity(), android.R.layout.simple_list_item_1, list);
                restoreDialog = new AlertDialog.Builder(getActivity())
                        .setTitle(R.string.dialog_restore_list_message)
                        .setAdapter(restoreAdapter, new DialogInterface.OnClickListener() {
                            @SuppressLint("InlinedApi")
                            @Override
                            public void onClick(DialogInterface dialogInterface, int i) {
                                File restorePackagesFile = new File(backupDir + File.separator
                                        + restoreAdapter.getItem(i) + File.separator + prefsPackagesFileShort);
                                File restorePerAppFile = new File(backupDir + File.separator
                                        + restoreAdapter.getItem(i) + File.separator + prefsPerAppFileShort);
                                if (restorePackagesFile.exists()) {
                                    try {
                                        //noinspection ResultOfMethodCallIgnored
                                        prefsPackagesFile.delete();
                                        FileUtils.copyFile(restorePackagesFile, prefsPackagesFile);
                                        if (restorePerAppFile.exists()) {
                                            //noinspection ResultOfMethodCallIgnored
                                            prefsPerAppFile.delete();
                                            FileUtils.copyFile(restorePerAppFile, prefsPerAppFile);
                                        }
                                    } catch (IOException e) {
                                        e.printStackTrace();
                                    }
                                    getActivity().getSharedPreferences(Common.PREFS_PACKAGES,
                                            Context.MODE_MULTI_PROCESS);
                                    getActivity().getSharedPreferences(Common.PREFS_PER_APP,
                                            Context.MODE_MULTI_PROCESS);
                                    Toast.makeText(getActivity(), R.string.toast_restore_success,
                                            Toast.LENGTH_SHORT).show();
                                    ((SettingsActivity) getActivity()).restart();
                                } else
                                    Toast.makeText(getActivity(), R.string.toast_no_files_to_restore,
                                            Toast.LENGTH_SHORT).show();
                            }
                        }).setNegativeButton(android.R.string.cancel, null).show();
                restoreDialog.getListView().setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
                    @Override
                    public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) {
                        try {
                            FileUtils.deleteDirectory(
                                    new File(backupDir + File.separator + restoreAdapter.getItem(i)));
                            restoreAdapter.remove(restoreAdapter.getItem(i));
                            restoreAdapter.notifyDataSetChanged();
                        } catch (IOException e) {
                            e.printStackTrace();
                            return false;
                        }
                        return true;
                    }
                });
                return true;
            case R.id.toolbar_clear_list:
                //noinspection deprecation
                getActivity().getSharedPreferences(Common.PREFS_PACKAGES, Context.MODE_WORLD_READABLE).edit()
                        .clear().commit();
                //noinspection deprecation
                getActivity().getSharedPreferences(Common.PREFS_PER_APP, Context.MODE_WORLD_READABLE).edit().clear()
                        .commit();
                ((SettingsActivity) getActivity()).restart();
            }
        } else
            Toast.makeText(getActivity(), R.string.toast_pro_required, Toast.LENGTH_SHORT).show();
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (String.valueOf(requestCode).startsWith(String.valueOf(Util.PATTERN_CODE_APP))) {
            if (resultCode == LockPatternActivity.RESULT_OK) {
                String app = (String) finalList.get(Integer.parseInt(String.valueOf(requestCode).substring(1)))
                        .get("key");
                Util.receiveAndSetPattern(getActivity(), data.getCharArrayExtra(LockPatternActivity.EXTRA_PATTERN),
                        app);
            }
        } else
            super.onActivityResult(requestCode, resultCode, data);
    }

    private class SetupAppList extends AsyncTask<Void, Integer, List<Map<String, Object>>> {

        private List<Map<String, Object>> itemList;

        @Override
        protected List<Map<String, Object>> doInBackground(Void... voids) {
            PackageManager pm = getActivity().getPackageManager();
            List<ApplicationInfo> list = pm.getInstalledApplications(0);
            progressDialog.setMax(list.size());

            itemList = new ArrayList<>();
            int i = 0;
            for (ApplicationInfo info : list) {
                if (isCancelled())
                    break;
                while (getActivity() == null) {
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                if ((pref.getBoolean("show_system_apps", false)
                        ? getActivity().getPackageManager().getLaunchIntentForPackage(info.packageName) != null
                        : (info.flags & ApplicationInfo.FLAG_SYSTEM) == 0)
                        && !info.packageName.equals(Common.PKG_NAME)
                        || info.packageName.equals("com.android.packageinstaller")) {

                    Map<String, Object> map = new HashMap<>();

                    map.put("title", pm.getApplicationLabel(info));
                    map.put("key", info.packageName);
                    map.put("icon", pm.getApplicationIcon(info));

                    itemList.add(map);
                }
                i++;
                publishProgress(i);
            }

            Collections.sort(itemList, new Comparator<Map<String, Object>>() {
                @Override
                public int compare(Map<String, Object> lhs, Map<String, Object> rhs) {
                    String s1 = (String) lhs.get("title");
                    String s2 = (String) rhs.get("title");
                    return s1.compareToIgnoreCase(s2);
                }
            });
            return itemList;
        }

        @Override
        protected void onProgressUpdate(Integer... progress) {
            progressDialog.setProgress(progress[0]);
        }

        @Override
        protected void onPostExecute(List<Map<String, Object>> list) {
            super.onPostExecute(list);
            finalList = list;
            setup();
        }

        @Override
        protected void onCancelled() {
            getFragmentManager().popBackStack();
        }
    }
}