I have an Android app that communicates with a Spring Boot backend. The backend is responsible for importing records into a database when the user requests it through the app. I would like the backend to send the names of the records back to the app while the processing is happening in real time so that the app user knows what is happening on the server. Currently the backend only returns a status string when the all of the processing has been completed. How can I get the backend to send status information back to the app as the records are being processed, and how do I handle it in the app? I've included the relevant code from my backend and from the Android app below.
I've tried searching on-line, but the closest thing I've found is Android real time updates from server. One user suggests using an AsyncTask, which I'm doing, but doesn't provide an example implementation.
Backend code:
@Controller
@RequestMapping("/myproject")
public class TestController {
@Autowired
JdbcTemplate jdbcTemplate;
@GetMapping("/import_new_record")
public @ResponseBody String importNewRecord() throws IOException
{
int count = 0;
// a list of records to be imported; in real life, each item in the list will be one line from a text file
String[] recordList = {"foo1","bar1","foo2","bar2","foo3","bar3"};
for (String record: recordList)
{
// update the db
this.jdbcTemplate.update("INSERT INTO mydb.mytable (id, record) VALUES (?, ?)", count, record);
// send count and record string back to app
// .....
// increment ID
count++;
}
return String.valueOf(count);
}
}
Android app:
public class ImportRecordActivity extends Activity
{
ProgressBar pb;
TextView tvNew;
@Override
protected void onCreate(Bundle b) {
super.onCreate(b);
setContentView(R.layout.activity_import_record);
pb = (ProgressBar) findViewById(R.id.indeterminateBar);
pb.setVisibility(ProgressBar.INVISIBLE);
tvNew = (TextView) findViewById(R.id.tvNew);
tvNew.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
new ImportNewRecords().execute(1);
}
});
}
// AsyncTask to trigger record import on the backend
private class ImportNewRecords extends AsyncTask<Integer, Integer, String>
{
String result;
String myServerAddress = "localhost";
protected String doInBackground(Integer... args) {
StringBuilder sb = new StringBuilder();
try {
publishProgress(100);
URL url = new URL("http://"+myServerAddress+":8080/myproject/import_new_record");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(con.getInputStream()));
String s;
while ((s = bufferedReader.readLine()) != null) {
sb.append(s + "\n");
}
result = sb.toString();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
// Display an indeterminate progress bar
// Presumably the code to display real-time progress should go here
@Override
protected void onProgressUpdate(Integer... args) {
pb.setVisibility(ProgressBar.VISIBLE);
}
@Override
protected void onPostExecute(String result) {
// kill the progress bar
pb.setVisibility(ProgressBar.INVISIBLE);
// display the number of records imported in a Toast
result = StringUtils.trim(result);
Toast toast = Toast.makeText(ImportRecordActivity.this, result, Toast.LENGTH_LONG);
View view = toast.getView();
TextView text = view.findViewById(android.R.id.message);
toast.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL, 0, 0);
toast.show();
}
@Override
protected void onPreExecute()
{
}
}
}