How to Fetch Data from a Web Server in an Android Application

How can I fetch data from a web server in an android application?

I would recommend these tutorials:

Connect android with PHP and MySql, JSON in android and PHP and MySQLi

I used these tutorials and managed to get what you are trying to do working without too much difficulty.

Between them they describe each step in how to do what you are attempting at each stage, the android application, the database and the web server side and has extra information included for what you can then do to process and use the received information

The only thing I would add is that the Connect android with PHP and MySql tutorial makes use of mysql_ in php which is deprecated. Much better to use MySqli which is why I included the third link.

The basic outline of what you want to do is this:

1) in the android app make a request to a server php script using a class like this:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;

import android.util.Log;

public class JSONParser {

// Response from the HTTP Request
static InputStream httpResponseStream = null;
// JSON Response String to create JSON Object
static String jsonString = "";

// Method to issue HTTP request, parse JSON result and return JSON Object
public JSONObject makeHttpRequest(String url, String method,
List<NameValuePair> params) {

try {
// get a Http client
DefaultHttpClient httpClient = new DefaultHttpClient();

// If required HTTP method is POST
if (method == "POST") {
// Create a Http POST object
HttpPost httpPost = new HttpPost(url);
// Encode the passed parameters into the Http request
httpPost.setEntity(new UrlEncodedFormEntity(params));
// Execute the request and fetch Http response
HttpResponse httpResponse = httpClient.execute(httpPost);
// Extract the result from the response
HttpEntity httpEntity = httpResponse.getEntity();
// Open the result as an input stream for parsing
httpResponseStream = httpEntity.getContent();
}
// Else if it is GET
else if (method == "GET") {
// Format the parameters correctly for HTTP transmission
String paramString = URLEncodedUtils.format(params, "utf-8");
// Add parameters to url in GET format
url += "?" + paramString;
// Execute the request
HttpGet httpGet = new HttpGet(url);
// Execute the request and fetch Http response
HttpResponse httpResponse = httpClient.execute(httpGet);
// Extract the result from the response
HttpEntity httpEntity = httpResponse.getEntity();
// Open the result as an input stream for parsing
httpResponseStream = httpEntity.getContent();
}
// Catch Possible Exceptions
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

try {
// Create buffered reader for the httpResponceStream
BufferedReader httpResponseReader = new BufferedReader(
new InputStreamReader(httpResponseStream, "iso-8859-1"), 8);
// String to hold current line from httpResponseReader
String line = null;
// Clear jsonString
jsonString = "";
// While there is still more response to read
while ((line = httpResponseReader.readLine()) != null) {
// Add line to jsonString
jsonString += (line + "\n");
}
// Close Response Stream
httpResponseStream.close();
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}

try {
// Create jsonObject from the jsonString and return it
return new JSONObject(jsonString);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
// Return null if in error
return null;
}
}
}

Which handles communication, opens a connection and receives a JSON string which it then processes into a JSON object.

2) in the php server, open an mysqli connection to your SQL database, run an mysqli->query() and do something like the following with the result:

