I want to be able to, using my android device, connect to a mySQL database, send in a parameter that will be used in an SQL-statement, and I want to get the result back and be able to present it. It sounds easy, but all tutorials and examples I can find suffer from:
- extremely overbuilt (10 classes minimum to make that perfect button)
- incredibly confusing (no comments, explanations and retarded variable names)
- dependent on classes that don't exist
If I strip something unnecessary down everything crashes, so I can't extract what's actually important to make it remotely readable/understandable.
So, in the simplest way possible: what is needed in my android app to connect to my database? How do I send a parameter to the php-script? How can I generate a result from it that the android app can read?
UPDATE, STRIPPING ESSENTIALS TAKE 1 So as I mentioned in one of the comments on SoftCoder's answer, I'll try and take his complete app and strip out the fancy stuff to just get what's needed to connect to mySQL.
First off, I have added <uses-permission android:name="android.permission.INTERNET" />
in the manifest. The .php looks like this (host, user, password etc is something else in reality):
<?php
$con = mysql_connect("HOST","USER","PASSWORD");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db("database_name", $con);
$result = mysql_query("SELECT * FROM Table;");
while($row = mysql_fetch_array($result))
{
echo $row['col1'];
echo $row['col2'];
}
mysql_close($con);
?>
This script prints out all entries from the table.
Now to the complete activity!
package com.example.project;
import java.io.*;
import org.apache.http.HttpResponse;
import org.apache.http.client.*;
import org.apache.http.client.methods.*;
import org.apache.http.impl.client.*;
import org.json.*;
import android.app.*;
import android.os.*;
import android.util.*;
import android.view.*;
import android.widget.*;
public class MainActivity extends Activity
{
private String jsonResult;
private String url = "url_to_php";
InputStream is=null;
String result=null;
String line=null;
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//supposedly the app wont crash with "NetworkOnMainThreadException". It crashes anyway
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
//create our Async class, because we can't work magic in the mainthread
JsonReadTask task = new JsonReadTask();
task.execute(new String[] { url });
}
private class JsonReadTask extends AsyncTask<String, Void, String>
{
// doInBackground Method will not interact with UI
protected String doInBackground(String... params)
{
// the below code will be done in background
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(params[0]);
try
{
//not sure what this does but it sounds important
HttpResponse response = httpclient.execute(httppost);
//took the "stringbuilder" apart and shoved it here instead
String rLine = "";
StringBuilder answer = new StringBuilder();
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
while ((rLine = rd.readLine()) != null)
answer.append(rLine);
//put the string into a json, don't know why really
jsonResult = answer.toString();
}
catch (ClientProtocolException e)
{
e.printStackTrace();
Log.e("Fail 12", e.toString());
}
catch (IOException e)
{
Log.e("Fail 22", e.toString());
e.printStackTrace();
}
return null;
}
}
// after the doInBackground Method is done the onPostExecute method will be called
protected void onPostExecute(String result) throws JSONException
{
// I skipped the method "drwer"-something and put it here instead, since all this method did was to call that method
// getting data from server
JSONObject jsonResponse = new JSONObject(jsonResult);
if(jsonResponse != null)
{
//I think the argument here is what table we'll look at... which is weird since we use php for that
JSONArray jsonMainNode = jsonResponse.optJSONArray("Tablename");
// get total number of data in table
for (int i = 0; i < jsonMainNode.length(); i++)
{
JSONObject jsonChildNode = jsonMainNode.getJSONObject(i);
String name = jsonChildNode.optString("col1"); // here name is the table field
String number = jsonChildNode.optString("col2"); // here id is the table field
String outPut = name + number ; // add two string to show in listview
//output to log instead of some weird UI on the device, just to see if it connects
Log.d("Log", outPut.toString());
}
}
}
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item)
{
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings)
return true;
return super.onOptionsItemSelected(item);
}
}
So this is what I came up with so far that would count as "simple as possible", no fancy UI or jumping between methods (utilizing good code conventions is not important here). Since everything crashes with a "NetworkOnMainThreadException" like someone else already said it would, it's impossible to test it. Why is it crashing with this exception even though I'm using both an AsyncTask and call the Strict-thingy?