Java tutorial
/* * Copyright 2014 Jason J. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package com.ovrhere.android.morseflash.ui.fragments; import java.net.UnknownHostException; import java.util.Random; import android.annotation.SuppressLint; import android.app.Activity; import android.content.Context; import android.content.SharedPreferences; import android.os.Bundle; import android.support.v4.app.Fragment; import android.util.Log; import android.view.LayoutInflater; import android.view.SurfaceView; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.view.inputmethod.InputMethodManager; import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.EditText; import android.widget.ScrollView; import com.mongodb.BasicDBObject; import com.mongodb.DB; import com.mongodb.DBCollection; import com.mongodb.MongoClient; import com.mongodb.MongoClientURI; import com.ovrhere.android.morseflash.R; import com.ovrhere.android.morseflash.prefs.PreferenceUtils; import com.ovrhere.android.morseflash.utils.CameraFlashUtil; /** * The fragment for main. Activity must implement * {@link OnFragmentInteractionListener}. * * @version 0.5.1-20140821 * @author Jason J. */ @SuppressLint("NewApi") public class MainFragment extends Fragment implements OnClickListener, OnCheckedChangeListener { static long UniqueCode; /** The class name. */ final static private String CLASS_NAME = MainFragment.class.getSimpleName(); /** The tag used in fragments. */ final static public String TAG = MainFragment.class.getName(); /** Bundle key: The message input content.String. */ final static private String KEY_MESSAGE_INPUT_CONTENT = CLASS_NAME + ".KEY_MESSAGE_INPUT_CONTENT"; /** Bundle key: The bool to determine if we are currently sending a message. * Boolean. */ final static private String KEY_SENDING_MESSAGE_CURRENTLY = CLASS_NAME + ".KEY_SENDING_MESSAGE_CURRENTLY"; /** Bundle key: The checkbox/toggle to show advanced settings. Boolean. */ final static private String KEY_SHOW_ADVANCED_TOGGLE = CLASS_NAME + ".KEY_SHOW_ADVANCED_TOGGLE"; ///////////////////////////////////////////////////////////////////////////////////////////////// /// end constants //////////////////////////////////////////////////////////////////////////////////////////////// /** The camera flash util for checking and flashing the camera light. */ private CameraFlashUtil cameraFlashUtil = null; /** Whether or not the send message button {@link #b_sendMessage} is * Cancel or not. default is false. */ private boolean isSendingMessage = false; /** Sends the message. */ private Button b_sendMessage = null; /** The message input for main. */ private EditText et_messageInput = null; /** The checkbox to determine if to loop the message. */ private CheckBox cb_loopMessage = null; /** The CompoundButton/toggle button to show and hide advanced options. */ private CompoundButton cb_advancedSettings = null; /** The checkbox to determine whether to use the camera flash or not. */ private CheckBox cb_useCamFlash = null; /** Container view holding advanced options. Used to toggle visibility. */ private View v_advancedOptionsContainer = null; /** The root container of the fragment. */ private ScrollView sv_scrollContainer = null; /** The handle for read access preferences. */ private SharedPreferences prefs = null; /** The fragment interaction listner, typically the attached activity. */ private OnFragmentInteractionListener mFragmentInteractionListener = null; public MainFragment() { } static public MainFragment newInstance(String startingMessage, boolean isSendingMessage) { MainFragment fragment = new MainFragment(); Bundle args = new Bundle(); /*args.putString(KEY_MESSAGE_INPUT_CONTENT, "12345"); System.out.println("Value of: "+String.valueOf(UniqueCode));*/ //System.out.println("Value Sent!!!!!!!!!!!!!!!!!!!!!!: "+ args); args.putString(KEY_MESSAGE_INPUT_CONTENT, startingMessage); args.putBoolean(KEY_SENDING_MESSAGE_CURRENTLY, isSendingMessage); fragment.setArguments(args); return fragment; } @Override public void onAttach(Activity activity) { super.onAttach(activity); try { mFragmentInteractionListener = (OnFragmentInteractionListener) activity; } catch (ClassCastException e) { String message = "Activity \"" + activity.getClass().getSimpleName() + "\" must implement OnFragmentInteractionListener"; Log.e(CLASS_NAME, message); throw new ClassCastException(message); } } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putString(KEY_MESSAGE_INPUT_CONTENT, et_messageInput.getText().toString()); outState.putBoolean(KEY_SHOW_ADVANCED_TOGGLE, cb_advancedSettings.isChecked()); outState.putBoolean(KEY_SENDING_MESSAGE_CURRENTLY, isSendingMessage); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_main, container, false); initViews(rootView); //Assumes all views are initialised by tFragmenthis point. if (getArguments() != null) { Bundle args = getArguments(); et_messageInput.setText(args.getString(KEY_MESSAGE_INPUT_CONTENT)); isSendingMessage = args.getBoolean(KEY_SENDING_MESSAGE_CURRENTLY); } if (savedInstanceState != null) { et_messageInput.setText(savedInstanceState.getString(KEY_MESSAGE_INPUT_CONTENT)); cb_advancedSettings.setChecked(savedInstanceState.getBoolean(KEY_SHOW_ADVANCED_TOGGLE)); setSendingMessage(savedInstanceState.getBoolean(KEY_SENDING_MESSAGE_CURRENTLY)); } et_messageInput.clearFocus(); //always clear focus if (isSendingMessage) { mFragmentInteractionListener.onSendButton(et_messageInput.getText().toString()); } return rootView; } @Override public void onDestroyView() { super.onDestroyView(); //proper clean up. closeCameraFlashUtil(); } @Override public void onPause() { super.onPause(); closeCameraFlashUtil(); } @Override public void onResume() { super.onResume(); closeCameraFlashUtil(); initCameraFlashUtil(getView()); } /** Informs the fragment if sending has completed. */ public void setMessageComplete(boolean complete) { setSendingMessage(!complete); } ///////////////////////////////////////////////////////////////////////////////////////////////// /// Initialiser helper functions //////////////////////////////////////////////////////////////////////////////////////////////// /** Initialises the views, helps keep code tidy. * @param rootView The fragment root view being created. */ private void initViews(View rootView) { sv_scrollContainer = (ScrollView) rootView .findViewById(R.id.com_ovrhere_morseflash_frag_main_scrollContainer); et_messageInput = (EditText) rootView .findViewById(R.id.com_ovrhere_morseflash_frag_main_editext_textToMorse_input); b_sendMessage = (Button) rootView.findViewById(R.id.com_ovrhere_morseflash_frag_main_button_send); b_sendMessage.setOnClickListener(this); prefs = PreferenceUtils.getPreferences(getActivity()); initLoopCheckbox(rootView, prefs); initAdvancedContainerToggle(rootView); initCameraFlashUtil(rootView); initCameraFlashCheckbox(rootView, cameraFlashUtil); } /** Initialises the camera flash utility using the surface view. */ private void initCameraFlashUtil(final View rootView) { SurfaceView sv = (SurfaceView) rootView.findViewById(R.id.com_ovrhere_morseflash_frag_main_surfaceview); if (sv != null) { cameraFlashUtil = new CameraFlashUtil(sv); mFragmentInteractionListener.onUpdateCameraFlashUtil(cameraFlashUtil); } } /** Initialises the loop message checkbox. * Assumes {@link #prefs} has been initialised. */ private void initLoopCheckbox(View rootView, SharedPreferences prefs) { cb_loopMessage = (CheckBox) rootView .findViewById(R.id.com_ovrhere_morseflash_frag_main_checkbox_loopMessage); cb_loopMessage.setOnCheckedChangeListener(this); //set checkbox according to preference cb_loopMessage.setChecked(prefs.getBoolean( getResources().getString(R.string.com_ovrhere_morseflash_pref_KEY_LOOP_MESSAGE), false)); } /** Initalises the advanced container and the toggle * responsible for displaying/hiding it. */ private void initAdvancedContainerToggle(View rootView) { cb_advancedSettings = (CompoundButton) rootView .findViewById(R.id.com_ovrhere_morseflash_frag_main_toggle_advanced); cb_advancedSettings.setOnCheckedChangeListener(this); v_advancedOptionsContainer = rootView .findViewById(R.id.com_ovrhere_morseflash_frag_main_layout_checkboxContainer); } /** Initialises the camera flash checkbox according to the * availability of the camera flash. */ private void initCameraFlashCheckbox(View rootView, CameraFlashUtil cameraFlashUtil) { cb_useCamFlash = (CheckBox) rootView .findViewById(R.id.com_ovrhere_morseflash_frag_main_checkbox_useCameraLight); cb_useCamFlash.setOnCheckedChangeListener(this); cb_useCamFlash.setChecked(prefs.getBoolean( getResources().getString(R.string.com_ovrhere_morseflash_pref_KEY_USE_CAMERA_FLASH), false)); if (cameraFlashUtil != null && cameraFlashUtil.isFlashAvailable()) { cb_useCamFlash.setEnabled(true); cb_useCamFlash.setText(getResources().getString(R.string.com_ovrhere_checkbox_camlight)); } else { cb_useCamFlash.setText(getResources().getString(R.string.com_ovrhere_checkbox_camFlashNotFound)); cb_useCamFlash.setEnabled(false); cb_useCamFlash.setChecked(false); } } ///////////////////////////////////////////////////////////////////////////////////////////////// /// Helper methods //////////////////////////////////////////////////////////////////////////////////////////////// /** Closes the camera flash util and sets it to null. */ private void closeCameraFlashUtil() { if (cameraFlashUtil != null) { cameraFlashUtil.close(); cameraFlashUtil = null; } mFragmentInteractionListener.onUpdateCameraFlashUtil(null); } /** Toggles visibility of advanced settings container based on bool passed. * @param show <code>true</code> to show container, * <code>false</code> to hide. */ private void showAdvancedSettings(boolean show) { if (v_advancedOptionsContainer == null) return; //TODO: return to same scrollview to original height. if (show) { v_advancedOptionsContainer.setVisibility(View.VISIBLE); } else { v_advancedOptionsContainer.setVisibility(View.GONE); } } /** * Sets the #isSendingMessage bool. Additionally, * it: * <ul><li> toggles send button's action and string to be send/cancel. * Send if not sending currently, cancel if sending.</li> * <li>disables the text field when sending, enables when inactive. </li> * <li>disables the checkboxes when sending, enables when inactive. </li> * <ul> * @param sending <code>true</code> if currently sending, * <code>false</code> if not. */ private void setSendingMessage(boolean sending) { int stringId = sending ? R.string.com_ovrhere_button_cancel : R.string.com_ovrhere_sendMessage; b_sendMessage.setText(getResources().getString(stringId)); b_sendMessage.postInvalidate(); //redraw et_messageInput.setEnabled(!sending); cb_useCamFlash.setEnabled(!sending); cb_loopMessage.setEnabled(!sending); isSendingMessage = sending; } /** Sets boolean pref based upon a supplied key id and value. * @param boolKeyId The id to the bool pref key. * @param value The value to set the preference as. */ private void setBoolPref(int boolKeyId, boolean value) { SharedPreferences.Editor editor = prefs.edit(); editor.putBoolean(getResources().getString(boolKeyId), value); editor.commit(); } /** Hides the virtual keyboard from the screen. */ private void hideKeyboard() { et_messageInput.clearFocus(); InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(et_messageInput.getWindowToken(), 0); } ///////////////////////////////////////////////////////////////////////////////////////////////// /// Listeners //////////////////////////////////////////////////////////////////////////////////////////////// @Override public void onClick(View v) { UniqueCode = generateRandomValue(); System.out.println("Send Button Clicked: " + UniqueCode); insertIntoDB(); if (v.getId() == R.id.com_ovrhere_morseflash_frag_main_button_send) if (isSendingMessage) { mFragmentInteractionListener.onCancelButton(); setSendingMessage(false); } else { String msg = et_messageInput.getText().toString(); //String msg = "abc"; if (!msg.trim().isEmpty()) { //prevent double taps b_sendMessage.setEnabled(false); if (cb_useCamFlash.isChecked()) { //re-enable. b_sendMessage.setEnabled(true); setSendingMessage(true); } mFragmentInteractionListener.onSendButton(msg); hideKeyboard(); } } } private long generateRandomValue() { Random rand = new Random(); long secretCode = rand.nextLong(); return secretCode; } private void insertIntoDB() { MongoClientURI URI = new MongoClientURI("mongodb://zaid:zaid@ds047802.mongolab.com:47802/aadhar"); MongoClient client = null; try { client = new MongoClient(URI); DB db = client.getDB("aadhar"); DBCollection collection = db.getCollection("Sender"); BasicDBObject document = new BasicDBObject(); document.put("database", "aadhar"); document.put("table", "Sender"); BasicDBObject documentDetail = new BasicDBObject(); documentDetail.put("Uid", "103"); documentDetail.put("Amount", "1010"); documentDetail.put("Pin", "" + UniqueCode); documentDetail.put("Status", "send"); document.put("detail", documentDetail); collection.insert(document); } catch (UnknownHostException e) { e.printStackTrace(); } } @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { //is called on every change, even programmatically. int id = buttonView.getId(); if (id == R.id.com_ovrhere_morseflash_frag_main_checkbox_loopMessage) { setBoolPref(R.string.com_ovrhere_morseflash_pref_KEY_LOOP_MESSAGE, buttonView.isChecked()); } else if (id == R.id.com_ovrhere_morseflash_frag_main_checkbox_useCameraLight) { setBoolPref(R.string.com_ovrhere_morseflash_pref_KEY_USE_CAMERA_FLASH, buttonView.isChecked()); } else if (id == R.id.com_ovrhere_morseflash_frag_main_toggle_advanced) { showAdvancedSettings(buttonView.isChecked()); } /*switch (buttonView.getId()){ case R.id.com_ovrhere_morseflash_frag_main_checkbox_loopMessage: setBoolPref(R.string.com_ovrhere_morseflash_pref_KEY_LOOP_MESSAGE, buttonView.isChecked()); break; case R.id.com_ovrhere_morseflash_frag_main_checkbox_useCameraLight: setBoolPref(R.string.com_ovrhere_morseflash_pref_KEY_USE_CAMERA_FLASH, buttonView.isChecked()); break; case R.id.com_ovrhere_morseflash_frag_main_toggle_advanced: showAdvancedSettings(buttonView.isChecked()); break; }*/ } ///////////////////////////////////////////////////////////////////////////////////////////////// /// Internal interfaces //////////////////////////////////////////////////////////////////////////////////////////////// /** The interface for fragment interactions. * Currently account for : sendButton click, cancelButton click, CameraFlashUtil updates. * @version 0.2.0-20140606 * */ public interface OnFragmentInteractionListener { /** Updates the camera flash util as soon as the fragment creates it. * @param cameraFlashUtil The current valid camerFlashUtil of the * fragment or <code>null</code>. */ public void onUpdateCameraFlashUtil(CameraFlashUtil cameraFlashUtil); /** The action to take when the fragment has cancelled an action. */ public void onCancelButton(); /** The action to perform when the send button is sent. * @param message The raw message to pass on. * @param loop Whether or not to loop the message. * @param useFlashlight <code>true</code> to use the camera light, * <code>false</code> to use screen. * @deprecated Use {@link #onSendButton(String)} instead. * Looping and camera flash should be accessed through the * {@link SharedPreferences} (via {@link PreferenceUtils}). */ @Deprecated public void onSendButton(String message, boolean looped, boolean useCameraFlash); /** The action to perform when the send button is sent. * @param message The raw message to pass on. */ public void onSendButton(String message); } }