Android Open Source - HockeySDK-Android Feedback Activity






From Project

Back to project page HockeySDK-Android.

License

The source code is released under:

Apache License

If you think the Android project HockeySDK-Android listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package net.hockeyapp.android;
/*from w w w.  j a  v  a2  s  . co m*/
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.NotificationManager;
import android.content.*;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.view.*;
import android.view.View.OnClickListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.*;
import net.hockeyapp.android.adapters.MessagesAdapter;
import net.hockeyapp.android.objects.ErrorObject;
import net.hockeyapp.android.objects.FeedbackMessage;
import net.hockeyapp.android.objects.FeedbackResponse;
import net.hockeyapp.android.tasks.ParseFeedbackTask;
import net.hockeyapp.android.tasks.SendFeedbackTask;
import net.hockeyapp.android.utils.AsyncTaskUtils;
import net.hockeyapp.android.utils.PrefsUtil;
import net.hockeyapp.android.utils.Util;
import net.hockeyapp.android.views.AttachmentListView;
import net.hockeyapp.android.views.AttachmentView;
import net.hockeyapp.android.views.FeedbackView;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * <h3>Description</h3>
 *
 * Activity to show the feedback form.
 *
 * <h3>License</h3>
 *
 * <pre>
 * Copyright (c) 2011-2014 Bit Stadium GmbH
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 * </pre>
 *
 * @author Bogdan Nistor
 * @author Patrick Eschenbach
 * @author Thomas Dohmke
 **/
public class FeedbackActivity extends Activity implements FeedbackActivityInterface, OnClickListener {
  /** Number of attachments allowed per message. **/
  private static final int MAX_ATTACHMENTS_PER_MSG = 3;

  /** ID of error dialog **/
  private final int DIALOG_ERROR_ID = 0;
  /** Activity request constants for ContextMenu and Chooser Intent */
  private final int ATTACH_PICTURE = 1;
  private final int ATTACH_FILE = 2;
  private final int PAINT_IMAGE = 3;
  /** Reference to this **/
  private Context context;
  /** Widgets and layout **/
  private TextView lastUpdatedTextView;
  private EditText nameInput;
  private EditText emailInput;
  private EditText subjectInput;
  private EditText textInput;
  private Button sendFeedbackButton;
  private Button addAttachmentButton;
  private Button addResponseButton;
  private Button refreshButton;
  private ScrollView feedbackScrollView;
  private LinearLayout wrapperLayoutFeedbackAndMessages;
  private ListView messagesListView;
  /** Send feedback {@link AsyncTask} */
  private SendFeedbackTask sendFeedbackTask;
  private Handler feedbackHandler;

  /** Parse feedback {@link AsyncTask} */
  private ParseFeedbackTask parseFeedbackTask;
  private Handler parseFeedbackHandler;

  /** URL for HockeyApp API **/
  private String url;

  /** Current error for alert dialog **/
  private ErrorObject error;

  /** Message data source **/
  private MessagesAdapter messagesAdapter;
  private ArrayList<FeedbackMessage> feedbackMessages;

  /** True when a message is posted **/
  private boolean inSendFeedback;

  /** True when the view was initialized **/
  private boolean feedbackViewInitialized;

  /** Unique token of the message feed **/
  private String token;

  /**
   * Enables/Disables the Send Feedback button.
   *
   * @param isEnable the button is enabled if true
   */
  public void enableDisableSendFeedbackButton(boolean isEnable) {
    if (sendFeedbackButton != null) {
      sendFeedbackButton.setEnabled(isEnable);
    }
  }

  /**
   * Creates and returns a new instance of {@link FeedbackView}
   *
   * @return Instance of {@link FeedbackView}
   */
  public ViewGroup getLayoutView() {
    return new FeedbackView(this);
  }