if (mysqli_num_rows($result) > 0) {
// looping through all results
$response["apps"] = array();

while ($row = mysqli_fetch_array($result)) {

$apps = array();

$apps["name"] = $row["name"];
$apps["package"] = $row["package"];
$apps["version"] = $row["version"];
$apps["dateversion"] = $row["dateversion"];
$apps["sdkver"] = $row["sdkver"];
$apps["pathroot"] = $row["pathroot"];
$apps["rootname"] = $row["rootname"];
$apps["apkmd5"] = $row["apkmd5"];
$apps["extraapkmd5"] = $row["extraapkmd5"];
$apps["instructionsmd5"] = $row["instructionsmd5"];
$apps["assetsmd5"] = $row["assetsmd5"];
$apps["root"] = $row["root"];
$apps["current"] = $row["current"];

// push single product into final response array
array_push($response["apps"], $apps);
}
// success
$response["success"] = 1;

// echoing JSON response
echo json_encode($response);

This iterates through the database response and encodes it into a JSON string which is sent back to the android app which can then process it.

How to create something like this is all explained in the tutorials linked

Send data from a web server to an android app

There is two best approach you can follow.

  1. from server to app: in this case make corn job(timer service) which send push notification to android app. when app get push notification create one background service which download any data from server.

Note: if you have small text with limit of 100 char then no need to create service just send using push notification


  1. fetch data from server: in this case make one background service(auto start service) in android app. which run within some interval period like 1 hour or more(whatever your requirement). that service fetch data from server.(in this case android app eat battery of user device because of background service)

i will suggest you to use 1st approach because its easy and best way(in case of performance) your server do everything & android app have to just receive data.


how to implement push notification best tutorial using PHP & android(its old but just read official docs)

Android app retrieve data from server, save in database and display to user

Updated Answer

After reading comments and updated question I figured out that you want to fetch a small list of data and store it to database and show all the data stored in the database. If this is what you want, you can perform the following (omitted DataSouce for brevity) -

In PostDao You can return a LiveData<List<MyData>> instead of List<MyData> and observe that LiveData in the Activity to update the RecyclerView. Just make sure you remove the suspend keyword as room will take care of threading when it returns LiveData.

@Dao
interface PostsDao {
@Query("SELECT * FROM " + Post.TABLE_NAME + " ORDER BY " + Post.COLUMN_ID + " desc")
fun getAllData(): LiveData<List<MyData>>

@Insert
suspend fun insertData(data: List<MyData>)
}

In Repository make 2 functions one for fetching remote data and storing it to the database and the other just returns the LiveData returned by the room. You don't need to make a request to room when you insert the remote data, room will automatically update you as you are observing a LiveData from room.

class DataRepository(private val dao: PostsDao, private val dto: PostDto) {

fun getDataFromDatabase() = dao.getAllData()

suspend fun getDataFromServer(since: Long) = withContext(Dispatchers.IO) {
val data = dto.getRemoteData(since)
saveDataToDatabase(data)
}

private suspend fun saveDataToDatabase(data: List<MyData>) = dao.insertData(data)
}

Your ViewModel should look like,

class DataViewModel(private val repository : DataRepository) : ViewModel() {

val dataList = repository.getDataFromDatabase()

fun data(since: Long) = viewModelScope.launch {
repository.getDataFromServer(since)
}
}

In the Activity make sure you use ListAdapter

private lateinit var mDataViewModel: DataViewModel
private lateinit var mAdapter: ListAdapter

override fun onCreate(savedInstanceBundle: Bundle?) {
...
mDataViewModel.data(getSince())
mDataViewModel.dataList.observe(this, Observer(adapter::submitList))
}

Initial Answer

First of all, I would recommend you to look into Android Architecture Blueprints v2. According to Android Architecture Blueprints v2 following improvements can be made,

  1. DataRepository should be injected rather than instantiating internally according to the Dependency Inversion principle.
  2. You should decouple the functions in the ViewModel. Instead of returning the LiveData, the data() function can update an encapsulated LiveData. For example,

    class DataViewModel(private val repository = DataRepository) : ViewModel() {
    private val _dataList = MutableLiveData<List<MyData>>()
    val dataList : LiveData<List<MyData>> = _dataList

    fun data(since: Long) = viewModelScope.launch {
    val list = repository.getData(since)
    _dataList.value = list
    }
    ...
    }
  3. Repository should be responsible for fetching data from remote data source and save it to local data source. You should have two data source i.e. RemoteDataSource and LocalDataSource that should be injected in the Repository. You can also have an abstract DataSource. Let's see how can you improve your repository,

    interface DataSource {
    suspend fun getData(since: Long) : List<MyData>
    suspend fun saveData(list List<MyData>)
    suspend fun delete()
    }

    class RemoteDataSource(dto: PostsDto) : DataSource { ... }
    class LocalDataSource(dao: PostsDao) : DataSource { ... }

    class DataRepository(private val remoteSource: DataSource, private val localSource: DataSource) {
    suspend fun getData(since: Long) : List<MyData> = withContext(Dispatchers.IO) {
    val data = remoteSource.getData(since)
    localSource.delete()
    localSource.save(data)
    return@withContext localSource.getData(since)
    }
    ...
    }
  4. In your Activity, you just need to observe the dataList: LiveData and submit it's value to ListAdapter.

    private lateinit var mDataViewModel: DataViewModel
    private lateinit var mAdapter: ListAdapter

    override fun onCreate(savedInstanceBundle: Bundle?) {
    ...
    mDataViewModel.data(since)
    mDataViewModel.dataList.observe(this, Observer(adapter::submitList))
    }

Best way to request data from server

The best way to achieve this is to use an HttpURLConnection to make your web calls inside an AsyncTask and then pass the result back to your calling Activity through a callback. Here's some code to help you get started:

The first thing you should understand is how to properly use a callback with an AsyncTask. Here is an example AsyncTask that defines a callback interface:

import android.os.AsyncTask;

public class TestTask extends AsyncTask<String, Void, String> {

TestTaskCallback listener;

public TestTask(TestTaskCallback listener) {
this.listener = listener;
}

protected String doInBackground(String... args) {

String input = args[0];
String output = "simulated return value";

return output;
}

protected void onPostExecute(String result) {
listener.onResultReceived(result);
}

public interface TestTaskCallback {
void onResultReceived(String result);
}
}

The way this works is, you define a public interface that you then implement in your Activity. This acts as a "listener" that is waiting for any data that is sent through to it. We define the interface TestTaskCallback because we are going to be sending our data from our AsyncTask to our calling Activity.

Then in the Activity, we need to implement this interface, and pass in a reference to our implementation to the task when we create it. That way, when the task fires, it knows where to send the result, which is back to our Activity. An example implementation might look like this:

public class TestActivity extends AppCompatActivity implements TestTask.TestTaskCallback {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_layout);

new TestTask(this).execute("Some input");

}

