Java tutorial
/** * Copyright (C) 2013 Jonathan Gillett, Joseph Heron * * 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 com.tinfoil.sms.settings; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; import android.annotation.TargetApi; import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.support.v4.app.NavUtils; import android.text.InputType; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.widget.ArrayAdapter; import android.widget.AutoCompleteTextView; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; import com.bugsense.trace.BugSenseHandler; import com.tinfoil.sms.R; import com.tinfoil.sms.crypto.KeyExchange; import com.tinfoil.sms.crypto.KeyGenerator; import com.tinfoil.sms.dataStructures.Number; import com.tinfoil.sms.dataStructures.TrustedContact; import com.tinfoil.sms.dataStructures.User; import com.tinfoil.sms.database.DBAccessor; import com.tinfoil.sms.utility.SMSUtility; public class UserKeySettings extends Activity { private ArrayList<TrustedContact> tc; private AlertDialog popup_alert; private AutoCompleteTextView phoneBook; public static final String path = "/keys"; public static final String file = "exchange.txt"; private DBAccessor dba; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.user_key_settings); setupActionBar(); dba = new DBAccessor(this); TextView keyView = (TextView) findViewById(R.id.public_key); // Check if the user is null if (SMSUtility.user == null) { SMSUtility.user = dba.getUserRow(); } //Check if the user is still null (never set in db) if (SMSUtility.user == null) { // Generate the user's public key KeyGenerator keyGen = new KeyGenerator(); SMSUtility.user = new User(keyGen.generatePubKey(), keyGen.generatePriKey()); //Set the user's dba.setUser(SMSUtility.user); } keyView.setText(new String(SMSUtility.user.getPublicKey())); } /*@Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.user_key_settings, menu); return true; }*/ public void exportKey(View view) { if (SMSUtility.isMediaWritable()) { phoneBook = new AutoCompleteTextView(this); List<String> contact = null; if (tc == null) { //Do in thread. tc = dba.getAllRows(DBAccessor.ALL); } if (tc != null) { if (contact == null) { contact = SMSUtility.contactDisplayMaker(tc); } } else { contact = null; } final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this.getBaseContext(), R.layout.auto_complete_list_item, contact); phoneBook.setAdapter(adapter); final AlertDialog.Builder popup_builder = new AlertDialog.Builder(this); popup_builder.setTitle(R.string.import_contacts_title).setCancelable(true).setView(phoneBook) .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { public void onClick(final DialogInterface dialog, final int which) { String[] contactInfo = SMSUtility.parseAutoComplete(phoneBook.getText().toString()); //String number = null; boolean invalid = false; if (contactInfo != null) { if (contactInfo[0] == null) { contactInfo[0] = contactInfo[1]; } final Number number = dba.getNumber(contactInfo[1]); if (number != null) { AlertDialog.Builder builder = new AlertDialog.Builder(UserKeySettings.this); LinearLayout linearLayout = new LinearLayout(UserKeySettings.this); linearLayout.setOrientation(LinearLayout.VERTICAL); final EditText sharedSecret1 = new EditText(UserKeySettings.this); sharedSecret1 .setHint(UserKeySettings.this.getString(R.string.shared_secret_hint_1)); sharedSecret1.setMaxLines(EditNumber.SHARED_INFO_MAX); sharedSecret1.setInputType(InputType.TYPE_CLASS_TEXT); linearLayout.addView(sharedSecret1); final EditText sharedSecret2 = new EditText(UserKeySettings.this); sharedSecret2 .setHint(UserKeySettings.this.getString(R.string.shared_secret_hint_2)); sharedSecret2.setMaxLines(EditNumber.SHARED_INFO_MAX); sharedSecret2.setInputType(InputType.TYPE_CLASS_TEXT); linearLayout.addView(sharedSecret2); builder.setMessage(UserKeySettings.this.getString(R.string.set_shared_secrets) + " " + contactInfo[0] + ", " + number.getNumber()) .setTitle(R.string.set_shared_secrets_title).setCancelable(true) .setPositiveButton(R.string.save, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int id) { //Save the shared secrets String s1 = sharedSecret1.getText().toString(); String s2 = sharedSecret2.getText().toString(); if (SMSUtility.checksharedSecret(s1) && SMSUtility.checksharedSecret(s2)) { number.setSharedInfo1(s1); number.setSharedInfo2(s2); dba.updateNumberRow(number, number.getNumber(), number.getId()); number.setInitiator(true); dba.updateInitiator(number); //TODO add check for shared secrets String keyExchangeMessage = KeyExchange.sign(number, dba, SMSUtility.user); writeToFile(number.getNumber(), keyExchangeMessage); Toast.makeText(UserKeySettings.this, UserKeySettings.this .getString(R.string.written_path) + " " + path + "/" + number.getNumber() + "_" + file, Toast.LENGTH_SHORT).show(); } else { Toast.makeText(UserKeySettings.this, R.string.invalid_secrets, Toast.LENGTH_LONG) .show(); } } }) .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface arg0, int arg1) { //Cancel the key exchange Toast.makeText(UserKeySettings.this, R.string.key_exchange_cancelled, Toast.LENGTH_LONG).show(); } }); AlertDialog alert = builder.create(); alert.setView(linearLayout); alert.show(); } else { invalid = true; } } else { invalid = true; } if (invalid) { Toast.makeText(UserKeySettings.this, R.string.invalid_number_message, Toast.LENGTH_LONG).show(); } } }); popup_alert = popup_builder.create(); popup_alert.show(); //getExternalFilesDir(null); } } public static void writeToFile(String name, String text) { File root = Environment.getExternalStorageDirectory(); File keys = new File(root.getAbsolutePath() + path); keys.mkdirs(); File pubKey = new File(keys, name + "_" + file); try { FileOutputStream f = new FileOutputStream(pubKey); PrintWriter pw = new PrintWriter(f); pw.println(text); pw.flush(); pw.close(); f.close(); } catch (FileNotFoundException e) { e.printStackTrace(); BugSenseHandler.sendExceptionMessage("Type", "Export Public Key Not Found Error", e); } catch (IOException e) { e.printStackTrace(); BugSenseHandler.sendExceptionMessage("Type", "Export Public Key Error", e); } } @Override public boolean onCreateOptionsMenu(final Menu menu) { final MenuInflater inflater = this.getMenuInflater(); inflater.inflate(R.menu.remove_contacts_menu, menu); return true; } @Override public boolean onOptionsItemSelected(final MenuItem item) { switch (item.getItemId()) { case android.R.id.home: // This ID represents the Home or Up button. In the case of this // activity, the Up button is shown. Use NavUtils to allow users // to navigate up one level in the application structure. For // more details, see the Navigation pattern on Android Design: // // http://developer.android.com/design/patterns/navigation.html#up-vs-back // NavUtils.navigateUpFromSameTask(this); return true; default: return super.onOptionsItemSelected(item); } } /** * Set up the {@link android.app.ActionBar}, if the API is available. */ @TargetApi(Build.VERSION_CODES.HONEYCOMB) private void setupActionBar() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { getActionBar().setDisplayHomeAsUpEnabled(true); } } }