  /**
   * Called when the Send Feedback {@link Button} is tapped. Sends the feedback and disables
   * the button to avoid multiple taps.
   */
  @Override
  public void onClick(View v) {
    switch (v.getId()) {
      case FeedbackView.SEND_FEEDBACK_BUTTON_ID:
        sendFeedback();
        break;

      case FeedbackView.ADD_ATTACHMENT_BUTTON_ID:
        ViewGroup attachments = (ViewGroup) findViewById(FeedbackView.WRAPPER_LAYOUT_ATTACHMENTS);
        if (attachments.getChildCount() >= MAX_ATTACHMENTS_PER_MSG) {
          Toast.makeText(this, "Only " + MAX_ATTACHMENTS_PER_MSG + " attachments allowed.", 1000).show();
        } else {
          openContextMenu(v);
        }
        break;

      case FeedbackView.ADD_RESPONSE_BUTTON_ID:
        configureFeedbackView(false);
        inSendFeedback = true;
        break;

      case FeedbackView.REFRESH_BUTTON_ID:
        sendFetchFeedback(url, null, null, null, null, null, PrefsUtil.getInstance().getFeedbackTokenFromPrefs(context), feedbackHandler, true);
        break;

      default:
        break;
    }
  }

  /**
   * Called when user clicked on context menu item.
   */
  @Override
  public boolean onContextItemSelected(MenuItem item) {
    switch (item.getItemId()) {
      case ATTACH_FILE:
      case ATTACH_PICTURE:
        return addAttachment(item.getItemId());

      default:
        return super.onContextItemSelected(item);
    }
  }

  /**
   * Called when the activity is starting. Sets the title and content view
   *
   * @param savedInstanceState Data it most recently supplied in
   *                           onSaveInstanceState(Bundle)
   */
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(getLayoutView());

    setTitle(Strings.get(Strings.FEEDBACK_TITLE_ID));
    context = this;

    Bundle extras = getIntent().getExtras();
    if (extras != null) {
      url = extras.getString("url");
    }

    if (savedInstanceState != null) {
      feedbackViewInitialized = savedInstanceState.getBoolean("feedbackViewInitialized");
      inSendFeedback = savedInstanceState.getBoolean("inSendFeedback");
    }
    else {
      inSendFeedback = false;
      feedbackViewInitialized = false;
    }

    // Cancel notification
    NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    notificationManager.cancel(ParseFeedbackTask.NEW_ANSWER_NOTIFICATION_ID);