public void onResultReceived(String result) {
Log.d("TEST TASK RESULT", result);
}
}

So our Activity implements the interface that we defined inside our AsyncTask, and notice that our AsyncTask takes the reference to this implementation (passed in through the constructor) and sends data to it in the onPostExecute() method. This will allow your result to be sent to the main UI thread so that you can update your Activity appropriately.

The only thing left is to actually make the web calls. I would recommend using an HttpURLConnection for this. You would put this code inside the doInBackground() method of your AsyncTask.

I'll show you an example web service call I have set up. This shows how to make a web service call to retrieve a JSON response. It looks something like this:

//The JSON we will get back as a response from the server
JSONObject jsonResponse = null;

//Http connections and data streams
URL url;
HttpURLConnection httpURLConnection = null;
OutputStreamWriter outputStreamWriter = null;

try {

//open connection to the server
url = new URL("your_url_to_web_service");
httpURLConnection = (HttpURLConnection) url.openConnection();

//set request properties
httpURLConnection.setDoOutput(true); //defaults request method to POST
httpURLConnection.setDoInput(true); //allow input to this HttpURLConnection
httpURLConnection.setRequestProperty("Content-Type", "application/json"); //header params
httpURLConnection.setRequestProperty("Accept", "application/json"); //header params
httpURLConnection.setFixedLengthStreamingMode(jsonToSend.toString().getBytes().length); //header param "content-length"

//open output stream and POST our JSON data to server
outputStreamWriter = new OutputStreamWriter(httpURLConnection.getOutputStream());
outputStreamWriter.write(jsonToSend.toString());
outputStreamWriter.flush(); //flush the stream when we're finished writing to make sure all bytes get to their destination

//prepare input buffer and get the http response from server
StringBuilder stringBuilder = new StringBuilder();
int responseCode = httpURLConnection.getResponseCode();

//Check to make sure we got a valid status response from the server,
//then get the server JSON response if we did.
if(responseCode == HttpURLConnection.HTTP_OK) {

//read in each line of the response to the input buffer
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream(),"utf-8"));
String line;
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line).append("\n");
}

bufferedReader.close(); //close out the input stream

