آموزش دریافت اطلاعات از mysql و قرار دادن در Spinner
سلام دوستان امیدوارم حالتان خوب باشد در این سری از آموزش برنامه نویسی اندروید به آموزش دریافت اطلاعات از mysql و قرار دادن در Spinner می پردازیم ما آموزش استفاده از دیتابیس Mysql و خواندن آن را به صورت شش پارت جداگانه در سایت قرار دادیم امروز به بررسی خواندن جدول (table) از دیتابیس mysql و قرار دادن آن در spinner خواهیم پرداخت در ادامه با ما همراه باشید.
در این آموزش ما از مجازی ساز xampp برای ایجاد دیتابیس استفاده خواهیم کرد در صورتی که شبیه سازی های متاوفت دیگری دارید می توانید از آنها استفاده کنید (زیاد فرق نمی کنند) در صورتی که مک دارید از می توایند از مجازی ساز MAMP استفاده کنید و در صورتی که از لینوکس دارید از LAMP می توانید استفاده کنید.
امکان استفاده از این آموزش در
بعد از اجرای xampp دو سرویس Apache و Mysql را اجرا کنید ( بروی دکمه های start کلیک کنید.
سپس در کنار همان دکمه start گزینه Admin را کلیک کنید منظور mysql است . آن را در مروگر باز کنید می توانید از آدرس زیر نیز استفاده کنید.
1 | localhost/phpmyadmin/ |
سپس یک دیتابیس به نام food ایجاد کنید.
سپس کد sql زیر را در آن اجرا کنید برای اینکار ابتدا باید دیتابیس ساخته شده (food) را انتخاب کنید سپس وارد tab به نام sql شده و در آن کادر کد زیر را قرار دهید.
1 2 3 4 5 6 7 8 9 10 11 | CREATE TABLE IF NOT EXISTS `categories` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(30) NOT NULL, PRIMARY KEY (`id`) ); INSERT INTO `categories` (`name`) VALUES ('Beverages'), ('Bread'), ('Cereals'), ('Cheese'), ('Citrus Fruits'); |
یک پوشه به نام food_api در مسیر زیر ایجاد کنید.
1 | C:\xampp |
فایل های php که ایجاد می کنید باید در این پوشه باشد.
در پوشه ذکر شده یک فایل به نام Config.php ایجاد کرده و کدهای زیر را در آن قرار دهید.
1 2 3 4 5 6 | <?php define('DB_USERNAME', 'root'); define('DB_PASSWORD', ''); define('DB_HOST', 'localhost'); define('DB_NAME', 'food'); ?> |
این فایل شامل نام دیتابیس و یوزر و پسورد دیتابیس است. در صورتی که بروی سرر است شما باید بخش پسورد را نیز پر کنید.
باید یک فایل کلاس برای بررسی اتصال به دیتابیس ایجاد کنیم.
پس یک فالی php به نام DbConnect.php ایجاد کرده و کدهای زیر را در آن قرار دهید.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <?php class DbConnect { private $conn; function __construct() { $this->connect(); } function __destruct() { $this->close(); } function connect() { include_once dirname(__FILE__) . './Config.php'; $this->conn = mysql_connect(DB_HOST, DB_USERNAME, DB_PASSWORD) or die(mysql_error()); mysql_select_db(DB_NAME) or die(mysql_error()); return $this->conn; } function close() { mysql_close($this->conn); } } ?> |
یک فایل php دیگر به نام get_categories.php ایجاد کرده و کدهای زیر را در آن قرار دهید. کار اصلی این کار دیافت رکورد ها از دیتابیس دریافت می کنید و به صورت json آن را خروجی میدهد.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <?php include_once './DbConnect.php'; function getCategories(){ $db = new DbConnect(); $response = array(); $response["categories"] = array(); $result = mysql_query("SELECT * FROM categories"); while($row = mysql_fetch_array($result)){ $tmp = array(); $tmp["id"] = $row["id"]; $tmp["name"] = $row["name"]; array_push($response["categories"], $tmp); } header('Content-Type: application/json'); echo json_encode($response); } getCategories(); ?> |
ما یک فایل دیگه به نام new_category.php داریم کار این فایل اضافه کردن یک categories جدید به دیتابیس است . (در صورتی که خواستید می تونید از این بخش استفاده کنید )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <?php include_once './DbConnect.php'; function createNewCategory() { if (isset($_POST["name"]) && $_POST["name"] != "") { $response = array(); $category = $_POST["name"]; $db = new DbConnect(); $query = "INSERT INTO categories(name) VALUES('$category')"; $result = mysql_query($query) or die(mysql_error()); if ($result) { $response["error"] = false; $response["message"] = "Category created successfully!"; } else { $response["error"] = true; $response["message"] = "Failed to create category!"; } } else { $response["error"] = true; $response["message"] = "Category name is missing!"; } echo json_encode($response); } createNewCategory(); ?> |
کد بالا عملیات post را انجام میدهد یعنی یک مقداری ورودی را میگیرد و پست می کند.
تا اینجا کد های php به اتمام رسیده حالا به سراغ پروژه اندروید می رویم.
باید دسترسی استفاده از اینترنت را در AndroidManifest.xml اضافه کنید.
1 | <uses-permission android:name="android.permission.INTERNET"/> |
ابتدا باید یک کلاس به نام Category.java ایجاد کنید این کلاس همان کلاس model ماست به این کلاس getter و setter نیز می گویند.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | package ir.programchi; public class Category { private int id; private String name; public Category(){} public Category(int id, String name){ this.id = id; this.name = name; } public void setId(int id){ this.id = id; } public void setName(String name){ this.name = name; } public int getId(){ return this.id; } public String getName(){ return this.name; } } |
یک کلاس به نام ServiceHandler.java ایجاد کنید کار این کلاس خواندن json است منظور همان دانلود است ابتدا باید دریافت شود سپس مورد استفاده قرار گیرد.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | package ir.programchi; 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 android.util.Log; public class ServiceHandler { static InputStream is = null; static String response = null; public final static int GET = 1; public final static int POST = 2; public ServiceHandler() { } public String makeServiceCall(String url, int method) { return this.makeServiceCall(url, method, null); } public String makeServiceCall(String url, int method, List<NameValuePair> params) { try { DefaultHttpClient httpClient = new DefaultHttpClient(); HttpEntity httpEntity = null; HttpResponse httpResponse = null; if (method == POST) { HttpPost httpPost = new HttpPost(url); if (params != null) { httpPost.setEntity(new UrlEncodedFormEntity(params)); } httpResponse = httpClient.execute(httpPost); } else if (method == GET) { if (params != null) { String paramString = URLEncodedUtils .format(params, "utf-8"); url += "?" + paramString; } HttpGet httpGet = new HttpGet(url); httpResponse = httpClient.execute(httpGet); } httpEntity = httpResponse.getEntity(); is = httpEntity.getContent(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } try { BufferedReader reader = new BufferedReader(new InputStreamReader( is, "UTF-8"), 8); StringBuilder sb = new StringBuilder(); String line = null; while ((line = reader.readLine()) != null) { sb.append(line + "\n"); } is.close(); response = sb.toString(); } catch (Exception e) { Log.e("Buffer Error", "Error: " + e.toString()); } return response; } } |
کلاس بالا کاری همانند کتاب خانه های volley را انجام میدهد اما حجم کمتری دارد.
وارد activity_main.xml شده و کدهای زیر را قرار دهید.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="10dp" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="New food category" /> <EditText android:id="@+id/txtCategory" android:layout_width="fill_parent" android:layout_height="wrap_content"/> <Button android:id="@+id/btnAddNewCategory" android:text="Create" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginBottom="40dp"/> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Select food category"/> <Spinner android:id="@+id/spinFood" android:layout_width="fill_parent" android:layout_height="wrap_content"/> </LinearLayout> |
در بالا یک EditText وجود دارد که با آن می توانید یک Category جدید در سرور ایجاد کنید و در پایین تر هم یک spinner وجود دارد.
و در آخر کد مربوط به MainActivity.java همانند زیر می شود.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | package ir.programchi; import java.util.ArrayList; import java.util.List; import org.apache.http.NameValuePair; import org.apache.http.message.BasicNameValuePair; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import android.app.Activity; import android.app.ProgressDialog; import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemSelectedListener; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.Spinner; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity implements OnItemSelectedListener { private Button btnAddNewCategory; private TextView txtCategory; private Spinner spinnerFood; private ArrayList<Category> categoriesList; ProgressDialog pDialog; private String URL_NEW_CATEGORY = "http://10.0.2.2/food_api/new_category.php"; private String URL_CATEGORIES = "http://10.0.2.2/food_api/get_categories.php"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btnAddNewCategory = (Button) findViewById(R.id.btnAddNewCategory); spinnerFood = (Spinner) findViewById(R.id.spinFood); txtCategory = (TextView) findViewById(R.id.txtCategory); categoriesList = new ArrayList<Category>(); spinnerFood.setOnItemSelectedListener(this); btnAddNewCategory.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (txtCategory.getText().toString().trim().length() > 0) { String newCategory = txtCategory.getText().toString(); new AddNewCategory().execute(newCategory); } else { Toast.makeText(getApplicationContext(), "Please enter category name", Toast.LENGTH_SHORT) .show(); } } }); new GetCategories().execute(); } private void populateSpinner() { List<String> lables = new ArrayList<String>(); txtCategory.setText(""); for (int i = 0; i < categoriesList.size(); i++) { lables.add(categoriesList.get(i).getName()); } ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, lables); spinnerAdapter .setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinnerFood.setAdapter(spinnerAdapter); } private class GetCategories extends AsyncTask<Void, Void, Void> { @Override protected void onPreExecute() { super.onPreExecute(); pDialog = new ProgressDialog(MainActivity.this); pDialog.setMessage("Fetching food categories.."); pDialog.setCancelable(false); pDialog.show(); } @Override protected Void doInBackground(Void... arg0) { ServiceHandler jsonParser = new ServiceHandler(); String json = jsonParser.makeServiceCall(URL_CATEGORIES, ServiceHandler.GET); Log.e("Response: ", "> " + json); if (json != null) { try { JSONObject jsonObj = new JSONObject(json); if (jsonObj != null) { JSONArray categories = jsonObj .getJSONArray("categories"); for (int i = 0; i < categories.length(); i++) { JSONObject catObj = (JSONObject) categories.get(i); Category cat = new Category(catObj.getInt("id"), catObj.getString("name")); categoriesList.add(cat); } } } catch (JSONException e) { e.printStackTrace(); } } else { Log.e("JSON Data", "Didn't receive any data from server!"); } return null; } @Override protected void onPostExecute(Void result) { super.onPostExecute(result); if (pDialog.isShowing()) pDialog.dismiss(); //populateSpinner(); } } private class AddNewCategory extends AsyncTask<String, Void, Void> { boolean isNewCategoryCreated = false; @Override protected void onPreExecute() { super.onPreExecute(); pDialog = new ProgressDialog(MainActivity.this); pDialog.setMessage("Creating new category.."); pDialog.setCancelable(false); pDialog.show(); } @Override protected Void doInBackground(String... arg) { String newCategory = arg[0]; // Preparing post params List<NameValuePair> params = new ArrayList<NameValuePair>(); params.add(new BasicNameValuePair("name", newCategory)); ServiceHandler serviceClient = new ServiceHandler(); String json = serviceClient.makeServiceCall(URL_NEW_CATEGORY, ServiceHandler.POST, params); Log.d("Create Response: ", "> " + json); if (json != null) { try { JSONObject jsonObj = new JSONObject(json); boolean error = jsonObj.getBoolean("error"); // checking for error node in json if (!error) { // new category created successfully isNewCategoryCreated = true; } else { Log.e("Create Category Error: ", "> " + jsonObj.getString("message")); } } catch (JSONException e) { e.printStackTrace(); } } else { Log.e("JSON Data", "Didn't receive any data from server!"); } return null; } @Override protected void onPostExecute(Void result) { super.onPostExecute(result); if (pDialog.isShowing()) pDialog.dismiss(); if (isNewCategoryCreated) { runOnUiThread(new Runnable() { @Override public void run() { // fetching all categories new GetCategories().execute(); } }); } } } @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { Toast.makeText( getApplicationContext(), parent.getItemAtPosition(position).toString() + " Selected" , Toast.LENGTH_LONG).show(); } @Override public void onNothingSelected(AdapterView<?> arg0) { } } |
کد بسیار طولانی است توصیه می کنم تست کنید سپس کد را از بالا به پایین بررسی کنید.
URL_NEW_CATEGORY آدرس فایل ما در xampp است + آدرس آیپی local کامپیوتر من (این فایل برای ایجاد یک گروه جدید بود)
URL_CATEGORIES آدرس فایل ما در xampp + آدرس آیپی local کامپیوتر من (این فایل برای خواندن دیتابیس و قرار دادن در spinner بود)
در بالا دو تا کلاس Async داریم برای انجام عمل insert و خواندن json از آدرس url و در آخر هم دیتای خونده شده را در listview بالا populate یا قرار می دهیم.
از progressDialog هم استفاده شده است کمی دقت کنید چیز خاصی در کد بالا استفاده نشده است.
این آموزش هم به پایان رسید.
موفق و پیروز باشید.