    initFeedbackHandler();
    initParseFeedbackHandler();
    configureAppropriateView();
  }

  /**
   * Called when context menu is needed (on add attachment button).
   */
  @Override
  public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
    super.onCreateContextMenu(menu, v, menuInfo);

    menu.add(0, ATTACH_FILE, 0, "Attach File");
    menu.add(0, ATTACH_PICTURE, 0, "Attach Picture");
  }

  @Override
  public boolean onKeyDown(int keyCode, KeyEvent event)  {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
      if (inSendFeedback) {
        inSendFeedback = false;
        configureAppropriateView();
      } else {
        finish();
      }

      return true;
    }

    return super.onKeyDown(keyCode, event);
  }

  /**
   * Detaches the activity from the send feedback task and returns the task
   * as last instance. This way the task is restored when the activity
   * is immediately re-created.
   *
   * @return The download task if present.
   */
  @Override
  public Object onRetainNonConfigurationInstance() {
    if (sendFeedbackTask != null) {
      sendFeedbackTask.detach();
    }

    return sendFeedbackTask;
  }

  /**
   * Configures the content view by initializing the input {@link EditText}s
   * and the listener for the Send Feedback {@link Button}
   *
   * @param haveToken the message list is shown if true
   */
  protected void configureFeedbackView(boolean haveToken) {
    feedbackScrollView = (ScrollView) findViewById(FeedbackView.FEEDBACK_SCROLLVIEW_ID);
    wrapperLayoutFeedbackAndMessages = (LinearLayout) findViewById(FeedbackView.WRAPPER_LAYOUT_FEEDBACK_AND_MESSAGES_ID);
    messagesListView = (ListView) findViewById(FeedbackView.MESSAGES_LISTVIEW_ID);

    if (haveToken) {
      /** If a token exists, the list of messages should be displayed */
      wrapperLayoutFeedbackAndMessages.setVisibility(View.VISIBLE);
      feedbackScrollView.setVisibility(View.GONE);

      lastUpdatedTextView = (TextView) findViewById(FeedbackView.LAST_UPDATED_TEXT_VIEW_ID);

      addResponseButton = (Button) findViewById(FeedbackView.ADD_RESPONSE_BUTTON_ID);
      addResponseButton.setOnClickListener(this);

      refreshButton = (Button) findViewById(FeedbackView.REFRESH_BUTTON_ID);
      refreshButton.setOnClickListener(this);
    }
    else {
      /** if the token doesn't exist, the feedback details inputs to be sent need to be displayed */
      wrapperLayoutFeedbackAndMessages.setVisibility(View.GONE);
      feedbackScrollView.setVisibility(View.VISIBLE);

      nameInput = (EditText)findViewById(FeedbackView.NAME_EDIT_TEXT_ID);
      emailInput = (EditText)findViewById(FeedbackView.EMAIL_EDIT_TEXT_ID);
      subjectInput = (EditText)findViewById(FeedbackView.SUBJECT_EDIT_TEXT_ID);
      textInput = (EditText)findViewById(FeedbackView.TEXT_EDIT_TEXT_ID);

      /** Check to see if the Name and Email are saved in {@link SharedPreferences} */
      if (!feedbackViewInitialized) {
        String nameEmailSubject = PrefsUtil.getInstance().getNameEmailFromPrefs(context);
        if (nameEmailSubject != null) {
          /** We have Name and Email. Prepopulate the appropriate fields */
          String[] nameEmailSubjectArray = nameEmailSubject.split("\\|");
          if (nameEmailSubjectArray != null && nameEmailSubjectArray.length >= 2) {
            nameInput.setText(nameEmailSubjectArray[0]);
            emailInput.setText(nameEmailSubjectArray[1]);

            if (nameEmailSubjectArray.length >= 3) {
              subjectInput.setText(nameEmailSubjectArray[2]);
              textInput.requestFocus();
            }
            else {
              subjectInput.requestFocus();
            }
          }
        }
        else {
          /** We dont have Name and Email. Reset those fields */
          nameInput.setText("");
          emailInput.setText("");
          subjectInput.setText("");
          nameInput.requestFocus();
        }

        feedbackViewInitialized = true;
      }

      /** Reset the remaining fields if previously populated */
      textInput.setText("");

      /** Check to see if the Feedback Token is availabe */
      if (PrefsUtil.getInstance().getFeedbackTokenFromPrefs(context) != null) {
        /** If Feedback Token is available, hide the Subject Input field */
        subjectInput.setVisibility(View.GONE);
      }
      else {
        /** If Feedback Token is not available, display the Subject Input field */
        subjectInput.setVisibility(View.VISIBLE);
      }

      /** Reset the attachment list */
      ViewGroup attachmentListView = (ViewGroup)findViewById(FeedbackView.WRAPPER_LAYOUT_ATTACHMENTS);
      attachmentListView.removeAllViews();

      /** Use of context menu needs to be enabled explicitly */
      addAttachmentButton = (Button)findViewById(FeedbackView.ADD_ATTACHMENT_BUTTON_ID);
      addAttachmentButton.setOnClickListener(this);
      registerForContextMenu(addAttachmentButton);

      sendFeedbackButton = (Button)findViewById(FeedbackView.SEND_FEEDBACK_BUTTON_ID);
      sendFeedbackButton.setOnClickListener(this);
    }
  }

  /**
   * Called when picture or file was chosen.
   */
  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode != RESULT_OK) {
      return;
    }

    if (requestCode == ATTACH_FILE) {
      /** User picked file */
      Uri uri = data.getData();

      if (uri != null) {
        final ViewGroup attachments = (ViewGroup) findViewById(FeedbackView.WRAPPER_LAYOUT_ATTACHMENTS);
        attachments.addView(new AttachmentView(this, attachments, uri, true));
      }

    } else if (requestCode == ATTACH_PICTURE) {
      /** User picked image */
      Uri uri = data.getData();

      /** Start PaintActivity */
      if (uri != null) {
        try {
          Intent intent = new Intent(this, PaintActivity.class);
          intent.putExtra("imageUri", uri);
          startActivityForResult(intent, PAINT_IMAGE);
        } catch (ActivityNotFoundException e) {
          Log.e(Util.LOG_IDENTIFIER, "Paint activity not declared!", e);
        }

      }

    } else if (requestCode == PAINT_IMAGE) {
      /** Final attachment picture received and ready to be added to list. */
      Uri uri = data.getParcelableExtra("imageUri");

      if (uri != null) {
        final ViewGroup attachments = (ViewGroup) findViewById(FeedbackView.WRAPPER_LAYOUT_ATTACHMENTS);
        attachments.addView(new AttachmentView(this, attachments, uri, true));
      }

    } else return;
  }

  @Override
  protected Dialog onCreateDialog(int id) {
    switch(id) {
      case DIALOG_ERROR_ID:
        return new AlertDialog.Builder(this)
          .setMessage("An error has occured")
          .setCancelable(false)
          .setTitle("Error")
          .setIcon(android.R.drawable.ic_dialog_alert)
          .setPositiveButton("OK", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
              error = null;
              dialog.cancel();
            }
          }).create();
    }

    return null;
  }

  @Override
  protected void onPrepareDialog(int id, Dialog dialog) {
    switch(id) {
    case DIALOG_ERROR_ID:
      AlertDialog messageDialogError = (AlertDialog) dialog;
      if (error != null) {
        /** If the ErrorObject is not null, display the ErrorObject message */
        messageDialogError.setMessage(error.getMessage());
      } else {
        /** If the ErrorObject is null, display the general error message */
        messageDialogError.setMessage(Strings.get(Strings.FEEDBACK_GENERIC_ERROR_ID));
      }

      break;
    }
  }

  /**
   * Restore all attachments.
   */
  @Override
  protected void onRestoreInstanceState(Bundle savedInstanceState) {
    if (savedInstanceState != null) {
      ViewGroup attachmentList = (ViewGroup) findViewById(FeedbackView.WRAPPER_LAYOUT_ATTACHMENTS);
      ArrayList<Uri> attachmentsUris = savedInstanceState.getParcelableArrayList("attachments");
      for (Uri attachmentUri : attachmentsUris) {
        attachmentList.addView(new AttachmentView(this, attachmentList, attachmentUri, true));
      }

      feedbackViewInitialized = savedInstanceState.getBoolean("feedbackViewInitialized");
    }

    super.onRestoreInstanceState(savedInstanceState);
  }

  /**
   * Save all attachments.
   */
  @Override
  protected void onSaveInstanceState(Bundle outState) {
    AttachmentListView attachmentListView = (AttachmentListView) findViewById(FeedbackView.WRAPPER_LAYOUT_ATTACHMENTS);

    outState.putParcelableArrayList("attachments", attachmentListView.getAttachments());
    outState.putBoolean("feedbackViewInitialized", feedbackViewInitialized);
    outState.putBoolean("inSendFeedback", inSendFeedback);

    super.onSaveInstanceState(outState);
  }

  /**
   * Adds either file or picture attachment by intent picker.
   *
   * @param request Either ATTACH_FILE or ATTACH_PICTURE.
   */
  private boolean addAttachment(int request) {
    if (request == ATTACH_FILE) {
      Intent intent = new Intent();
      intent.setType("*/*");
      intent.setAction(Intent.ACTION_GET_CONTENT);
      startActivityForResult(Intent.createChooser(intent, "Select File"), ATTACH_FILE);
      return true;

    } else if (request == ATTACH_PICTURE) {
      Intent intent = new Intent();
      intent.setType("image/*");
      intent.setAction(Intent.ACTION_GET_CONTENT);
      startActivityForResult(Intent.createChooser(intent, "Select Picture"), ATTACH_PICTURE);
      return true;

    } else return false;
  }

  private void configureAppropriateView() {
    /** Try to retrieve the Feedback Token from {@link SharedPreferences} */
    token = PrefsUtil.getInstance().getFeedbackTokenFromPrefs(this);
    if ((token == null) || (inSendFeedback)) {
      /** If Feedback Token is NULL, show the usual {@link FeedbackView} */
      configureFeedbackView(false);
    }
    else {
      /** If Feedback Token is NOT NULL, show the Add Response Button and fetch the feedback messages */
      configureFeedbackView(true);
      sendFetchFeedback(url, null, null, null, null, null, token, feedbackHandler, true);
    }
  }

  /**
   * Initializes the {@link ParseFeedbackTask}
   * @param feedbackResponseString  JSON string response
   */
  private void createParseFeedbackTask(String feedbackResponseString, String requestType) {
    parseFeedbackTask = new ParseFeedbackTask(this, feedbackResponseString, parseFeedbackHandler, requestType);
  }

  private void hideKeyboard() {
    if (textInput != null) {
      InputMethodManager manager = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
      manager.hideSoftInputFromWindow(textInput.getWindowToken(), 0);
    }
  }

  /**
   * Initializes the Feedback response {@link Handler}
   */
  private void initFeedbackHandler() {
    feedbackHandler = new Handler() {
      @Override
      public void handleMessage(Message msg) {
        boolean success = false;
        error = new ErrorObject();

        if (msg != null && msg.getData() != null) {
          Bundle bundle = msg.getData();
          String responseString = bundle.getString("feedback_response");
          String statusCode = bundle.getString("feedback_status");
          String requestType = bundle.getString("request_type");
          if ((requestType.equals("send") && ((responseString == null) || (Integer.parseInt(statusCode) != 201)))) {
            // Send feedback went wrong if response is empty or status code != 201
            error.setMessage(Strings.get(Strings.FEEDBACK_SEND_GENERIC_ERROR_ID));
          }
          else if ((requestType.equals("fetch") && (statusCode != null) && ((Integer.parseInt(statusCode) == 404) || (Integer.parseInt(statusCode) == 422)))) {
            // Fetch feedback went wrong if status code is 404 or 422
            resetFeedbackView();
            success = true;
          }
          else if (responseString != null) {
            startParseFeedbackTask(responseString, requestType);
            success = true;
          }
          else {
            error.setMessage(Strings.get(Strings.FEEDBACK_SEND_NETWORK_ERROR_ID));
          }
        }
        else {
          error.setMessage(Strings.get(Strings.FEEDBACK_SEND_GENERIC_ERROR_ID));
        }

        if (!success) {
          runOnUiThread(new Runnable() {

            @SuppressWarnings("deprecation")
            @Override
            public void run() {
              enableDisableSendFeedbackButton(true);
              showDialog(DIALOG_ERROR_ID);
            }
          });
        }
      }
    };
  }

  /**
   * Initialize the Feedback response parse result {@link Handler}
   */
  private void initParseFeedbackHandler() {
    parseFeedbackHandler = new Handler() {
      @Override
      public void handleMessage(Message msg) {
        boolean success = false;
        error = new ErrorObject();

        if (msg != null && msg.getData() != null) {
          Bundle bundle = msg.getData();
          FeedbackResponse feedbackResponse = (FeedbackResponse) bundle.getSerializable("parse_feedback_response");
          if (feedbackResponse != null) {
            if (feedbackResponse.getStatus().equalsIgnoreCase("success")) {
              /** We have a valid result from JSON parsing */
              success = true;

              if (feedbackResponse.getToken() != null) {
                /** Save the Token to SharedPreferences */
                PrefsUtil.getInstance().saveFeedbackTokenToPrefs(context, feedbackResponse.getToken());
                /** Load the existing feedback messages */
                loadFeedbackMessages(feedbackResponse);
                inSendFeedback = false;
              }
            }
            else {
              success = false;
            }
          }
        }

        /** Something went wrong, so display an error dialog */
        if (!success) {
          runOnUiThread(new Runnable() {

            @SuppressWarnings("deprecation")
            @Override
            public void run() {
              showDialog(DIALOG_ERROR_ID);
            }
          });
        }

        enableDisableSendFeedbackButton(true);
      }
    };
  }

  /**
   * Load the feedback messages fetched from server
   * @param feedbackResponse  {@link FeedbackResponse} object
   */
  private void loadFeedbackMessages(final FeedbackResponse feedbackResponse) {
    runOnUiThread(new Runnable() {

      @Override
      public void run() {
        configureFeedbackView(true);

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
        SimpleDateFormat formatNew = new SimpleDateFormat("d MMM h:mm a");

        Date date = null;
        if (feedbackResponse != null && feedbackResponse.getFeedback() != null &&
            feedbackResponse.getFeedback().getMessages() != null && feedbackResponse.
            getFeedback().getMessages().size() > 0) {

          feedbackMessages = feedbackResponse.getFeedback().getMessages();
          /** Reverse the order of the feedback messages list, so we show the latest one first */
          Collections.reverse(feedbackMessages);

          /** Set the lastUpdatedTextView text as the date of the latest feedback message */
          try {
            date = format.parse(feedbackMessages.get(0).getCreatedAt());
            lastUpdatedTextView.setText(String.format("Last Updated: %s", formatNew.format(date)));
          }
          catch (ParseException e1) {
            e1.printStackTrace();
          }

          if (messagesAdapter == null) {
            messagesAdapter = new MessagesAdapter(context, feedbackMessages);
          }
          else {
            messagesAdapter.clear();
            for (FeedbackMessage message : feedbackMessages) {
              messagesAdapter.add(message);
            }

            messagesAdapter.notifyDataSetChanged();
          }

          messagesListView.setAdapter(messagesAdapter);
        }
      }
    });
  }

  private void resetFeedbackView() {
    runOnUiThread(new Runnable() {
      @Override
      public void run() {
        PrefsUtil.getInstance().saveFeedbackTokenToPrefs(FeedbackActivity.this, null);

        SharedPreferences preferences = getSharedPreferences(ParseFeedbackTask.PREFERENCES_NAME, 0);
        PrefsUtil.applyChanges(preferences.edit()
            .remove(ParseFeedbackTask.ID_LAST_MESSAGE_SEND)
            .remove(ParseFeedbackTask.ID_LAST_MESSAGE_PROCESSED));

        configureFeedbackView(false);
      }
    });
  }

  /**
   * Send feedback to HockeyApp.
   */
  private void sendFeedback() {
    enableDisableSendFeedbackButton(false);
    hideKeyboard();

    String token = PrefsUtil.getInstance().getFeedbackTokenFromPrefs(context);

    String name = nameInput.getText().toString().trim();
    String email = emailInput.getText().toString().trim();
    String subject = subjectInput.getText().toString().trim();
    String text = textInput.getText().toString().trim();

    if(TextUtils.isEmpty(subject)){
      subjectInput.setVisibility(View.VISIBLE);
      setError(subjectInput, Strings.FEEDBACK_VALIDATE_SUBJECT_ERROR_ID);
    }
    else if (TextUtils.isEmpty(name)) {
      setError(nameInput, Strings.FEEDBACK_VALIDATE_NAME_ERROR_ID);
    }
    else if (TextUtils.isEmpty(email)) {
      setError(emailInput, Strings.FEEDBACK_VALIDATE_EMAIL_EMPTY_ID);
    }
    else if(TextUtils.isEmpty(text)) {
      setError(textInput, Strings.FEEDBACK_VALIDATE_TEXT_ERROR_ID);
    }
    else if (!Util.isValidEmail(email)) {
      setError(emailInput, Strings.FEEDBACK_VALIDATE_EMAIL_ERROR_ID);
    }
    else {
      /** Save Name and Email to {@link SharedPreferences} */
      PrefsUtil.getInstance().saveNameEmailSubjectToPrefs(context, name, email, subject);

      /** Make list for attachments file paths */
      AttachmentListView attachmentListView = (AttachmentListView) findViewById(FeedbackView.WRAPPER_LAYOUT_ATTACHMENTS);
      List<Uri> attachmentUris = attachmentListView.getAttachments();

      /** Start the Send Feedback {@link AsyncTask} */
      sendFetchFeedback(url, name, email, subject, text, attachmentUris, token, feedbackHandler, false);
    }
  }

   private void setError(EditText inputField, int feedbackStringId) {
      inputField.setError(Strings.get(feedbackStringId));
      enableDisableSendFeedbackButton(true);
   }

   /**
   * Initialize the {@link SendFeedbackTask}
   * @param url             URL to HockeyApp API
   * @param name            Name of the feedback sender
   * @param email           Email of the feedback sender
   * @param subject         Message subject
   * @param text            The message
   * @param token           Token for message feed
   * @param feedbackHandler Handler to handle the response
   * @param isFetchMessages Set true to fetch messages, false to send one
   */
  private void sendFetchFeedback(String url, String name, String email, String subject, String text, List<Uri> attachmentUris, String token, Handler feedbackHandler, boolean isFetchMessages) {
    sendFeedbackTask = new SendFeedbackTask(context, url, name, email, subject, text, attachmentUris, token, feedbackHandler, isFetchMessages);
    AsyncTaskUtils.execute(sendFeedbackTask);
  }

  /**
   * Creates and starts execution of the {@link ParseFeedbackTask}
   * @param feedbackResponseString  JSON string response
   */
  private void startParseFeedbackTask(String feedbackResponseString, String requestType) {
    createParseFeedbackTask(feedbackResponseString, requestType);
    AsyncTaskUtils.execute(parseFeedbackTask);
  }
}




