Я хочу, чтобы с помощью моего устройства Android подключался к базе данных mySQL, отправлял параметр, который будет использоваться в SQL-заявлении, и я хочу вернуть результат и быть в состоянии представить его. Это звучит просто, но все учебники и примеры, которые я могу найти, страдают от:
Если я убираю что-то ненужное, все падает, поэтому я не могу извлечь то, что действительно важно, чтобы сделать его доступным для чтения / понятным.
Итак, самым простым способом: что нужно в моем приложении Android для подключения к моей базе данных? Как отправить параметр в php-скрипт? Как я могу сгенерировать результат, который может прочитать приложение для Android?
ОБНОВЛЕНИЕ, ПОСЛЕДОВАТЕЛЬНЫЕ ЭФФЕКТЫ ПРИНИМАЮТ 1 Итак, как я упомянул в одном из комментариев на ответ SoftCoder, я попытаюсь взять его полное приложение и вычеркнуть причудливые вещи, чтобы получить только то, что нужно для подключения к mySQL.
Во-первых, я добавил в манифесте <uses-permission android:name="android.permission.INTERNET" />
. .php выглядит так (хост, пользователь, пароль и т. Д. – это что-то еще в действительности):
<?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); ?>
Этот скрипт выдает все записи из таблицы.
Теперь к полной активности!
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); } }
Таким образом, это то, к чему я придумал до сих пор, который будет считаться «простым, насколько это возможно», никакой причудливый пользовательский интерфейс или прыжок между методами (использование хороших условных кодов здесь не важно). Поскольку все происходит с «NetworkOnMainThreadException», как кто-то еще сказал, что это будет, его невозможно проверить. Почему это сбой с этим исключением, хотя я использую AsyncTask и называю Strict-thingy?
Вот пример
РЕДАКТИРОВАТЬ: Сначала создайте базу данных. Предположите, что имя dbname в MySql в wamp или на вашем сервере и создайте таблицу с именем emp_info, в которую добавлены два поля id и name
Здесь Сценарий заключается в том, чтобы вставить идентификатор и NAME сотрудника из базы данных EDITTEXT в MYSQL
Глобальные переменные
String name; String id; InputStream is=null; String result=null; String line=null; int 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(); } }); } }
Способ вставки данных
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+"]"); } }
здесь находится файл insert2.php
<?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); ?>
Здесь данные отображаются в виде списка.
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
public void accessWebService() { JsonReadTask task = new JsonReadTask(); task.execute(new String[] { url }); }
для класса JsonReadTask
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
// 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; } }
и ваш код файла read.php
<?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); ?>
в<?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); ?>
и если вы хотите проверить подключение к Интернету, прежде чем использовать эту вставку и чтение, используйте этот метод .. ie поставьте этот метод в 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; }
Для обновления и удаления используйте метод insert для передачи значений на сервер и просто измените запрос insert2.php, чтобы обновить такие, как это
if($r=mysql_query("UPDATE emp_info SET employee_name = '$name' WHERE employee_name = '$id'",$con)) { $flag['code']=1; }
для удаления
if($r=mysql_query("DELETE FROM emp_info WHERE employee_name = '$name'",$con)) { $flag['code']=1; echo"hi"; }
Также, когда вы узнаете об этом, следующей задачей вы должны изучить потоки и Asyntask, чтобы сделать его более совершенным, поскольку работа над основным потоком не очень хороша в Android. просто поместите этот метод в Asyntask, как я упомянул в методе Чтения, так что пользовательский интерфейс не нарушается, а интернет-приложение выполняется в фоновом режиме.
ЗАМЕТКА:
для новой версии php добавьте эту строку после <?php
snippet
error_reporting(E_ALL ^ E_DEPRECATED);