Connect mySQL with Android

笑着哭i 提交于 2019-12-29 09:33:36

问题


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?


回答1:


Here is the example

EDIT: First Create A database Name suppose dbname in MySql in wamp or in your server and create a table named emp_info in which two fields are added id and name

Here the Scenario is to insert ID and NAME of employee from the EDITTEXT to MYSQL server database

The Global Variables are

  String name;
    String id;
    InputStream is=null;
    String result=null;
    String line=null;
    int code;

For Activity Code

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONObject;

import android.app.Activity;
import android.os.Bundle;
import android.os.StrictMode;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class add extends Activity {

    String name;
    String id;
    InputStream is=null;
    String result=null;
    String line=null;
    int code;
    String tobed = null;



    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.add);
        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);
        final EditText e_id=(EditText) findViewById(R.id.editText1);
        final EditText e_name=(EditText) findViewById(R.id.editText2);
        Button insert=(Button) findViewById(R.id.button1);

        insert.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub

            id = e_id.getText().toString();
            name = e_name.getText().toString();

            insert();
        }
    });
    }
}

Method of inserting data

public void insert()
    {
        ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();

      // put the values of id and name in that variable
    nameValuePairs.add(new BasicNameValuePair("id",id));
    nameValuePairs.add(new BasicNameValuePair("name",name));

        try
        {
        HttpClient httpclient = new DefaultHttpClient();

          // here is the php file
         // for local use for example if you are using wamp just put the file in www/project folder
        HttpPost httppost = new HttpPost("http://10.0.2.2/project/insert2.php");
        // if the file is on server
        HttpPost httppost = new HttpPost("http://example.com/insert2.php");
            httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
            HttpResponse response = httpclient.execute(httppost); 
            HttpEntity entity = response.getEntity();
            is = entity.getContent();
            Log.e("pass 1", "connection success ");
    }
        catch(Exception e)
    {
            Log.e("Fail 1", e.toString());
            Toast.makeText(getApplicationContext(), "Invalid IP Address",
            Toast.LENGTH_LONG).show();
    }     

        try
        {
            BufferedReader reader = new BufferedReader
            (new InputStreamReader(is,"iso-8859-1"),8);
            StringBuilder sb = new StringBuilder();
            while ((line = reader.readLine()) != null)
        {
                sb.append(line + "\n");
            }
            is.close();
            result = sb.toString();
        Log.e("pass 2", "connection success ");
    }
        catch(Exception e)
    {
            Log.e("Fail 2", e.toString());
    }     

    try
    {

            // get the result from php file
            JSONObject json_data = new JSONObject(result);
            code=(json_data.getInt("code"));

            if(code==1)
            {
        Toast.makeText(getBaseContext(), "Inserted Successfully",
            Toast.LENGTH_SHORT).show();
            }
            else
            {
         Toast.makeText(getBaseContext(), "Sorry, Try Again",
            Toast.LENGTH_LONG).show();
            }
    }
    catch(Exception e)
    {
            Log.e("Fail 3", e.toString());
            Log.i("tagconvertstr", "["+result+"]");
    }
    }

here is insert2.php file

<?php
    // this variables is used for connecting to database and server
    $host="yourhost";
    $uname="username";
    $pwd='pass';
    $db="dbname";

     // this is for connecting
    $con = mysql_connect($host,$uname,$pwd) or die("connection failed");
    mysql_select_db($db,$con) or die("db selection failed");

    // getting id and name from the client
     if(isset($_REQUEST)){
    $id=$_REQUEST['id'];
    $name=$_REQUEST['name'];}

    $flag['code']=0;

    // query for insertion
    // table name emp_info and its fields are id and name
    if($r=mysql_query("insert into emp_info values('$name','$id') ",$con))
    {
        // if query runs succesfully then set the flag to 1 that will be send to client app
        $flag['code']=1;
        echo"hi";
    }
      // send result to client that will be 1 or 0
    print(json_encode($flag));
    //close
    mysql_close($con);


 ?>

Second Edit:-

For reading data i have done asyntask

Here the data is displayed in a listview.

public class read extends Activity {
     private String jsonResult;//
      // use this if your file is on server
     private String url = "http://exmaple.com/read.php";
     // use this if you are locally using
     // private String url = "http://10.0.2.2/project/read.php";
     private ListView listView;
     Context context;
     String name;
        String id;
        InputStream is=null;
        String result=null;
        String line=null;
        int code;
     @Override
     protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.read);
      StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
      StrictMode.setThreadPolicy(policy);
      context = this;
      listView = (ListView) findViewById(R.id.listView1);
      accessWebService();
     }