Java Source Code List

net.hockeyapp.android.Constants.java
net.hockeyapp.android.CrashManagerListener.java
net.hockeyapp.android.CrashManager.java
net.hockeyapp.android.ExceptionHandler.java
net.hockeyapp.android.ExpiryInfoActivity.java
net.hockeyapp.android.FeedbackActivityInterface.java
net.hockeyapp.android.FeedbackActivity.java
net.hockeyapp.android.FeedbackManagerListener.java
net.hockeyapp.android.FeedbackManager.java
net.hockeyapp.android.LocaleManager.java
net.hockeyapp.android.LoginActivity.java
net.hockeyapp.android.LoginManagerListener.java
net.hockeyapp.android.LoginManager.java
net.hockeyapp.android.PaintActivity.java
net.hockeyapp.android.StringListener.java
net.hockeyapp.android.Strings.java
net.hockeyapp.android.Tracking.java
net.hockeyapp.android.UpdateActivityInterface.java
net.hockeyapp.android.UpdateActivity.java
net.hockeyapp.android.UpdateFragment.java
net.hockeyapp.android.UpdateInfoListener.java
net.hockeyapp.android.UpdateManagerListener.java
net.hockeyapp.android.UpdateManager.java
net.hockeyapp.android.adapters.MessagesAdapter.java
net.hockeyapp.android.listeners.DownloadFileListener.java
net.hockeyapp.android.listeners.SendFeedbackListener.java
net.hockeyapp.android.objects.ErrorObject.java
net.hockeyapp.android.objects.FeedbackAttachment.java
net.hockeyapp.android.objects.FeedbackMessage.java
net.hockeyapp.android.objects.FeedbackResponse.java
net.hockeyapp.android.objects.Feedback.java
net.hockeyapp.android.tasks.AttachmentDownloader.java
net.hockeyapp.android.tasks.CheckUpdateTaskWithUI.java
net.hockeyapp.android.tasks.CheckUpdateTask.java
net.hockeyapp.android.tasks.DownloadFileTask.java
net.hockeyapp.android.tasks.GetFileSizeTask.java
net.hockeyapp.android.tasks.LoginTask.java
net.hockeyapp.android.tasks.ParseFeedbackTask.java
net.hockeyapp.android.tasks.SendFeedbackTask.java
net.hockeyapp.android.utils.AsyncTaskUtils.java
net.hockeyapp.android.utils.Base64.java
net.hockeyapp.android.utils.ConnectionManager.java
net.hockeyapp.android.utils.DeviceUtils.java
net.hockeyapp.android.utils.FeedbackParser.java
net.hockeyapp.android.utils.ImageUtils.java
net.hockeyapp.android.utils.PrefsUtil.java
net.hockeyapp.android.utils.SimpleMultipartEntity.java
net.hockeyapp.android.utils.UiThreadUtil.java
net.hockeyapp.android.utils.Util.java
net.hockeyapp.android.utils.VersionCache.java
net.hockeyapp.android.utils.VersionHelper.java
net.hockeyapp.android.utils.ViewHelper.java
net.hockeyapp.android.views.AttachmentListView.java
net.hockeyapp.android.views.AttachmentView.java
net.hockeyapp.android.views.ExpiryInfoView.java
net.hockeyapp.android.views.FeedbackMessageView.java
net.hockeyapp.android.views.FeedbackView.java
net.hockeyapp.android.views.LoginView.java
net.hockeyapp.android.views.PaintView.java
net.hockeyapp.android.views.UpdateView.java