Android MySQL Retrofit Full Course – INSERT SELECT UPDATE DELETE SEARCH PAGINATION → Activity for INSERTING, UPDATING and DELETING from MySQL – Camposha

Android MySQL Retrofit Full Course – INSERT SELECT UPDATE DELETE SEARCH PAGINATION

Activity for INSERTING, UPDATING and DELETING from MySQL

INSERTING, UPDATING and DELETING

This lesson will involve us creating a class to perform our INSERT, UPDATE and DELETION to and from our MySQL database. This part of our Android MySQL CRUD – Creating a Scientists App series. In the series we are creating a full app and we’ve covered some parts already. In this part we are creating one of our most important classes, the class to perform the inserting, updating and deleting of the data.

This activity we will be creting will be re-used for both inserting and updating of data. It can be opened in two modes. When opened with a Scientist object being passed via intent, then we know we are opening for editing or deleting. In that case the Scientist’s attributes will be rendered in our edittexts. Thus the user can edit and just click an update/save method which will inflated in the toolbar.

However when it’s opened with the scientist object being null. Then we know it’s being opened for the sake of adding a new Scientist. In that case only the insert/save button will rendered in our toolbar. Thus when the user clicks it we will insert to mysql.

Note that our toolbar menus will be inflated dynamically based on what the activity is opened for.

Let’s start.

Video Tutorial(Recommended)

(a). Add imports,Define Class, Specify Instance Fields

We start by add by adding our imports:

import android.content.Context;
import android.helper.DateTimePickerEditText;
import android.os.Bundle;
import android.support.v4.app.NavUtils;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;

import info.camposha.retrofitmysqlcrud.Helpers.Utils;
import info.camposha.retrofitmysqlcrud.R;
import info.camposha.retrofitmysqlcrud.Retrofit.ResponseModel;
import info.camposha.retrofitmysqlcrud.Retrofit.RestApi;
import info.camposha.retrofitmysqlcrud.Retrofit.Scientist;
import io.github.inflationx.viewpump.ViewPumpContextWrapper;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

Then we create our class, making it derive from AppCompatActivity:

public class CRUDActivity extends AppCompatActivity {

Next we specify our instance fields:

    //we'll have several instance fields
    private EditText nameTxt, descriptionTxt, galaxyTxt, starTxt;
    private TextView headerTxt;
    private DateTimePickerEditText dobTxt, dodTxt;
    private ProgressBar mProgressBar;
    private String id = null;
    private Scientist receivedScientist;
    private Context c = CRUDActivity.this;

You can see we have specified the following widgets as our instance fields:

  1. EditTexts – These will be used to enter the scientist’s attributes.
  2. TextView – This will be used render the header of the page.
  3. DateTimePickerEditText – This will be used to select date via a wheel dialog that will be shown.
  4. ProgressBar – This will be used to show progress as we send data to the server.

We’ve also initialized an id as well as Context object.

(b). Initializing Widgets

Next we need to initialize our widgets:

    private void initializeWidgets() {
        mProgressBar = findViewById(R.id.mProgressBarSave);
        mProgressBar.setIndeterminate(true);
        mProgressBar.setVisibility(View.GONE);

        headerTxt = findViewById(R.id.headerTxt);
        nameTxt = findViewById(R.id.nameTxt);
        descriptionTxt = findViewById(R.id.descriptionTxt);
        galaxyTxt = findViewById(R.id.galaxyTxt);
        starTxt = findViewById(R.id.starTxt);

        dobTxt = findViewById(R.id.dobTxt);
        dobTxt.setFormat(Utils.DATE_FORMAT);
        dodTxt = findViewById(R.id.dodTxt);
        dodTxt.setFormat(Utils.DATE_FORMAT);
    }

The above are basically findViewById calls. We are simply referencing our views.

(c). Performing Insert

The next method allows us to actually perform our insert call.
Add the following method:

The above seems long. However it will allow us safely insert our data. In case of any error,like when there is not connection, our app won’t crash. Instead we will safely handle that error. It also allows us identify what exactly failed and output the right message. For example the failure can be a no connectivity situation, in case which we will simply handle the onFailure callback.

It can also be a positive response from the server that indicates the situation is on the server side and not on the client. For example maybe our app could connect to the server but couldn’t connect to mysql due to incorrect database credentials. In such cases we simply rely on the response code to identify the exact situation. Our server will be sending as part of the response the following:

