/* * Copyright (C) 2009-2013 Felix Bechstein * * This file is part of Call Meter 3G. * * 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. * * 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.ub0r.android.callmeter.ui.prefs; import android.Manifest; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; import android.os.Environment; import android.preference.Preference; import android.preference.PreferenceActivity; import android.preference.PreferenceGroup; import android.support.annotation.NonNull; import android.view.Window; import android.widget.Toast; import java.io.File; import de.ub0r.android.callmeter.CallMeter; import de.ub0r.android.callmeter.R; import de.ub0r.android.lib.Utils; import de.ub0r.android.logg0r.Log; /** * Show a list of ready to import rule sets. * * @author flx */ public final class PreferencesImport extends PreferenceActivity { private static final String TAG = "PreferencesImport"; /** * Maximal depth for searching files. */ private static final int MAX_DEPTH = 3; private static final int PERMISSION_REQUEST_READ_EXTERNAL_STORAGE = 1; /** * {@link AsyncTask} running through the SD card and adding {@link Preferences} for each file. * * @author flx */ private class FileFinder extends AsyncTask<Void, File, Boolean> { /** * Tag for output. */ private static final String TAG = "PreferencesImport.FileFinder"; @Override protected void onPreExecute() { PreferencesImport.this.setProgressBarIndeterminate(true); PreferencesImport.this.setProgressBarIndeterminateVisibility(true); } @Override protected Boolean doInBackground(final Void... paramArrayOfParams) { return addExport(Environment.getExternalStorageDirectory(), MAX_DEPTH); } @SuppressWarnings("deprecation") @Override protected void onProgressUpdate(final File... values) { for (File f : values) { // add file to list PreferencesImport context = PreferencesImport.this; Preference p = new Preference(context); p.setTitle(f.getName()); p.setSummary(f.getAbsolutePath()); Intent i = new Intent(context, Preferences.class); i.setData(Uri.parse("file://" + f.getAbsolutePath())); p.setIntent(i); ((PreferenceGroup) context.findPreference("import_rules_files")).addPreference(p); } } @Override protected void onPostExecute(final Boolean result) { PreferencesImport.this.setProgressBarIndeterminateVisibility(false); if (!result) { Toast.makeText(PreferencesImport.this, R.string.import_rules_sd_nofiles, Toast.LENGTH_LONG).show(); } } /** * Add all ready to import rule sets to preference list. * * @param d root directory * @param depth maximal depth for searching files * @return true, if a file were found */ private boolean addExport(final File d, final int depth) { if (d == null) { Log.e(TAG, "null file: " + d); return false; } if (!d.exists()) { Log.e(TAG, d + " does not exist"); return false; } if (!d.isDirectory()) { Log.e(TAG, d + " is not a directory"); return false; } if (d.list() == null) { Log.e(TAG, d + ".list() is null"); return false; } boolean ret = false; // read directory for (String s : d.list()) { if (s.startsWith(".") || s.equals("Android") || s.equals("clockworkmod") || s.equals("DCIM") || s.equals("Music") || s.equals("TitaniumBackup") || s.equals("openfeint") || s.equals("soundhound") || s.equals("WhatsApp") || s.equals("Pictures") || s.equals("SMSBackupRestore")) { Log.d(TAG, "skip: ", s); continue; } File f = new File(d.getAbsoluteFile(), s); Log.d(TAG, "try file: ", f.getAbsolutePath()); if (f.isDirectory()) { if (depth > 0) { ret |= addExport(f, depth - 1); } } else if (f.isFile() && (f.getAbsolutePath().endsWith(".xml"))) { // add file to list onProgressUpdate(f); ret = true; } } return ret; } } @SuppressWarnings("deprecation") @Override public void onCreate(final Bundle savedInstanceState) { requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); super.onCreate(savedInstanceState); Utils.setLocale(this); addPreferencesFromResource(R.xml.import_from_sd); updateFiles(); } @Override public void onRequestPermissionsResult( final int requestCode, @NonNull final String permissions[], @NonNull final int[] grantResults) { switch (requestCode) { case PERMISSION_REQUEST_READ_EXTERNAL_STORAGE: if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // just try again. updateFiles(); } else { Log.e(TAG, "permission denied: READ_EXTERNAL_STORAGE, finish"); finish(); } } } private void updateFiles() { if (!CallMeter.requestPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE, PERMISSION_REQUEST_READ_EXTERNAL_STORAGE, R.string.permissions_read_external_storage, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { finish(); } })) { return; } new FileFinder().execute((Void) null); } }