/** * Check if NFC adapter is enabled. If not, show the user a dialog and let him choose between * "Goto NFC Setting", "Use Editor Only" and "Exit App". Also enable NFC foreground dispatch * system. * * @see Common#enableNfcForegroundDispatch(Activity) */ private void checkNfc() { // Check if the NFC hardware is enabled. if (Common.getNfcAdapter() != null && !Common.getNfcAdapter().isEnabled()) { // NFC is disabled. Show dialog. mEnableNfc.show(); // Disable read/write tag options. mReadTag.setEnabled(false); mWriteTag.setEnabled(false); return; } else { // NFC is enabled. Hide dialog and enable NFC // foreground dispatch. if (mOldIntent != getIntent()) { int typeCheck = Common.treatAsNewTag(getIntent(), this); if (typeCheck == -1 || typeCheck == -2) { // Device or tag does not support Mifare Classic. // Run the only thing that is possible: The tag info tool. Intent i = new Intent(this, TagInfoToolActivity.class); startActivity(i); } mOldIntent = getIntent(); } Common.enableNfcForegroundDispatch(this); mEnableNfc.hide(); mReadTag.setEnabled(true); mWriteTag.setEnabled(true); } }
/** Add the menu with the tools. It will be shown if the user clicks on "Tools". */ @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); MenuInflater inflater = getMenuInflater(); menu.setHeaderTitle(R.string.dialog_tools_menu_title); menu.setHeaderIcon(android.R.drawable.ic_menu_preferences); inflater.inflate(R.menu.tools, menu); // Enable/Disable tag info tool depending on NFC availability. menu.findItem(R.id.menuMainTagInfo) .setEnabled(Common.getNfcAdapter() != null && Common.getNfcAdapter().isEnabled()); }
/** * Handle new Intent as a new tag Intent and if the tag/device does not support Mifare Classic, * then run {@link TagInfoToolActivity}. * * @see Common#treatAsNewTag(Intent, android.content.Context) * @see TagInfoToolActivity */ @Override public void onNewIntent(Intent intent) { int typeCheck = Common.treatAsNewTag(intent, this); if (typeCheck == -1 || typeCheck == -2) { // Device or tag does not support Mifare Classic. // Run the only thing that is possible: The tag info tool. Intent i = new Intent(this, TagInfoToolActivity.class); startActivity(i); } }
/** * Copy the standard key files ({@link Common#STD_KEYS} and {@link Common#STD_KEYS_EXTENDED}) form * assets to {@link Common#KEYS_DIR}. Key files are simple text files. Any plain text editor will * do the trick. All key and dump data from this App is stored in * getExternalStoragePublicDirectory(Common.HOME_DIR) to remain there after App uninstallation. * * @see Common#KEYS_DIR * @see Common#HOME_DIR * @see Common#copyFile(InputStream, OutputStream) */ private void copyStdKeysFilesIfNecessary() { File std = new File( Environment.getExternalStoragePublicDirectory(Common.HOME_DIR) + "/" + Common.KEYS_DIR, Common.STD_KEYS); File extended = new File( Environment.getExternalStoragePublicDirectory(Common.HOME_DIR) + "/" + Common.KEYS_DIR, Common.STD_KEYS_EXTENDED); AssetManager assetManager = getAssets(); if (!std.exists()) { // Copy std.keys. try { InputStream in = assetManager.open(Common.KEYS_DIR + "/" + Common.STD_KEYS); OutputStream out = new FileOutputStream(std); Common.copyFile(in, out); in.close(); out.flush(); out.close(); } catch (IOException e) { Log.e(LOG_TAG, "Error while copying 'std.keys' from assets " + "to external storage."); } } if (!extended.exists()) { // Copy extended-std.keys. try { InputStream in = assetManager.open(Common.KEYS_DIR + "/" + Common.STD_KEYS_EXTENDED); OutputStream out = new FileOutputStream(extended); Common.copyFile(in, out); in.close(); out.flush(); out.close(); } catch (IOException e) { Log.e( LOG_TAG, "Error while copying 'extended-std.keys' " + "from assets to external storage."); } } }
/** * Open a file chooser ({@link FileChooserActivity}). The Activity result will be processed in * {@link #onActivityResult(int, int, Intent)}. * * @param view The View object that triggered the method (in this case the show/edit key button). * @see FileChooserActivity * @see #onActivityResult(int, int, Intent) */ public void onOpenKeyEditor(View view) { if (Common.isExternalStorageWritableErrorToast(this)) { Intent intent = new Intent(this, FileChooserActivity.class); intent.putExtra( FileChooserActivity.EXTRA_DIR, Environment.getExternalStoragePublicDirectory(Common.HOME_DIR) + "/" + Common.KEYS_DIR); intent.putExtra( FileChooserActivity.EXTRA_TITLE, getString(R.string.text_open_key_file_title)); intent.putExtra( FileChooserActivity.EXTRA_BUTTON_TEXT, getString(R.string.action_open_key_file)); intent.putExtra(FileChooserActivity.EXTRA_ENABLE_NEW_FILE, true); intent.putExtra(FileChooserActivity.EXTRA_ENABLE_DELETE_FILE, true); startActivityForResult(intent, FILE_CHOOSER_KEY_FILE); } }
/** * Open a file chooser ({@link FileChooserActivity}). The Activity result will be processed in * {@link #onActivityResult(int, int, Intent)}. If the dump files folder is empty display an * additional error message. * * @param view The View object that triggered the method (in this case the show/edit tag dump * button). * @see FileChooserActivity * @see #onActivityResult(int, int, Intent) */ public void onOpenTagDumpEditor(View view) { String dumpsDir = Environment.getExternalStoragePublicDirectory(Common.HOME_DIR) + "/" + Common.DUMPS_DIR; if (Common.isExternalStorageWritableErrorToast(this)) { File file = new File(dumpsDir); if (file.isDirectory() && (file.listFiles() == null || file.listFiles().length == 0)) { Toast.makeText(this, R.string.info_no_dumps, Toast.LENGTH_LONG).show(); } Intent intent = new Intent(this, FileChooserActivity.class); intent.putExtra(FileChooserActivity.EXTRA_DIR, dumpsDir); intent.putExtra(FileChooserActivity.EXTRA_TITLE, getString(R.string.text_open_dump_title)); intent.putExtra( FileChooserActivity.EXTRA_BUTTON_TEXT, getString(R.string.action_open_dump_file)); intent.putExtra(FileChooserActivity.EXTRA_ENABLE_DELETE_FILE, true); startActivityForResult(intent, FILE_CHOOSER_DUMP_FILE); } }
/** * Check for NFC hardware, Mifare Classic support and for external storage. If the directory * structure and the std. keys files is not already there it will be created. Also, at the first * run of this App, a warning notice will be displayed. * * @see #copyStdKeysFilesIfNecessary() */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Show App version and footer. TextView tv = (TextView) findViewById(R.id.textViewMainFooter); tv.setMovementMethod(LinkMovementMethod.getInstance()); try { String appVersion = getPackageManager().getPackageInfo(getPackageName(), 0).versionName; tv.setText( TextUtils.concat( getString(R.string.app_version), ": ", appVersion, " - ", getText(R.string.text_footer))); } catch (NameNotFoundException e) { Log.d(LOG_TAG, "Version not found."); } // Add the context menu to the tools button. Button tools = (Button) findViewById(R.id.buttonMainTools); registerForContextMenu(tools); // Check if there is an NFC hardware component. Common.setNfcAdapter(NfcAdapter.getDefaultAdapter(this)); if (Common.getNfcAdapter() == null) { new AlertDialog.Builder(this) .setTitle(R.string.dialog_no_nfc_title) .setMessage(R.string.dialog_no_nfc) .setIcon(android.R.drawable.ic_dialog_alert) .setPositiveButton( R.string.action_exit_app, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { finish(); } }) .setOnCancelListener( new DialogInterface.OnCancelListener() { @Override public void onCancel(DialogInterface dialog) { finish(); } }) .show(); mResume = false; return; } if (Common.isExternalStorageWritableErrorToast(this)) { // Create keys directory. File path = new File( Environment.getExternalStoragePublicDirectory(Common.HOME_DIR) + "/" + Common.KEYS_DIR); if (path.exists() == false && !path.mkdirs()) { // Could not create directory. Log.e( LOG_TAG, "Error while crating '" + Common.HOME_DIR + "/" + Common.KEYS_DIR + "' directory."); return; } // Create dumps directory. path = new File( Environment.getExternalStoragePublicDirectory(Common.HOME_DIR) + "/" + Common.DUMPS_DIR); if (path.exists() == false && !path.mkdirs()) { // Could not create directory. Log.e( LOG_TAG, "Error while crating '" + Common.HOME_DIR + "/" + Common.DUMPS_DIR + "' directory."); return; } // Create tmp directory. path = new File( Environment.getExternalStoragePublicDirectory(Common.HOME_DIR) + "/" + Common.TMP_DIR); if (path.exists() == false && !path.mkdirs()) { // Could not create directory. Log.e(LOG_TAG, "Error while crating '" + Common.HOME_DIR + Common.TMP_DIR + "' directory."); return; } // Clean up tmp directory. for (File file : path.listFiles()) { file.delete(); } // Create std. key file if there is none. copyStdKeysFilesIfNecessary(); } // Find Read/Write buttons and bind them to member vars. mReadTag = (Button) findViewById(R.id.buttonMainReadTag); mWriteTag = (Button) findViewById(R.id.buttonMainWriteTag); // Create a dialog that send user to NFC settings if NFC is off. // (Or let the user use the App in editor only mode / exit the App.) mEnableNfc = new AlertDialog.Builder(this) .setTitle(R.string.dialog_nfc_not_enabled_title) .setMessage(R.string.dialog_nfc_not_enabled) .setIcon(android.R.drawable.ic_dialog_info) .setPositiveButton( R.string.action_nfc, new DialogInterface.OnClickListener() { @Override @SuppressLint("InlinedApi") public void onClick(DialogInterface dialog, int which) { // Goto NFC Settings. if (Build.VERSION.SDK_INT >= 16) { startActivity(new Intent(Settings.ACTION_NFC_SETTINGS)); } else { startActivity(new Intent(Settings.ACTION_WIRELESS_SETTINGS)); } } }) .setNeutralButton( R.string.action_editor_only, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // Only use Editor. Do nothing. } }) .setNegativeButton( R.string.action_exit_app, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int id) { // Exit the App. finish(); } }) .create(); // Show first usage notice. SharedPreferences sharedPref = getPreferences(Context.MODE_PRIVATE); boolean isFirstRun = sharedPref.getBoolean("is_first_run", true); if (isFirstRun) { Editor e = sharedPref.edit(); e.putBoolean("is_first_run", false); e.commit(); new AlertDialog.Builder(this) .setTitle(R.string.dialog_first_run_title) .setIcon(android.R.drawable.ic_dialog_alert) .setMessage(R.string.dialog_first_run) .setPositiveButton( R.string.action_ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.cancel(); } }) .setOnCancelListener( new DialogInterface.OnCancelListener() { @Override public void onCancel(DialogInterface dialog) { mResume = true; checkNfc(); } }) .show(); mResume = false; } }
/** * Disable NFC foreground dispatch system. * * @see Common#disableNfcForegroundDispatch(Activity) */ @Override public void onPause() { super.onPause(); Common.disableNfcForegroundDispatch(this); }