try {
//Copy the JSON response to a local JSONObject
jsonResponse = new JSONObject(stringBuilder.toString());
} catch (JSONException je) {
je.printStackTrace();
}
}

} catch (IOException ioe) {
ioe.printStackTrace();
} finally {
if(httpURLConnection != null) {
httpURLConnection.disconnect(); //close out our http connection
}

if(outputStreamWriter != null) {
try {
outputStreamWriter.close(); //close our output stream
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}

//Return the JSON response from the server.
return jsonResponse;

This is pretty much all you need to know to do exactly what it is you are trying to do. I realize this is a ton of info to throw at you all at once, but if you take your time and work through it piece by piece, you'll find it's not too difficult after all and is actually a VERY powerful tool that you'll use all the time programming Android apps!

Hope this helps. Feel free to ask questions for any parts you don't fully understand yet!

How to fetch data from a website in android app after entering his personal details during registration?

You can write a RESTful web service on your server which takes the arguments like (age,income,etc) and store these arguments to a new variable then use those variable when connecting the government's website. After that you can use your government's APIs if there are any, if not: you can write a web scraper for that particular website.

You can check this tutorial for web scraping with Node JS:

https://scotch.io/tutorials/scraping-the-web-with-node-js

how can android app read data from database on the server?

Basically you need a Web Service that read/write into your DB. Android then read the data through JSONObject and parser.

Direct connection through JDBC is insecure.

Below is tutorial on How Android connect to mySql on server

  • http://www.tutorialspoint.com/android/android_php_mysql.htm
  • http://www.helloandroid.com/tutorials/connecting-mysql-database
  • http://www.androidhive.info/2012/05/how-to-connect-android-with-php-mysql/

You may also take a look on this thread

  • How to connect Android app to MySQL database?

Android app . fetching data from database

If you wanna use the database as centralized then it should be a server but not Local DB.
Local db can be accessible within the device as we all know and the below can help you to handle the server.

Step 1: First buy a server in either GoDaddy or 000webhost.com(Free server will be available)

step 2: Create a database and make some tables which matches your requirement.

step 3: Remaining all coding and integrating part is in this Url
Android Php connect

This is the basic API for the starters, keep going.

Android API integration using Java servlet

Step 1: Download Eclipse EE(Express Edition) or Add Eclipse EE plugin to your Existing Eclipse

Step 2: In your Eclipse go to File > New > Project > Web > Dynamic Web Project > next.

Step 3: Name your Project and select Apache Tomcat v7.0 as the target runtime and click finish.

Step 4: Now right click on project > New > Other > Web > Servelt. Name the Servlet as your wish.

Step 5: As an Example I placed here two multiply the number with 2

import java.io.IOException;
import java.io.OutputStreamWriter;

import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/DoubleMeServlet")
public class DoubleMeServlet extends HttpServlet {
private static final long serialVersionUID = 1L;

public DoubleMeServlet() {
super();

}

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

response.getOutputStream().println("Hurray !! This Servlet Works");

}

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

try {
int length = request.getContentLength();
byte[] input = new byte[length];
ServletInputStream sin = request.getInputStream();
int c, count = 0 ;
while ((c = sin.read(input, count, input.length-count)) != -1) {
count +=c;
}
sin.close();

String recievedString = new String(input);
response.setStatus(HttpServletResponse.SC_OK);
OutputStreamWriter writer = new OutputStreamWriter(response.getOutputStream());

Integer doubledValue = Integer.parseInt(recievedString) * 2;

writer.write(doubledValue.toString());
writer.flush();
writer.close();

} catch (IOException e) {
try{
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
response.getWriter().print(e.getMessage());
response.getWriter().close();
} catch (IOException ioe) {
}
}
}

}

Step 6: Right click on Servlet project > Run as > Run on Server. Run on Server Dialog should pop up. Select "Manually define a new server" and also Tomcat v7.0 under server type." Before that make sure your tomcat server is up and running. Open your web browser and type http://localhost:8080. You should see a default page displayed by tomcat server.

And below is the sample code, you should call your servlet file from your android app like this mentioned way

package com.app.myapp;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLConnection;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

public class DoubleMeActivity extends Activity implements OnClickListener {

EditText inputValue=null;
Integer doubledValue =0;
Button doubleMe;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.calculate);

inputValue = (EditText) findViewById(R.id.inputNum);
doubleMe = (Button) findViewById(R.id.doubleme);

doubleMe.setOnClickListener(this);
}

@Override
public void onClick(View v) {

switch (v.getId()){
case R.id.doubleme:

new Thread(new Runnable() {
public void run() {

try{
URL url = new URL("http://10.0.2.2:8080/MyServletProject/DoubleMeServlet");
URLConnection connection = url.openConnection();

String inputString = inputValue.getText().toString();
//inputString = URLEncoder.encode(inputString, "UTF-8");

Log.d("inputString", inputString);

connection.setDoOutput(true);
OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
out.write(inputString);
out.close();

BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));

String returnString="";
doubledValue =0;

while ((returnString = in.readLine()) != null)
{
doubledValue= Integer.parseInt(returnString);
}
in.close();

runOnUiThread(new Runnable() {
public void run() {
inputValue.setText(doubledValue.toString());

}
});

}catch(Exception e)
{
Log.d("Exception",e.toString());
}

}
}).start();

break;
}
}
}

Refer the below link for complete reference
Connect android app with servlet

Fetch Data from website to android app

Yes, it is possible. You will need the following components:

  • The website won't notify you when something changes. Thus, you have to poll the website frequently to find out if something changed.

  • Since the website offers no API, you will have to download the HTML and parse it.

Using these keywords in your search, you should find lots of material on StackOverflow, e.g.

  • Android Polling from a Server periodically
  • How can I parse webpage content in Android

I can't retrieve data from server to android studio although data is shown in a browser

you can use StringRequest instead of jsonObject with the new library of volley

compile 'com.android.volley:volley:1.0.0'

How to make an Activity fetch data from the server automatically in android

you have to call the service on second activity's on create method after setContentView() and fetch the data from the shared preferences and pass that data to the php script and catch response and show the data to the apropreate location.

and the credentials you want to give for one day duration then check the entry with the system date and validate it. if it is belong to the same date then it will pass to the thank you page otherwise it allow user to move to second activity.



Related Topics



Leave a reply



Submit