diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 6029d82..d22446d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -5,6 +5,7 @@ android:versionName="0.1.1" > + + + + + + + + + = Build.VERSION_CODES.GINGERBREAD_MR1) { + mNfcAdapter = NfcAdapter.getDefaultAdapter(this); + if (mNfcAdapter != null && + Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) + mNfcAdapter.setNdefPushMessageCallback(new NfcAdapter.CreateNdefMessageCallback() { + @Override + public NdefMessage createNdefMessage(NfcEvent nfcEvent) { + return getNdefMessage(); + } + }, this); + } + } + + @SuppressLint("NewApi") + @Override + public void onResume() { + super.onResume(); + + if (mNfcAdapter != null && + Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) { + mNfcAdapter.enableForegroundNdefPush(this, getNdefMessage()); + } + + // Check to see that the Activity started due to an Android Beam + if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction()) || + NfcAdapter.ACTION_TAG_DISCOVERED.equals(getIntent().getAction())) { + processIntent(getIntent()); + } + } + + private NdefMessage getNdefMessage() { + EditContactFragment f = (EditContactFragment) getSupportFragmentManager() + .findFragmentById(android.R.id.content); + return f.createNdefMessage(); + } + + @Override + public void onNewIntent(Intent intent) { + // onResume gets called after this to handle the intent + setIntent(intent); + } + + /** + * Parses the NDEF Message from the intent + */ + void processIntent(Intent intent) { + Parcelable[] rawMsgs = intent.getParcelableArrayExtra( + NfcAdapter.EXTRA_NDEF_MESSAGES); + if (rawMsgs == null || rawMsgs.length < 1) + return; // TODO notify user? + NdefMessage msg = (NdefMessage) rawMsgs[0]; + + NdefRecord[] records = msg.getRecords(); + if (records.length != 2) + return; // TODO notify user? + String name = new String(records[0].getPayload()); + String destination = new String(records[1].getPayload()); + + EditContactFragment f = EditContactFragment.newInstance( + name, destination); + getSupportFragmentManager().beginTransaction() + .replace(android.R.id.content, f).commit(); + } + + @SuppressLint("NewApi") + @Override + public void onPause() { + super.onPause(); + + if (mNfcAdapter != null && + Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) { + mNfcAdapter.disableForegroundNdefPush(this); } } } diff --git a/app/src/main/java/i2p/bote/android/addressbook/EditContactFragment.java b/app/src/main/java/i2p/bote/android/addressbook/EditContactFragment.java index 7a669b4..bcf1f22 100644 --- a/app/src/main/java/i2p/bote/android/addressbook/EditContactFragment.java +++ b/app/src/main/java/i2p/bote/android/addressbook/EditContactFragment.java @@ -1,5 +1,27 @@ package i2p.bote.android.addressbook; +import android.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.net.Uri; +import android.nfc.NdefMessage; +import android.nfc.NdefRecord; +import android.os.Build; +import android.os.Bundle; +import android.support.v4.app.DialogFragment; +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.Button; +import android.widget.EditText; +import android.widget.TextView; +import android.widget.Toast; + import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; @@ -13,35 +35,18 @@ import i2p.bote.android.util.BoteHelper; import i2p.bote.android.util.EditPictureFragment; import i2p.bote.fileencryption.PasswordException; import i2p.bote.packet.dht.Contact; -import android.app.Activity; -import android.app.AlertDialog; -import android.app.Dialog; -import android.content.DialogInterface; -import android.content.Intent; -import android.net.Uri; -import android.os.Bundle; -import android.support.v4.app.DialogFragment; -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.Button; -import android.widget.EditText; -import android.widget.TextView; -import android.widget.Toast; public class EditContactFragment extends EditPictureFragment { public static final String CONTACT_DESTINATION = "contact_destination"; + public static final String NEW_NAME = "new_name"; + public static final String NEW_DESTINATION = "new_destination"; static final int REQUEST_DESTINATION_FILE = 3; - - private String mDestination; EditText mNameField; EditText mDestinationField; EditText mTextField; TextView mError; + private String mDestination; public static EditContactFragment newInstance(String destination) { EditContactFragment f = new EditContactFragment(); @@ -51,6 +56,15 @@ public class EditContactFragment extends EditPictureFragment { return f; } + public static EditContactFragment newInstance(String name, String destination) { + EditContactFragment f = new EditContactFragment(); + Bundle args = new Bundle(); + args.putString(NEW_NAME, name); + args.putString(NEW_DESTINATION, destination); + f.setArguments(args); + return f; + } + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -59,7 +73,7 @@ public class EditContactFragment extends EditPictureFragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { + Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_edit_contact, container, false); } @@ -68,6 +82,7 @@ public class EditContactFragment extends EditPictureFragment { super.onViewCreated(view, savedInstanceState); mDestination = getArguments().getString(CONTACT_DESTINATION); + String newName = getArguments().getString(NEW_NAME); mNameField = (EditText) view.findViewById(R.id.contact_name); mDestinationField = (EditText) view.findViewById(R.id.destination); @@ -90,6 +105,9 @@ public class EditContactFragment extends EditPictureFragment { // TODO Handle e.printStackTrace(); } + } else if (newName != null) { + mNameField.setText(newName); + mDestinationField.setText(getArguments().getString(NEW_DESTINATION)); } Button b = (Button) view.findViewById(R.id.import_destination_from_file); @@ -100,7 +118,7 @@ public class EditContactFragment extends EditPictureFragment { i.addCategory(Intent.CATEGORY_OPENABLE); try { startActivityForResult( - Intent.createChooser(i,"Select file containing Email Destination"), + Intent.createChooser(i, "Select file containing Email Destination"), REQUEST_DESTINATION_FILE); } catch (android.content.ActivityNotFoundException ex) { Toast.makeText(getActivity(), "Please install a File Manager.", @@ -110,6 +128,42 @@ public class EditContactFragment extends EditPictureFragment { }); } + public NdefMessage createNdefMessage() { + NdefMessage msg = new NdefMessage(new NdefRecord[]{ + createNameRecord(), + createDestinationRecord() + }); + return msg; + } + + private NdefRecord createNameRecord() { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) + return new NdefRecord( + NdefRecord.TNF_EXTERNAL_TYPE, + "i2p.bote:contact".getBytes(), + new byte[0], + mNameField.getText().toString().getBytes() + ); + else + return NdefRecord.createExternal( + "i2p.bote", "contact", mNameField.getText().toString().getBytes() + ); + } + + private NdefRecord createDestinationRecord() { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) + return new NdefRecord( + NdefRecord.TNF_EXTERNAL_TYPE, + "i2p.bote:contactDestination".getBytes(), + new byte[0], + mDestinationField.getText().toString().getBytes() + ); + else + return NdefRecord.createExternal( + "i2p.bote", "contactDestination", mDestinationField.getText().toString().getBytes() + ); + } + @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.edit_contact, menu); @@ -118,70 +172,70 @@ public class EditContactFragment extends EditPictureFragment { @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { - case R.id.action_save_contact: - String picture = getPictureB64(); - String name = mNameField.getText().toString(); - String destination = mDestinationField.getText().toString(); - String text = mTextField.getText().toString(); + case R.id.action_save_contact: + String picture = getPictureB64(); + String name = mNameField.getText().toString(); + String destination = mDestinationField.getText().toString(); + String text = mTextField.getText().toString(); - mError.setText(""); + mError.setText(""); - try { - String err = BoteHelper.saveContact(destination, name, picture, text); - if (err == null) { - if (mDestination == null) // Only set if adding new contact - getActivity().setResult(Activity.RESULT_OK); - getActivity().finish(); - } else - mError.setText(err); - } catch (PasswordException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - mError.setText(e.getLocalizedMessage()); - } catch (GeneralSecurityException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - mError.setText(e.getLocalizedMessage()); - } - return true; - - case R.id.action_delete_contact: - DialogFragment df = new DialogFragment() { - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - builder.setMessage(R.string.delete_contact) - .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - dialog.dismiss(); - try { - String err = BoteHelper.deleteContact(mDestination); - if (err == null) { - getActivity().setResult(Activity.RESULT_OK); - getActivity().finish(); - } else - mError.setText(err); - } catch (PasswordException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (GeneralSecurityException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - }).setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - dialog.cancel(); - } - }); - return builder.create(); + try { + String err = BoteHelper.saveContact(destination, name, picture, text); + if (err == null) { + if (mDestination == null) // Only set if adding new contact + getActivity().setResult(Activity.RESULT_OK); + getActivity().finish(); + } else + mError.setText(err); + } catch (PasswordException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + mError.setText(e.getLocalizedMessage()); + } catch (GeneralSecurityException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + mError.setText(e.getLocalizedMessage()); } - }; - df.show(getActivity().getSupportFragmentManager(), "deletecontact"); - return true; + return true; - default: - return super.onOptionsItemSelected(item); + case R.id.action_delete_contact: + DialogFragment df = new DialogFragment() { + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + builder.setMessage(R.string.delete_contact) + .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + try { + String err = BoteHelper.deleteContact(mDestination); + if (err == null) { + getActivity().setResult(Activity.RESULT_OK); + getActivity().finish(); + } else + mError.setText(err); + } catch (PasswordException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (GeneralSecurityException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + }).setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + dialog.cancel(); + } + }); + return builder.create(); + } + }; + df.show(getActivity().getSupportFragmentManager(), "deletecontact"); + return true; + + default: + return super.onOptionsItemSelected(item); } } @@ -196,7 +250,8 @@ public class EditContactFragment extends EditPictureFragment { try { br = new BufferedReader( new InputStreamReader( - new FileInputStream(file))); + new FileInputStream(file)) + ); try { mDestinationField.setText(br.readLine()); } catch (IOException ioe) {