Java tutorial
package edu.mit.mobile.android.demomode; /* * Copyright (C) 2012 MIT Mobile Experience Lab * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License Version 2 * as published by the Free Software Foundation. * * 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/>. */ import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; import org.apache.http.NameValuePair; import org.apache.http.client.utils.URLEncodedUtils; import org.apache.http.entity.StringEntity; import org.apache.http.message.BasicNameValuePair; import android.content.ComponentName; import android.content.ContentProviderOperation; import android.content.Intent; import android.content.OperationApplicationException; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.os.RemoteException; import android.preference.Preference; import android.preference.Preference.OnPreferenceClickListener; import android.preference.PreferenceActivity; import android.util.Log; import com.google.zxing.integration.android.IntentIntegrator; import com.google.zxing.integration.android.IntentResult; public class Preferences extends PreferenceActivity implements OnPreferenceClickListener { private static final String TAG = Preferences.class.getSimpleName(); private SharedPreferences mPrefs; public static final String KEY_PASSWORD = "password"; public static final String KEY_LOCKED = "locked"; public static final String KEY_SHARE_CONFIG = "share_config"; public static final String KEY_SCAN_CONFIG = "scan_config"; public static final String KEY_ENABLED = "enable"; private static String CFG_PKG_SEP = ","; @SuppressWarnings("deprecation") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.addPreferencesFromResource(R.xml.preferences); mPrefs = getPreferenceManager().getSharedPreferences(); findPreference(KEY_SHARE_CONFIG).setOnPreferenceClickListener(this); findPreference(KEY_SCAN_CONFIG).setOnPreferenceClickListener(this); mPrefs.registerOnSharedPreferenceChangeListener(new OnSharedPreferenceChangeListener() { @Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { if (KEY_ENABLED.equals(key)) { updateDemoModeEnabled(); } } }); } @Override protected void onResume() { super.onResume(); if (mPrefs.getBoolean(KEY_LOCKED, false)) { finish(); } } private static final String CFG_K_VER = "v", CFG_K_SECRETKEY = "k", CFG_K_APPS = "a"; public static final String CFG_MIME_TYPE = "application/x-demo-mode"; private String toConfigString() { final String password = mPrefs.getString(KEY_PASSWORD, null); final ArrayList<BasicNameValuePair> nvp = new ArrayList<BasicNameValuePair>(); int ver; try { ver = getPackageManager().getPackageInfo(getPackageName(), 0).versionCode; } catch (final NameNotFoundException e) { // this should never happen ver = 0; e.printStackTrace(); } nvp.add(new BasicNameValuePair(CFG_K_VER, String.valueOf(ver))); nvp.add(new BasicNameValuePair(CFG_K_SECRETKEY, password)); final Cursor c = getContentResolver().query(LauncherItem.CONTENT_URI, null, null, null, null); try { final int pkgCol = c.getColumnIndex(LauncherItem.PACKAGE_NAME); final int actCol = c.getColumnIndex(LauncherItem.ACTIVITY_NAME); for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) { nvp.add(new BasicNameValuePair(CFG_K_APPS, c.getString(pkgCol) + CFG_PKG_SEP + c.getString(actCol))); } return "data:" + CFG_MIME_TYPE + "," + URLEncodedUtils.format(nvp, "utf-8"); } finally { c.close(); } } private void shareConfig() { startActivity(Intent.createChooser( new Intent(Intent.ACTION_SEND).setType("text/plain").putExtra(Intent.EXTRA_TEXT, toConfigString()) .putExtra(Intent.EXTRA_SUBJECT, getText(R.string.app_name) + " Config"), getText(R.string.share_config))); } private void fromCfgString(String cfg) { final Uri cfgUri = Uri.parse(cfg); if ("data".equals(cfgUri.getScheme())) { final String[] cfgParts = cfgUri.getEncodedSchemeSpecificPart().split(",", 2); if (CFG_MIME_TYPE.equals(cfgParts[0])) { final Editor ed = mPrefs.edit(); final ArrayList<ContentProviderOperation> cpos = new ArrayList<ContentProviderOperation>(); // first erase everything cpos.add(ContentProviderOperation.newDelete(LauncherItem.CONTENT_URI).build()); try { final StringEntity entity = new StringEntity(cfgParts[1]); entity.setContentType("application/x-www-form-urlencoded"); final List<NameValuePair> nvp = URLEncodedUtils.parse(entity); for (final NameValuePair pair : nvp) { final String name = pair.getName(); Log.d(TAG, "parsed pair: " + pair); if (CFG_K_SECRETKEY.equals(name)) { ed.putString(KEY_PASSWORD, pair.getValue()); } else if (CFG_K_APPS.equals(name)) { final String[] app = pair.getValue().split(CFG_PKG_SEP, 2); final ContentProviderOperation cpo = ContentProviderOperation .newInsert(LauncherItem.CONTENT_URI) .withValue(LauncherItem.PACKAGE_NAME, app[0]) .withValue(LauncherItem.ACTIVITY_NAME, app[1]).build(); cpos.add(cpo); Log.d(TAG, "adding " + cpo); } } ed.commit(); getContentResolver().applyBatch(HomescreenProvider.AUTHORITY, cpos); } catch (final UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (final IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (final RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (final OperationApplicationException e) { // TODO Auto-generated catch block e.printStackTrace(); } } else { Log.e(TAG, "unknown MIME type for data URI: " + cfgParts[0]); } } else { Log.e(TAG, "not a data URI"); } } private void scanQRCode() { final IntentIntegrator integrator = new IntentIntegrator(this); integrator.initiateScan(); } @Override public void onActivityResult(int requestCode, int resultCode, Intent intent) { final IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent); if (scanResult != null && scanResult.getContents() != null) { fromCfgString(scanResult.getContents()); } } @Override public boolean onPreferenceClick(Preference preference) { final String pref = preference.getKey(); if (KEY_SCAN_CONFIG.equals(pref)) { scanQRCode(); return true; } else if (KEY_SHARE_CONFIG.equals(pref)) { shareConfig(); return true; } return false; } private void updateDemoModeEnabled() { getPackageManager().setComponentEnabledSetting(new ComponentName(this, DemoMode.class), mPrefs.getBoolean(KEY_ENABLED, true) ? PackageManager.COMPONENT_ENABLED_STATE_DEFAULT : PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); } }