accessWebService method

       public void accessWebService() {
       JsonReadTask task = new JsonReadTask();
       task.execute(new String[] { url });
         }

for JsonReadTask class

private class JsonReadTask extends AsyncTask<String, Void, String> {
      // doInBackground Method will not interact with UI 
      @Override

      protected String doInBackground(String... params) {
       // the below code will be done in background
       HttpClient httpclient = new DefaultHttpClient();
       HttpPost httppost = new HttpPost(params[0]);
       try {
        HttpResponse response = httpclient.execute(httppost);
        jsonResult = inputStreamToString(
          response.getEntity().getContent()).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;
      }

      private StringBuilder inputStreamToString(InputStream is) {
       String rLine = "";
       StringBuilder answer = new StringBuilder();
       BufferedReader rd = new BufferedReader(new InputStreamReader(is));

       try {
        while ((rLine = rd.readLine()) != null) {
         answer.append(rLine);
        }
       }

       catch (IOException e) {
        // e.printStackTrace();
        Toast.makeText(getApplicationContext(),
          "Error..." + e.toString(), Toast.LENGTH_LONG).show();
       }
       return answer;
      }

      // after the doInBackground Method is done the onPostExecute method will be called
      @Override
      protected void onPostExecute(String result) {
      // here you can interact with UI
       ListDrwaer();
      }
     }// end async task

ListDrawaer Method

 // build hash set for list view
     public void ListDrwaer() {
      List<Map<String, String>> employeeList = new ArrayList<Map<String, String>>();

      try {
        // getting data from server 
       JSONObject jsonResponse = new JSONObject(jsonResult);
       if(jsonResponse != null)
       {
       JSONArray jsonMainNode = jsonResponse.optJSONArray("emp_info");

       // get total number of data in table
       for (int i = 0; i < jsonMainNode.length(); i++) {
        JSONObject jsonChildNode = jsonMainNode.getJSONObject(i);

        String name = jsonChildNode.optString("name"); // here name is the table field
        String number = jsonChildNode.optString("id"); // here id is the table field
        String outPut = name + number ; // add two string to show in listview 
        employeeList.add(createEmployee("employees", outPut));
       }
       }
      } catch (JSONException e) {
       Toast.makeText(getApplicationContext(), "Error" + e.toString(),
         Toast.LENGTH_SHORT).show();
      }

      SimpleAdapter simpleAdapter = new SimpleAdapter(this, employeeList,
        android.R.layout.simple_list_item_1,
        new String[] { "employees" }, new int[] { android.R.id.text1 });
      listView.setAdapter(simpleAdapter);
     }

     private HashMap<String, String> createEmployee(String name, String number) {
      HashMap<String, String> employeeNameNo = new HashMap<String, String>();
      employeeNameNo.put(name, number);
      return employeeNameNo;
     }
    }

and your read.php file code

<?php
$host="localhost"; //replace with database hostname
$username="root"; //replace with database username
$password=""; //replace with database password
$db_name="dbname"; //replace with database name

$con=mysql_connect("$host", "$username", "$password")or die("cannot connect");
mysql_select_db("$db_name")or die("cannot select DB");
$sql = "select * from emp_info";
$result = mysql_query($sql);
$json = array();

if(mysql_num_rows($result)){
while($row=mysql_fetch_assoc($result)){
$json['emp_info'][]=$row;
}
}
mysql_close($con);
echo json_encode($json);
?> 

and if you want to check you internet connection before using this insertion and reading use this method .. i.e put this method in if else statement

 public boolean isOnline() {
                ConnectivityManager cm =
                    (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
                NetworkInfo netInfo = cm.getActiveNetworkInfo();
                if (netInfo != null && netInfo.isConnectedOrConnecting()) {
                    return true;
                }
                return false;
            }

For Updation and deletion use the insert method to pass the values to the server and just change the query of insert2.php to update ones like this

if($r=mysql_query("UPDATE emp_info SET employee_name = '$name' WHERE employee_name = '$id'",$con))
    {
        $flag['code']=1;
    } 

for deletion

if($r=mysql_query("DELETE FROM emp_info WHERE employee_name = '$name'",$con))
    {
        $flag['code']=1;
        echo"hi";
    }

Also when you have learn this, the next task you should learn threading and Asyntask to make it more improved as working on main thread is not good in android. just put this insert method in Asyntask as i have mentioned in Reading method so that UI dont get disturbed and the internet thing is done in background.

NOTE:

for new version of php add this line after <?php snippet

error_reporting(E_ALL ^ E_DEPRECATED);


来源:https://stackoverflow.com/questions/25408822/connect-mysql-with-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!