  1. Response Message
  2. Response Code
  3. List of scientists(Optional)

The above are represented in our ResponseModel class.

(d). Performing Update

The below method will allow us update our mysql table:

It’s faily similar to the insertData method. However it’s performing an entirely different function, updating an existing data. That means that it will be called when the activity ws opened in the context of updating existing data. In that case the id for the scientist to be updated would be available.

It is also invoking the updateData defined in our RestApi class. That method required us to pass it an id which we do. That id will allow us identify the row that is to be updated. We will receive it from the receievedScientist object.

Again we will have two callback methods returned by our enqueue method:

  1. onResponse – Successful connection to the server.
  2. onFailure – Failed connection to the server.

If your connection fails then you need to check your URL and make sure you can connect to it in the emulator browser.

Beware that the onResponse() doesn’t necessarily imply that we have updated our data. It can be that we connected to the server, attempted to insert data but that attempt fails because of some reason like mismatched data types. In that case still the onResponse will be called. Becuase of that in our PHP code we made sure that we handled our exceptions correctly. And as part of the response will include a response code. That code will tell us what really happened.

Full Code – CRUDActivity.java

Here is the full code:

package info.camposha.retrofitmysqlcrud.Views;
import android.content.Context;
import android.helper.DateTimePickerEditText;
import android.os.Bundle;
import android.support.v4.app.NavUtils;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import info.camposha.retrofitmysqlcrud.Helpers.Utils;
import info.camposha.retrofitmysqlcrud.R;
import info.camposha.retrofitmysqlcrud.Retrofit.ResponseModel;
import info.camposha.retrofitmysqlcrud.Retrofit.RestApi;
import info.camposha.retrofitmysqlcrud.Retrofit.Scientist;
import io.github.inflationx.viewpump.ViewPumpContextWrapper;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class CRUDActivity extends AppCompatActivity {
//we'll have several instance fields
private EditText nameTxt, descriptionTxt, galaxyTxt, starTxt;
private TextView headerTxt;
private DateTimePickerEditText dobTxt, dodTxt;
private ProgressBar mProgressBar;
private String id = null;
private Scientist receivedScientist;
private Context c = CRUDActivity.this;
/**
* Let's reference our widgets
*/
private void initializeWidgets() {
mProgressBar = findViewById(R.id.mProgressBarSave);
mProgressBar.setIndeterminate(true);
mProgressBar.setVisibility(View.GONE);
headerTxt = findViewById(R.id.headerTxt);
nameTxt = findViewById(R.id.nameTxt);
descriptionTxt = findViewById(R.id.descriptionTxt);
galaxyTxt = findViewById(R.id.galaxyTxt);
starTxt = findViewById(R.id.starTxt);
dobTxt = findViewById(R.id.dobTxt);
dobTxt.setFormat(Utils.DATE_FORMAT);
dodTxt = findViewById(R.id.dodTxt);
dodTxt.setFormat(Utils.DATE_FORMAT);
}
/**
* The following method will allow us insert data typed in this page into th
* e database
*/
private void insertData() {
String name, description, galaxy, star, dob, died;
if (Utils.validate(nameTxt, descriptionTxt, galaxyTxt)) {
name = nameTxt.getText().toString();
description = descriptionTxt.getText().toString();
galaxy = galaxyTxt.getText().toString();
star = starTxt.getText().toString();
if (dobTxt.getDate() != null) {
dob = dobTxt.getDate().toString();
} else {
dobTxt.setError("Invalid Date");
dobTxt.requestFocus();
return;
}
if (dodTxt.getDate() != null) {
died = dodTxt.getDate().toString();
} else {
dodTxt.setError("Invalid Date");
dodTxt.requestFocus();
return;
}
RestApi api = Utils.getClient().create(RestApi.class);
Call<ResponseModel> insertData = api.insertData("INSERT", name,
description, galaxy,
star, dob, died);
Utils.showProgressBar(mProgressBar);
insertData.enqueue(new Callback<ResponseModel>() {
@Override
public void onResponse(Call<ResponseModel> call,
Response<ResponseModel> response) {
Log.d("RETROFIT", "response : " + response.body().toString());
String myResponseCode = response.body().getCode();
if (myResponseCode.equals("1")) {
Utils.show(c, "SUCCESS: n 1. Data Inserted Successfully. n 2. ResponseCode: "
+ myResponseCode);
Utils.openActivity(c, ScientistsActivity.class);
} else if (myResponseCode.equalsIgnoreCase("2")) {
Utils.showInfoDialog(CRUDActivity.this, "UNSUCCESSFUL",
"However Good Response. n 1. CONNECTION TO SERVER WAS SUCCESSFUL n 2. WE"+
" ATTEMPTED POSTING DATA BUT ENCOUNTERED ResponseCode: "+myResponseCode+
" n 3. Most probably the problem is with your PHP Code.");
}else if (myResponseCode.equalsIgnoreCase("3")) {
Utils.showInfoDialog(CRUDActivity.this, "NO MYSQL CONNECTION",+
" Your PHP Code"+
" is unable to connect to mysql database. Make sure you have supplied correct"+
" database credentials.");
}
Utils.hideProgressBar(mProgressBar);
}
@Override
public void onFailure(Call<ResponseModel> call, Throwable t) {
Log.d("RETROFIT", "ERROR: " + t.getMessage());
Utils.hideProgressBar(mProgressBar);
Utils.showInfoDialog(CRUDActivity.this, "FAILURE",
"FAILURE THROWN DURING INSERT."+
" ERROR Message: " + t.getMessage());
}
});
}
}
/**
* The following method will allow us update the current scientist's data in the database
*/
private void updateData() {
String name, description, galaxy, star, dob, died;
if (Utils.validate(nameTxt, descriptionTxt, galaxyTxt)) {
name = nameTxt.getText().toString();
description = descriptionTxt.getText().toString();
galaxy = galaxyTxt.getText().toString();
star = starTxt.getText().toString();
if (dobTxt.getDate() != null) {
dob = dobTxt.getFormat().format(dobTxt.getDate());
} else {
dobTxt.setError("Invalid Date");
dobTxt.requestFocus();
return;
}
if (dodTxt.getDate() != null) {
died = dodTxt.getFormat().format(dodTxt.getDate());
} else {
dodTxt.setError("Invalid Date");
dodTxt.requestFocus();
return;
}
Utils.showProgressBar(mProgressBar);
RestApi api = Utils.getClient().create(RestApi.class);
Call<ResponseModel> update = api.updateData("UPDATE", id, name, description, galaxy,
star,
dob, died);
update.enqueue(new Callback<ResponseModel>() {
@Override
public void onResponse(Call<ResponseModel> call, Response<ResponseModel> response) {
Log.d("RETROFIT", "Response: " + response.body().getResult());
Utils.hideProgressBar(mProgressBar);
String myResponseCode = response.body().getCode();
if (myResponseCode.equalsIgnoreCase("1")) {
Utils.show(c, response.body().getMessage());
Utils.openActivity(c, ScientistsActivity.class);
finish();
} else if (myResponseCode.equalsIgnoreCase("2")) {
Utils.showInfoDialog(CRUDActivity.this, "UNSUCCESSFUL",
"Good Response From PHP,"+
"WE ATTEMPTED UPDATING DATA BUT ENCOUNTERED ResponseCode: "+myResponseCode+
" n 3. Most probably the problem is with your PHP Code.");
} else if (myResponseCode.equalsIgnoreCase("3")) {
Utils.showInfoDialog(CRUDActivity.this, "NO MYSQL CONNECTION",
" Your PHP Code"+
" is unable to connect to mysql database. Make sure you have supplied correct"+
" database credentials.");
}
}
@Override
public void onFailure(Call<ResponseModel> call, Throwable t) {
Log.d("RETROFIT", "ERROR THROWN DURING UPDATE: " + t.getMessage());
Utils.hideProgressBar(mProgressBar);
Utils.showInfoDialog(CRUDActivity.this, "FAILURE THROWN", "ERROR DURING UPDATE.Here"+
" is the Error: " + t.getMessage());
}
});
}
}
/**
* The following method will allow us delete data from database
*/
private void deleteData() {
RestApi api = Utils.getClient().create(RestApi.class);
Call<ResponseModel> del = api.remove("DELETE", id);
Utils.showProgressBar(mProgressBar);
del.enqueue(new Callback<ResponseModel>() {
@Override
public void onResponse(Call<ResponseModel> call, Response<ResponseModel> response) {
Log.d("RETROFIT", "DELETE RESPONSE: " + response.body());
Utils.hideProgressBar(mProgressBar);
String myResponseCode = response.body().getCode();
if (myResponseCode.equalsIgnoreCase("1")) {
Utils.show(c, response.body().getMessage());
Utils.openActivity(c, ScientistsActivity.class);
finish();
} else if (myResponseCode.equalsIgnoreCase("2")) {
Utils.showInfoDialog(CRUDActivity.this, "UNSUCCESSFUL",
"However Good Response. n 1. CONNECTION TO SERVER WAS SUCCESSFUL"+
" n 2. WE ATTEMPTED POSTING DATA BUT ENCOUNTERED ResponseCode: "+
myResponseCode+ " n 3. Most probably the problem is with your PHP Code.");
}else if (myResponseCode.equalsIgnoreCase("3")) {
Utils.showInfoDialog(CRUDActivity.this, "NO MYSQL CONNECTION",
" Your PHP Code is unable to connect to mysql database. Make sure you have supplied correct database credentials.");
}
}
@Override
public void onFailure(Call<ResponseModel> call, Throwable t) {
Utils.hideProgressBar(mProgressBar);
Log.d("RETROFIT", "ERROR: " + t.getMessage());
Utils.showInfoDialog(CRUDActivity.this, "FAILURE THROWN", "ERROR during DELETE attempt. Message: " + t.getMessage());
}
});
}
/**
* Show selected star in our edittext
*/
private void showSelectedStarInEditText() {
starTxt.setOnClickListener(v -> Utils.selectStar(c, starTxt));
}
/**
* When our back button is pressed
*/
@Override
public void onBackPressed() {
Utils.showInfoDialog(this, "Warning", "Are you sure you want to exit?");
}
/**
* Let's inflate our menu based on the role this page has been opened for.
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
if (receivedScientist == null) {
getMenuInflater().inflate(R.menu.new_item_menu, menu);
headerTxt.setText("Add New Scientist");
} else {
getMenuInflater().inflate(R.menu.edit_item_menu, menu);
headerTxt.setText("Edit Existing Scientist");
}
return true;
}
/**
* Let's listen to menu action events and perform appropriate function
*/
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.insertMenuItem:
insertData();
return true;
case R.id.editMenuItem:
if (receivedScientist != null) {
updateData();
} else {
Utils.show(this, "EDIT ONLY WORKS IN EDITING MODE");
}
return true;
case R.id.deleteMenuItem:
if (receivedScientist != null) {
deleteData();
} else {
Utils.show(this, "DELETE ONLY WORKS IN EDITING MODE");
}
return true;
case R.id.viewAllMenuItem:
Utils.openActivity(this, ScientistsActivity.class);
finish();
return true;
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* Attach Base Context
*/
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(ViewPumpContextWrapper.wrap(newBase));
}
/**
* When our activity is resumed we will receive our data and set them to their editing
* widgets.
*/
@Override
protected void onResume() {
super.onResume();
Object o = Utils.receiveScientist(getIntent(), c);
if (o != null) {
receivedScientist = (Scientist) o;
id = receivedScientist.getId();
nameTxt.setText(receivedScientist.getName());
descriptionTxt.setText(receivedScientist.getDescription());
galaxyTxt.setText(receivedScientist.getGalaxy());
starTxt.setText(receivedScientist.getStar());
Object dob = receivedScientist.getDob();
if (dob != null) {
String d = dob.toString();
dobTxt.setDate(Utils.giveMeDate(d));
}
Object dod = receivedScientist.getDied();
if (dod != null) {
String d = dod.toString();
dodTxt.setDate(Utils.giveMeDate(d));
}
} else {
//Utils.show(c,"Received Scientist is Null");
}
}
/**
* Let's override our onCreate() method
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_crud);
this.initializeWidgets();
this.showSelectedStarInEditText();
}
}
//end

Now move over to the next lesson.

(1) Comment

  • IOSTREAM17 September 16, 2019 @ 1:26 pm

    Good job.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

(2) Comments

  • IOSTREAM17 July 5, 2019 @ 6:55 am

    good job well done

    • Admin bar avatar
      Oclemy July 5, 2019 @ 7:08 am

      Thank you very much.

Comments are closed.

X