So here is the ugliest fragment of my application, I tried to reformat as much as I could but I think it's still pretty ugly.
Basically, I'm trying to use an API call to receive JSON which tells me what type of field to create dynamically (Edit text, checkbox, Multiple choice, single choice). And then, I add them dynamically to my fragment. I use Retrofit for the API call.
It also provides a way to upload picture or file and get the path of the created file to send back the file through another API call. It was pretty painful to write as I knew it was bad coding but I don't know how to make it better and shorter.
public class FragmentIncidentPlan extends BackHandledFragment {
private static final String TAG = "FragmentIncidentPlan";
public static final String PLAN_ID = "planId";
private int mPlanId;
DialogLoading dialog;
private JSONObject obj = null;
private JSONObject currentObj = null;
//For the plans form
private String mCurrentPhotoPath;
private EntityPlanTemplate mPlan;
// Current form state
private static Map<String, EntityOption> currentForm = new HashMap<>();
private static Map<String, String> valMap = new HashMap<>();
// TextView ID, Form ID
private static Map<Integer, String> valMapId = new HashMap<>();
private static LinearLayout formD;
private View view;
private int mYear, mMonth, mDay, mHour, mMinute;
private String dateFormat;
private Button attachFileButton;
private Button openCameraButton;
private Button sendIncidentButton;
private CobaltServices cobaltServices;
public static final int REQUEST_TAKE_PICTURE = 0;
public static final int REQUEST_UPLOAD_FILE = 1;
public static final int REQUEST_VIDEO_CAPTURE = 2;
public FragmentIncidentPlan() {
// Required empty public constructor
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mPlanId = getArguments().getInt(PLAN_ID);
Log.e(TAG, "" + mPlanId);
}
mPlan = GenericDAO.getInstance(EntityPlanTemplate.class).queryById(String.valueOf(mPlanId));
for (EntityForm form : mPlan.getForm()) {
Log.w(TAG, form.getName());
}
cobaltServices = RetrofitCreator.createService(getContext(), CobaltServices.class);
Log.e(TAG, mPlan.getListLabel() + " is Open!");
Log.e(TAG, "" + mPlan.getForm().size());
dialog = DialogLoading.newInstance("white");
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
view = inflater.inflate(R.layout.fragment_incident_plan, container, false);
((AppCompatActivity) getActivity()).getSupportActionBar().setTitle(mPlan.getName());
attachFileButton = (Button) view.findViewById(R.id.button_attach_file);
openCameraButton = (Button) view.findViewById(R.id.button_open_camera);
sendIncidentButton = (Button) view.findViewById(R.id.button_send_incident);
formD = (LinearLayout) view.findViewById(R.id.incident_form_holder);
attachFileButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
attach();
}
});
openCameraButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
takePicture();
}
});
sendIncidentButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
sendIncident();
}
});
valMapId.clear();
int countIdTextView = 0;
for (final EntityForm form : mPlan.getForm()) {
final String type = form.getType();
final String name = form.getName();
final String id = form.getdId();
if (type.equalsIgnoreCase("Textbox")) {
LinearLayout ln = new LinearLayout(context);
RelativeLayout.LayoutParams lp2 = new RelativeLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT
, LinearLayout.LayoutParams.WRAP_CONTENT);
ln.setPadding(30, 10, 30, 10);
ln.setLayoutParams(lp2);
ln.setBackgroundColor(getResources().getColor(R.color.gray_light));
EditText text = createEditText();
text.setHint(name);
text.setId(countIdTextView);
countIdTextView++;
if (valMap.containsKey(id)) {
text.setText(valMap.get(Long.valueOf(id)));
}
ln.addView(text);
formD.addView(ln);
valMapId.put(text.getId(), id);
} else if (type.equalsIgnoreCase("Date")) {
String fName = name;
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
final RelativeLayout linearLayout = new RelativeLayout(context);
linearLayout.setBackground(getResources().getDrawable(R.drawable.form_textview));
linearLayout.setPadding(30, 10, 30, 10);
linearLayout.setLayoutParams(layoutParams);
linearLayout.setBackgroundColor(getResources().getColor(R.color.gray_light));
final TextView textView = createDateTimePicker();
textView.setHint(fName);
textView.setId(countIdTextView);
countIdTextView++;
if (valMap.containsKey(id)) {
textView.setText(valMap.get(id));
}
linearLayout.addView(textView);
ImageView imgView = createImageView();
linearLayout.addView(imgView);
formD.addView(linearLayout);
valMapId.put(textView.getId(), id);
} else if (type.equalsIgnoreCase("Multiple")) {
final String fName = name;
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
final RelativeLayout linearLayout = new RelativeLayout(context);
linearLayout.setBackground(getResources().getDrawable(R.drawable.form_textview));
linearLayout.setPadding(30, 10, 30, 10);
linearLayout.setLayoutParams(layoutParams);
linearLayout.setBackgroundColor(getResources().getColor(R.color.gray_light));
TextView textView = createTextView();
textView.setText(fName);
linearLayout.addView(textView);
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
if (null != mListener) {
saveCurrentForm(form);
FragmentIncidentFormSelect fragment = new FragmentIncidentFormSelect();
Bundle args = new Bundle();
args.putString(FragmentIncidentFormSelect.OPTION_ID, form.getdId());
fragment.setArguments(args);
mListener.onFragmentInteraction(fragment);
}
}
}, 300);
}
});
ImageView imgView = createImageView();
linearLayout.addView(imgView);
formD.addView(linearLayout);
} else if (type.equalsIgnoreCase("Single")) {
final String fName = name;
final ArrayList<EntityOption> options = new ArrayList<>();
options.addAll(form.getOptions());
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
final RelativeLayout linearLayout = new RelativeLayout(context);
linearLayout.setBackground(getResources().getDrawable(R.drawable.form_textview));
linearLayout.setPadding(30, 10, 30, 10);
linearLayout.setLayoutParams(layoutParams);
linearLayout.setBackgroundColor(getResources().getColor(R.color.gray_light));
LayoutParams lparams1 = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
TextView txtResGender = new TextView(context);
txtResGender.setLayoutParams(lparams1);
txtResGender.setBackground(getResources().getDrawable(R.drawable.form_textview));
txtResGender.setText(fName);
txtResGender.setClickable(true);
txtResGender.setPadding(25, 40, 7, 40);
txtResGender.setTypeface(null, Typeface.BOLD);
txtResGender.setTextSize(18.0f);
txtResGender.setTextColor(getResources().getColor(R.color.gray_very_dark));
linearLayout.addView(txtResGender);
lparams1.setMargins(20, 20, 20, 20);
txtResGender.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
if (null != mListener) {
saveCurrentForm(form);
FragmentIncidentFormSelect fragment = new FragmentIncidentFormSelect();
Bundle args = new Bundle();
args.putString(FragmentIncidentFormSelect.OPTION_ID, form.getdId());
fragment.setArguments(args);
mListener.onFragmentInteraction(fragment);
}
}
}, 300);
}
});
LayoutParams lparams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
ImageView imgView = new ImageView(getActivity());
imgView.setImageResource(R.drawable.ic_arrowforblue2x);
imgView.setLayoutParams(lparams);
imgView.setPadding(0, 15, 50, 0);
linearLayout.addView(imgView);
lparams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
lparams.addRule(RelativeLayout.CENTER_VERTICAL);
lparams.setMargins(20, 20, 20, 20);
formD.addView(linearLayout);
}
}
return view;
}
private EditText createEditText() {
EditText text = new EditText(context);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT
, ViewGroup.LayoutParams.WRAP_CONTENT);
lp.setMargins(20, 20, 20, 20);
text.setTextSize(18.0f);
text.setPadding(25, 40, 7, 40);
text.setHintTextColor(getResources().getColor(R.color.gray_darker));
text.setTextColor(getResources().getColor(R.color.gray_very_dark));
text.setBackground(getResources().getDrawable(R.drawable.form_textview));
text.setLayoutParams(lp);
return text;
}
private TextView createTextView() {
LayoutParams lparams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
lparams.setMargins(20, 20, 20, 20);
final TextView textView = new TextView(context);
textView.setLayoutParams(lparams);
textView.setBackground(getResources().getDrawable(R.drawable.form_textview));
textView.setClickable(true);
textView.setPadding(25, 40, 7, 40);
textView.setTypeface(null, Typeface.BOLD);
textView.setTextSize(18.0f);
textView.setTextColor(getResources().getColor(R.color.gray_very_dark));
return textView;
}
private TextView createDateTimePicker() {
final TextView textView = createTextView();
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Get Current Date
final Calendar c = Calendar.getInstance();
mYear = c.get(Calendar.YEAR);
mMonth = c.get(Calendar.MONTH);
mDay = c.get(Calendar.DAY_OF_MONTH);
DatePickerDialog datePickerDialog = new DatePickerDialog(context,
new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year,
int monthOfYear, int dayOfMonth) {
mYear = year;
mMonth = monthOfYear;
mDay = dayOfMonth;
// Get Current Time
final Calendar c = Calendar.getInstance();
mHour = c.get(Calendar.HOUR_OF_DAY);
mMinute = c.get(Calendar.MINUTE);
// Launch Time Picker Dialog
TimePickerDialog timePickerDialog = new TimePickerDialog(context,
new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker view, int hourOfDay,
int minute) {
mHour = hourOfDay;
mMinute = minute;
Calendar calendar = Calendar.getInstance();
calendar.set(mYear, mMonth, mDay);
calendar.set(Calendar.HOUR, mHour);
calendar.set(Calendar.MINUTE, mMinute);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss Z");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
Log.e(TAG, sdf.format(calendar.getTime()));
dateFormat = sdf.format(calendar.getTime());
sdf.setTimeZone(TimeZone.getDefault());
textView.setText(sdf.format(calendar.getTime()));
}
}, mHour, mMinute, false);
timePickerDialog.show();
}
}, mYear, mMonth, mDay);
datePickerDialog.show();
}
});
return textView;
}
private ImageView createImageView() {
LayoutParams lparams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
lparams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
lparams.addRule(RelativeLayout.CENTER_VERTICAL);
lparams.setMargins(20, 20, 20, 20);
ImageView imgView = new ImageView(context);
imgView.setImageResource(R.drawable.ic_arrowforblue2x);
imgView.setLayoutParams(lparams);
imgView.setPadding(0, 15, 50, 0);
return imgView;
}
private void retrieveCurrentForm() {
for (EntityOption cOption : currentForm.values()) {
Log.e(TAG, "-->" + cOption.getListLabel() + "--" + cOption.getIsSelected());
GenericDAO.getInstance(EntityOption.class).update(cOption);
}
currentForm.clear();
valMap.clear();
valMapId.clear();
Log.w(TAG, "Form Reverted to it's initial states");
}
private void saveFormTextField() {
ArrayList<String> val = new ArrayList<>();
for (int i : valMapId.keySet()) {
View v = view.findViewById(i);
if (v instanceof EditText) {
EditText e = (EditText) v;
if (!e.getText().toString().equals("")) {
valMap.put(valMapId.get(i), e.getText().toString());
}
} else if (v instanceof TextView) {
// ONLY DATE SHOULD BE HERE
TextView e = (TextView) v;
if (!e.getText().toString().equals("")) {
valMap.put(valMapId.get(i), dateFormat);
}
}
}
for (EntityForm currentForm : mPlan.getForm()) {
ArrayList<EntityOption> mOptions = new ArrayList<>();
mOptions.addAll(currentForm.getOptions());
if (currentForm.getType().equals("Single")) {
for (EntityOption currentOption : mOptions) {
if (currentOption.getIsSelected()) {
val.add(currentOption.getTxt());
break;
}
}
if (val.size() > 0) {
valMap.put(currentForm.getId(), val.toString());
val.clear();
}
} else if (currentForm.getType().equals("Multiple")) {
for (EntityOption currentOption : mOptions) {
if (currentOption.getIsSelected()) {
val.add(currentOption.getTxt());
}
}
if (val.size() > 0) {
valMap.put(currentForm.getId(), val.toString());
val.clear();
}
}
}
}
private void saveCurrentForm(EntityForm form) {
saveFormTextField();
for (EntityOption mOption : form.getOptions()) {
if (!currentForm.containsKey(mOption.getId())) {
currentForm.put(mOption.getId(), mOption);
}
}
Log.w(TAG, "Form state saved");
}
@Override
public String getTagText() {
return "FragmentIncidentGroup";
}
@Override
public void onDestroy() {
retrieveCurrentForm();
super.onDestroy();
}
@Override
public boolean onBackPressed() {
retrieveCurrentForm();
return false;
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
try {
if (requestCode == GenericActivity.REQUEST_TAKE_PICTURE) {
if (resultCode == Activity.RESULT_OK) {
String[] split = mCurrentPhotoPath.split(":");
Log.e(TAG, "RESULT->" + split[1]);
//uploadFile(split[1]);
}
} else if (requestCode == REQUEST_UPLOAD_FILE) {
if (resultCode == Activity.RESULT_OK) {
Uri myUri = data.getData();
String filepath = Utils.getFilePath(context, myUri);
Log.e(TAG, "RESULT->" + filepath);
//uploadFile(filepath);
}
}
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
}
private JSONObject convertIncidentIntoJsonArray() {
JSONObject finalObj = new JSONObject();
JSONArray jsonArrayIncident = new JSONArray();
JSONObject incidentData = new JSONObject();
Iterator it = valMap.entrySet().iterator();
try {
while (it.hasNext()) {
String[] dArr;
Map.Entry pair = (Map.Entry) it.next();
String mData = (String) pair.getValue();
if (mData.startsWith("[")) {
String sData = mData.substring(1, mData.length() - 1);
dArr = sData.split(",");
incidentData.put(pair.getKey().toString(), new JSONArray(Arrays.asList(dArr)));
} else {
incidentData.put(pair.getKey().toString(), pair.getValue());
}
}
Iterator keys = incidentData.keys();
while (keys.hasNext()) {
String jVal = "";
String key = (String) keys.next();
if (incidentData.getString(key).startsWith("[")) {
jVal = "{\"val\":" + incidentData.getString(key) + " ,\"variableId\" : \"" + key + "\" }";
} else {
jVal = "{\"val\":[\"" + incidentData.getString(key) + "\"] ,\"variableId\" : \"" + key + "\" }";
}
JSONObject jObj = new JSONObject(jVal);
jsonArrayIncident.put(jObj);
}
if (obj != null) {
JSONArray array = new JSONArray();
array.put(obj);
finalObj.put("attachmentFiles", array);
}
finalObj.put("formVariableItems", jsonArrayIncident);
Log.d(TAG, "Incident DATA:" + jsonArrayIncident.toString());
} catch (JSONException e) {
Log.w(TAG, "JSONException : Error parsing Incident data");
}
return finalObj;
}
public void attach() {
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.setType("*/*");
startActivityForResult(i, REQUEST_UPLOAD_FILE);
}
public void takePicture() {
Log.w("FINAL", " : " + valMap.toString());
//intent.putExtra(MediaStore.EXTRA_OUTPUT, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getActivity().getPackageManager()) != null) {
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
}
if (photoFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoFile));
startActivityForResult(takePictureIntent, REQUEST_TAKE_PICTURE);
}
}
}
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = "file:" + image.getAbsolutePath();
galleryAddPic();
return image;
}
private void galleryAddPic() {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(mCurrentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
getActivity().sendBroadcast(mediaScanIntent);
}
private void uploadFile(String path) {
Map<String, RequestBody> map = new HashMap<>();
map.put("Id", Utils.toRequestBody("123"));
map.put("Name", Utils.toRequestBody("testest"));
if (path != null) {
File file2 = new File(path);
RequestBody fileBody = RequestBody.create(MediaType.parse("image/png"), file2);
map.put("file\"; filename=\"pp.png\"", fileBody);
}
Call<ResponseBody> call = cobaltServices.upload(map);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call,
Response<ResponseBody> response) {
try {
currentObj = new JSONObject(response.body().string());
obj = new JSONObject();
obj.put("fileId", (int) currentObj.get("fileid"));
obj.put("fileName", "file.jpg");
obj.put("mimeType", "image/jpeg");
obj.put("image", true);
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.e("Upload error:", t.getMessage());
}
});
}
public void sendIncident() {
dialog.show(getActivity().getSupportFragmentManager(), "fragmentDialogLoadingCrisis");
saveFormTextField();
JSONObject incident = convertIncidentIntoJsonArray();
Log.w(TAG, "Attributes : " + mPlan.getTemplateId() + "::" + String.valueOf(mPlan.getId()) + "EMP" + "" + mPlan.getName());
Call<ResponseBody> call = cobaltServices.launchIncident(incident.toString().getBytes(), mPlan.getTemplateId(), String.valueOf(mPlan.getId()), "EMP");
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.isSuccessful()) {
// Retrieve the crisis in background
Intent intent = new Intent(context, DatabaseService.class);
intent.setAction(DatabaseService.UPDATE_CRISIS);
getActivity().startService(intent);
((ActivityHome) (FragmentIncidentPlan.this.getActivity())).selectFragment(new FragmentCrisis());
if (dialog.isVisible()) {
dialog.dismiss();
}
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.e(TAG, "Error: " + t.getMessage());
Utils.showToastMessage(getActivity(), "Error sending Incident", true);
}
});
}
}