В данном уроке я покажу как можно на Android работать с MySQL базой данных на основе JSON формата.

В этой части данного урока мы перейдем не посредственно к созданию самого Android приложения, так как backend мы написали в прошлом уроке  ‘Как работать с MySQL в Android? Часть 1‘, где мы сделали серверную часть на PHP которая получает данные с БД и формирует ответ в качестве JSON формата.

Шаг 1. Создание Android приложение

Создаем Androi приложение File->New Project :

После создания проекта создайте следующий список классов:

Шаг 2. Настраиваем Manifest

Теперь заходим в AndroidManifest.xml и прописываем там все наши только что созданные классы, все кроме класса JSONPaser, так как все эти классы будут Activity.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.devcolibri.androidandmysql"
          android:versionCode="1"
          android:versionName="1.0">
    <uses-sdk android:minSdkVersion="8"/>
    <application android:label="@string/app_name">
        <activity android:name=".MainScreenActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <!-- All Product Activity -->
        <activity
                android:name=".AllProductsActivity"
                android:label="All Products" >
        </activity>

        <!-- Add Product Activity -->
        <activity
                android:name=".NewProductActivity"
                android:label="Add New Product" >
        </activity>

        <!-- Edit Product Activity -->
        <activity
                android:name=".EditProductActivity"
                android:label="Edit Product" >
        </activity>
    </application>

    <!--  Internet Permissions -->
    <uses-permission android:name="android.permission.INTERNET" />
</manifest>

Шаг 3. Создание layout

Теперь для каждого класса Activity создадим layout.

Первый будет main_screen.xml для Activity MainScreenActivity:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:orientation="vertical"
              android:gravity="center_horizontal">

    <!--  Эта кнопка будет открывать окно для просмотра всех продуктов -->
    <Button android:id="@+id/btnViewProducts"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="@string/btn_viewproduct"
            android:layout_marginTop="25dip"/>

    <!--  Эта кнопка будет открывать окно для создания нового продукта -->
    <Button android:id="@+id/btnCreateProduct"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="@string/btn_addnewproduct"
            android:layout_marginTop="25dip"/>

</LinearLayout>

Выглядеть она должна так:

Теперь создадим layout all_products.xml для AllProductsActivity:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:orientation="vertical">
    <!--
        Главный ListView
        Всегда давайте значение идентификатора
        в виде списка(@android:id/list)
    -->
    <ListView
            android:id="@android:id/list"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"/>

</LinearLayout>

и вторая дополнительная list_item.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="fill_parent"
              android:layout_height="wrap_content"
              android:orientation="vertical" >

    <!--
        Идентификатор продукта id
        (pid) - будет HIDDEN - используется для передачи в другой activity -->
    <TextView
            android:id="@+id/pid"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:visibility="gone" />

    <TextView
            android:id="@+id/name"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:paddingTop="6dip"
            android:paddingLeft="6dip"
            android:textSize="17dip"
            android:textStyle="bold" />

</LinearLayout>

Выглядит она так:

Следующая add_product.xml для NewProductActivity:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical" >

    <TextView android:layout_width="fill_parent"
              android:layout_height="wrap_content"
              android:text="Product Name"
              android:paddingLeft="10dip"
              android:paddingRight="10dip"
              android:paddingTop="10dip"
              android:textSize="17dip"/>

    <EditText android:id="@+id/inputName"
              android:layout_width="fill_parent"
              android:layout_height="wrap_content"
              android:layout_margin="5dip"
              android:layout_marginBottom="15dip"
              android:singleLine="true"/>

    <TextView android:layout_width="fill_parent"
              android:layout_height="wrap_content"
              android:text="Price"
              android:paddingLeft="10dip"
              android:paddingRight="10dip"
              android:paddingTop="10dip"
              android:textSize="17dip"/>

    <EditText android:id="@+id/inputPrice"
              android:layout_width="fill_parent"
              android:layout_height="wrap_content"
              android:layout_margin="5dip"
              android:layout_marginBottom="15dip"
              android:singleLine="true"
              android:inputType="numberDecimal"/>

    <TextView android:layout_width="fill_parent"
              android:layout_height="wrap_content"
              android:text="Description"
              android:paddingLeft="10dip"
              android:paddingRight="10dip"
              android:paddingTop="10dip"
              android:textSize="17dip"/>

    <EditText android:id="@+id/inputDesc"
              android:layout_width="fill_parent"
              android:layout_height="wrap_content"
              android:layout_margin="5dip"
              android:layout_marginBottom="15dip"
              android:lines="4"
              android:gravity="top"/>

    <Button android:id="@+id/btnCreateProduct"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="Create Product"/>

</LinearLayout>

Выглядит она так:

И последний это edit_product.xml для EditProductActivity:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical" >

    <TextView android:layout_width="fill_parent"
              android:layout_height="wrap_content"
              android:text="Product Name"
              android:paddingLeft="10dip"
              android:paddingRight="10dip"
              android:paddingTop="10dip"
              android:textSize="17dip"/>

    <EditText android:id="@+id/inputName"
              android:layout_width="fill_parent"
              android:layout_height="wrap_content"
              android:layout_margin="5dip"
              android:layout_marginBottom="15dip"
              android:singleLine="true"/>

    <TextView android:layout_width="fill_parent"
              android:layout_height="wrap_content"
              android:text="Price"
              android:paddingLeft="10dip"
              android:paddingRight="10dip"
              android:paddingTop="10dip"
              android:textSize="17dip"/>

    <EditText android:id="@+id/inputPrice"
              android:layout_width="fill_parent"
              android:layout_height="wrap_content"
              android:layout_margin="5dip"
              android:layout_marginBottom="15dip"
              android:singleLine="true"
              android:inputType="numberDecimal"/>

    <TextView android:layout_width="fill_parent"
              android:layout_height="wrap_content"
              android:text="Description"
              android:paddingLeft="10dip"
              android:paddingRight="10dip"
              android:paddingTop="10dip"
              android:textSize="17dip"/>

    <EditText android:id="@+id/inputDesc"
              android:layout_width="fill_parent"
              android:layout_height="wrap_content"
              android:layout_margin="5dip"
              android:layout_marginBottom="15dip"
              android:lines="4"
              android:gravity="top"/>

    <LinearLayout android:layout_width="fill_parent"
                  android:layout_height="wrap_content"
                  android:orientation="horizontal">
        <Button android:id="@+id/btnSave"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:text="Save Changes"
                android:layout_weight="1"/>

        <Button android:id="@+id/btnDelete"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:text="Delete"
                android:layout_weight="1"/>
    </LinearLayout>

</LinearLayout>

Выглядит так:

Шаг 4. Пишем Activity

Начнем с самого главного MainScreenActivity:

package com.devcolibri.androidandmysql;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainScreenActivity extends Activity {

    Button btnViewProducts;
    Button btnNewProduct;

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

        btnViewProducts = (Button) findViewById(R.id.btnViewProducts);
        btnNewProduct = (Button) findViewById(R.id.btnCreateProduct);

        // обработчик на нажатиЯ кнопки View Products
        btnViewProducts.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {
                // Запускаем Activity вывода всех продуктов
                Intent i = new Intent(getApplicationContext(), AllProductsActivity.class);
                startActivity(i);

            }
        });

        // обработчик на нажатия кнопки Add New Products
        btnNewProduct.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {
                // Запускаем Activity создания нового продукта
                Intent i = new Intent(getApplicationContext(), NewProductActivity.class);
                startActivity(i);

            }
        });
    }
}

В комментариях к коду я старался объяснить код, что будет не понятно в комментарии к этому уроку задавайте ваши вопросы.

Следующий это AllProductsActivity:

package com.devcolibri.androidandmysql;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import com.devcolibri.parser.JSONParser;
import org.apache.http.NameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;

public class AllProductsActivity extends ListActivity {

    private ProgressDialog pDialog;

    // Создаем JSON парсер
    JSONParser jParser = new JSONParser();

    ArrayList<HashMap<String, String>> productsList;

    // url получения списка всех продуктов
    private static String url_all_products = "http://test.devcolibri.com/get_all_products.php";

    // JSON Node names
    private static final String TAG_SUCCESS = "success";
    private static final String TAG_PRODUCTS = "products";
    private static final String TAG_PID = "pid";
    private static final String TAG_NAME = "name";

    // тут будет хранится список продуктов
    JSONArray products = null;

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

        // Hashmap for ListView
        productsList = new ArrayList<HashMap<String, String>>();

        // Загружаем продукты в фоновом потоке
        new LoadAllProducts().execute();

        // получаем ListView
        ListView lv = getListView();

        // на выбор одного продукта
        // запускается Edit Product Screen
        lv.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                                    int position, long id) {
                // getting values from selected ListItem
                String pid = ((TextView) view.findViewById(R.id.pid)).getText()
                        .toString();

                // Запускаем новый intent который покажет нам Activity
                Intent in = new Intent(getApplicationContext(), EditProductActivity.class);
                // отправляем pid в следующий activity
                in.putExtra(TAG_PID, pid);

                // запуская новый Activity ожидаем ответ обратно
                startActivityForResult(in, 100);
            }
        });

    }

    // Ответ из Edit Product Activity
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        // если результующий код равен 100
        if (resultCode == 100) {
            // если полученный код результата равен 100
            // значит пользователь редактирует или удалил продукт
            // тогда мы перезагружаем этот экран
            Intent intent = getIntent();
            finish();
            startActivity(intent);
        }

    }

    /**
     * Фоновый Async Task для загрузки всех продуктов по HTTP запросу
     * */
    class LoadAllProducts extends AsyncTask<String, String, String> {

        /**
         * Перед началом фонового потока Show Progress Dialog
         * */
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            pDialog = new ProgressDialog(AllProductsActivity.this);
            pDialog.setMessage("Загрузка продуктов. Подождите...");
            pDialog.setIndeterminate(false);
            pDialog.setCancelable(false);
            pDialog.show();
        }

        /**
         * Получаем все продукт из url
         * */
        protected String doInBackground(String... args) {
            // Будет хранить параметры
            List<NameValuePair> params = new ArrayList<NameValuePair>();
            // получаем JSON строк с URL
            JSONObject json = jParser.makeHttpRequest(url_all_products, "GET", params);

            Log.d("All Products: ", json.toString());

            try {
                // Получаем SUCCESS тег для проверки статуса ответа сервера
                int success = json.getInt(TAG_SUCCESS);

                if (success == 1) {
                    // продукт найден
                    // Получаем масив из Продуктов
                    products = json.getJSONArray(TAG_PRODUCTS);

                    // перебор всех продуктов
                    for (int i = 0; i < products.length(); i++) {
                        JSONObject c = products.getJSONObject(i);

                        // Сохраняем каждый json елемент в переменную
                        String id = c.getString(TAG_PID);
                        String name = c.getString(TAG_NAME);

                        // Создаем новый HashMap
                        HashMap<String, String> map = new HashMap<String, String>();

                        // добавляем каждый елемент в HashMap ключ => значение
                        map.put(TAG_PID, id);
                        map.put(TAG_NAME, name);

                        // добавляем HashList в ArrayList
                        productsList.add(map);
                    }
                } else {
                    // продукт не найден
                    // Запускаем Add New Product Activity
                    Intent i = new Intent(getApplicationContext(),
                            NewProductActivity.class);
                    // Закрытие всех предыдущие activities
                    i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                    startActivity(i);
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }

            return null;
        }

        /**
         * После завершения фоновой задачи закрываем прогрес диалог
         * **/
        protected void onPostExecute(String file_url) {
            // закрываем прогресс диалог после получение все продуктов
            pDialog.dismiss();
            // обновляем UI форму в фоновом потоке
            runOnUiThread(new Runnable() {
                public void run() {
                    /**
                     * Обновляем распарсенные JSON данные в ListView
                     * */
                    ListAdapter adapter = new SimpleAdapter(
                            AllProductsActivity.this, productsList,
                            R.layout.list_item, new String[] { TAG_PID,
                            TAG_NAME},
                            new int[] { R.id.pid, R.id.name });
                    // обновляем listview
                    setListAdapter(adapter);
                }
            });

        }

    }

}

После идет activity NewProductActivity:

package com.devcolibri.androidandmysql;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import com.devcolibri.parser.JSONParser;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;

public class NewProductActivity extends Activity {

    private ProgressDialog pDialog;

    JSONParser jsonParser = new JSONParser();
    EditText inputName;
    EditText inputPrice;
    EditText inputDesc;

    private static String url_create_product = "http://test.devcolibri.com/create_product.php";

    private static final String TAG_SUCCESS = "success";

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

        inputName = (EditText) findViewById(R.id.inputName);
        inputPrice = (EditText) findViewById(R.id.inputPrice);
        inputDesc = (EditText) findViewById(R.id.inputDesc);

        Button btnCreateProduct = (Button) findViewById(R.id.btnCreateProduct);

        btnCreateProduct.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {
                new CreateNewProduct().execute();
            }
        });
    }

    /**
     * Фоновый Async Task создания нового продукта
     **/
    class CreateNewProduct extends AsyncTask<String, String, String> {

        /**
         * Перед согданием в фоновом потоке показываем прогресс диалог
         **/
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            pDialog = new ProgressDialog(NewProductActivity.this);
            pDialog.setMessage("Создание продукта...");
            pDialog.setIndeterminate(false);
            pDialog.setCancelable(true);
            pDialog.show();
        }

        /**
         * Создание продукта
         **/
        protected String doInBackground(String[] args) {
            String name = inputName.getText().toString();
            String price = inputPrice.getText().toString();
            String description = inputDesc.getText().toString();

            // Заполняем параметры
            List<NameValuePair> params = new ArrayList<NameValuePair>();
            params.add(new BasicNameValuePair("name", name));
            params.add(new BasicNameValuePair("price", price));
            params.add(new BasicNameValuePair("description", description));

            // получаем JSON объект
            JSONObject json = jsonParser.makeHttpRequest(url_create_product, "POST", params);

            Log.d("Create Response", json.toString());

            try {
                int success = json.getInt(TAG_SUCCESS);

                if (success == 1) {
                    // продукт удачно создан
                    Intent i = new Intent(getApplicationContext(), AllProductsActivity.class);
                    startActivity(i);

                    // закрываем это окно
                    finish();
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }

            return null;
        }

        /**
         * После оконачния скрываем прогресс диалог
         **/
        protected void onPostExecute(String file_url) {
            pDialog.dismiss();
        }

    }

}

Последний EditProductActivity:

package com.devcolibri.androidandmysql;

import java.util.ArrayList;
import java.util.List;

import com.devcolibri.parser.JSONParser;
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.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class EditProductActivity extends Activity {

    EditText txtName;
    EditText txtPrice;
    EditText txtDesc;
    Button btnSave;
    Button btnDelete;

    String pid;

    private ProgressDialog pDialog;

    JSONParser jsonParser = new JSONParser();

    // url для получения одного продукта
    private static final String url_product_detials = "http://test.devcolibri.com/get_product_details.php";

    // url для обновления продукта
    private static final String url_update_product = "http://test.devcolibri.com/update_product.php";

    // url для удаления продукта
    private static final String url_delete_product = "http://test.devcolibri.com/delete_product.php";

    // JSON параметры
    private static final String TAG_SUCCESS = "success";
    private static final String TAG_PRODUCT = "product";
    private static final String TAG_PID = "pid";
    private static final String TAG_NAME = "name";
    private static final String TAG_PRICE = "price";
    private static final String TAG_DESCRIPTION = "description";

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

        btnSave = (Button) findViewById(R.id.btnSave);
        btnDelete = (Button) findViewById(R.id.btnDelete);

        // показываем форму про детальную информацию о продукте
        Intent i = getIntent();

        // получаем id продукта (pid) с формы
        pid = i.getStringExtra(TAG_PID);

        // Получение полной информации о продукте в фоновом потоке
        new GetProductDetails().execute();

        // обрабочик на кнопку сохранение продукта
        btnSave.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // запускаем выполнение задачи на обновление продукта
                new SaveProductDetails().execute();
            }
        });

        // обработчик на кнопку удаление продукта
        btnDelete.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // удалем продукт в фоновом потоке
                new DeleteProduct().execute();
            }
        });

    }

    /**
     * Фоновая асинхронная задача для получения полной информации о продукте
     **/
    class GetProductDetails extends AsyncTask<String, String, String> {

        /**
         * Перед началом показать в фоновом потоке прогресс диалог
         **/
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            pDialog = new ProgressDialog(EditProductActivity.this);
            pDialog.setMessage("Loading product details. Please wait...");
            pDialog.setIndeterminate(false);
            pDialog.setCancelable(true);
            pDialog.show();
        }

        /**
         * Получение детальной информации о продукте в фоновом режиме
         **/
        protected String doInBackground(String[] params) {

            // обновляем UI форму
            runOnUiThread(new Runnable() {
                public void run() {
                    // проверяем статус success тега
                    int success;
                    try {
                        // Список параметров
                        List<NameValuePair> params = new ArrayList<NameValuePair>();
                        params.add(new BasicNameValuePair("pid", pid));

                        // получаем продукт по HTTP запросу
                        JSONObject json = jsonParser.makeHttpRequest(url_product_detials, "GET", params);

                        Log.d("Single Product Details", json.toString());

                        success = json.getInt(TAG_SUCCESS);
                        if (success == 1) {
                            // Успешно получинна детальная информация о продукте
                            JSONArray productObj = json.getJSONArray(TAG_PRODUCT);

                            // получаем первый обьект с JSON Array
                            JSONObject product = productObj.getJSONObject(0);

                            // продукт с pid найден
                            // Edit Text
                            txtName = (EditText) findViewById(R.id.inputName);
                            txtPrice = (EditText) findViewById(R.id.inputPrice);
                            txtDesc = (EditText) findViewById(R.id.inputDesc);

                            // покаываем данные о продукте в EditText
                            txtName.setText(product.getString(TAG_NAME));
                            txtPrice.setText(product.getString(TAG_PRICE));
                            txtDesc.setText(product.getString(TAG_DESCRIPTION));

                        }else{
                            // продукт с pid не найден
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            });

            return null;
        }

        /**
         * После завершения фоновой задачи закрываем диалог прогресс
         **/
        protected void onPostExecute(String file_url) {
            // закрываем диалог прогресс
            pDialog.dismiss();
        }
    }

    /**
     * В фоновом режиме выполняем асинхроную задачу на сохранение продукта
     **/
    class SaveProductDetails extends AsyncTask<String, String, String> {

        /**
         * Перед началом показываем в фоновом потоке прогрксс диалог
         **/
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            pDialog = new ProgressDialog(EditProductActivity.this);
            pDialog.setMessage("Saving product ...");
            pDialog.setIndeterminate(false);
            pDialog.setCancelable(true);
            pDialog.show();
        }

        /**
         * Сохраняем продукт
         **/
        protected String doInBackground(String[] args) {

            // получаем обновленные данные с EditTexts
            String name = txtName.getText().toString();
            String price = txtPrice.getText().toString();
            String description = txtDesc.getText().toString();

            // формируем параметры
            List<NameValuePair> params = new ArrayList<NameValuePair>();
            params.add(new BasicNameValuePair(TAG_PID, pid));
            params.add(new BasicNameValuePair(TAG_NAME, name));
            params.add(new BasicNameValuePair(TAG_PRICE, price));
            params.add(new BasicNameValuePair(TAG_DESCRIPTION, description));

            // отправляем измененные данные через http запрос
            JSONObject json = jsonParser.makeHttpRequest(url_update_product, "POST", params);

            // проверяем json success тег
            try {
                int success = json.getInt(TAG_SUCCESS);

                if (success == 1) {
                    // продукт удачно обнавлён
                    Intent i = getIntent();
                    // отправляем результирующий код 100 чтобы сообщить об обновлении продукта
                    setResult(100, i);
                    finish();
                } else {
                    // продукт не обновлен
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }

            return null;
        }

        /**
         * После окончания закрываем прогресс диалог
         **/
        protected void onPostExecute(String file_url) {
            // закрываем прогресс диалог
            pDialog.dismiss();
        }
    }

    /**
     * Фоновая асинхронная задача на удаление продукта
     **/
    class DeleteProduct extends AsyncTask<String, String, String> {

        /**
         * На начале показываем прогресс диалог
         **/
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            pDialog = new ProgressDialog(EditProductActivity.this);
            pDialog.setMessage("уДАЛЕМ ПРОДУКТ...");
            pDialog.setIndeterminate(false);
            pDialog.setCancelable(true);
            pDialog.show();
        }

        /**
         * Удаление продукта
         **/
        protected String doInBackground(String[] args) {

            int success;
            try {
                List<NameValuePair> params = new ArrayList<NameValuePair>();
                params.add(new BasicNameValuePair("pid", pid));

                // получение продукта используя HTTP запрос
                JSONObject json = jsonParser.makeHttpRequest(url_delete_product, "POST", params);

                Log.d("Delete Product", json.toString());

                success = json.getInt(TAG_SUCCESS);
                if (success == 1) {
                    // Продукт удачно удален
                    Intent i = getIntent();
                    // отправляем результирующий код 100 для уведомления об удалении продукта
                    setResult(100, i);
                    finish();
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }

            return null;
        }

        /**
         * После оконачния скрываем прогресс диалог
         **/
        protected void onPostExecute(String file_url) {
            pDialog.dismiss();
        }
    }
}

Шаг 5. Добавим название некоторых кнопок

Давайте теперь добавим название кнопок главного Activity в string.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">AndroidAndMySQL</string>
    <string name="btn_viewproduct">View Products</string>
    <string name="btn_addnewproduct">Add New Products</string>
</resources>

Шаг 6. Добавим нужные библиотеки

После того как вы сделаете все что описано выше вы увидите, что фрагменты кода которые работают с JSON не определяются, правильно ведь мы еще не добавили нужную библиотеку json.jar его вы найдете вы прикрепленном исходнике к этому посту.

Давайте добавим эту библиотеку к нашему проекту.

Для начало скиньте её в корень проекта папку libs/json-20090211.jar.

После в Intellij IDEA зайдите в Project Structure:

После того как вы добавите библиотеку нажмите Ok.

Шаг 7. Запускаем.

Теперь смотри, что же получилось.

httpv://www.youtube.com/watch?v=BGbomXai424

14/06/2013

151 комментариев к статье "Как работать с MySQL в Android? Часть 2"

  1. Пробуем! Спасибо

    • Ув. Александр, забросили ли вы этот проект? проблемы есть, как ниже заметили из-за невозможности работать с сетями в главном потоке не работает подробный вывод продуктов, при установке targetsdk=8 ошибка пропадает, форма edit product открывается однако данные из базы не получает, No product found, succes:0

  2. Скажите, столкнулся с такой задачей. На эмуляторе работает, но когда переношу на телефон, не редактирует запись. Выбивает приложение. Подскажите пожалуйста, как с этим справиться?

  3. Помогите пожалуйста)
    метод httpClient.execute(httpPost); выдает IOException ошибку…
    сервер WAMP, PHP коды аналогичны вашим

  4. все работает, спасибо) но как быть с русским текстом?)

    • Как я понял у вас русские слова выводит так [ ??????? ] правильно?

    • В этом случаем попробуйте добавить в php файлы где происходит запись в БД эту строку:
      mysql_query(‘SET names cp1251’);
      или проверьте чтобы кодировка БД была cp1251(это лучше, после этого не надо выполнять запрос тот, что выше)

    • пример отличный. вот только с русским языком пришлось бубнов оттанцевать,..

      1. Вся структура на мускуле создается в utf8_general_ci
      2. в файл db_connect.php после строки
      $con = mysql_connect(DB_SERVER, DB_USER, DB_PASSWORD) or die(mysql_error());
      вставляем строку:
      mysql_set_charset(‘utf8’, $con);

      это решает получение данных но пока еще не вставку

      шаманим далее:
      3. В классе NewProductActivity заменяем
      params.add(new BasicNameValuePair(“name”, name));
      на
      params.add(new BasicNameValuePair(“name”, URLEncoder.encode(name, “UTF-8”))));

      с подключением соответствующих библиотек я думаю справитесь сами.

      с обновлением тоже самое.

      • забыл :(
        в файл create_products.php
        строки типа: $description = $_POST[‘description’];
        заменяем на : $description = urldecode($_POST[‘description’]);
        Все остальное по аналогии. Вот теперь все

        • Провел весь день в поисках косяка у себя, ибо использовал похожую конструкцию, облазил фигову тучу статей, и под ночь наткнул на твой коммент, спасибо тебе, ты спас мой сон

      • После добавления и правки строки (неправильные кавычки и лишняя закрывающая скобка) Eclipse ругается вот так:
        Unhandled exception type UnsupportedEncodingException
        т.е. UTF-8 не поддерживается? Или нужно изменить написание UTF-8?

  5. Ребята как выяснилось одним из читателей урока, WAMP сервер лучше не использовать.

  6. Интересная особенность работы execute метода. В том виде, в котором он описан выше работает только до sdk 9.0. При равном или большем вызывает ошибку android.os.StrictMode$AndroidBlockGuardPolicy
    Решается проблема тремя путями. 1. Установить target_sdk=8 или 2. установить strictMode правильно
    if (android.os.Build.VERSION.SDK_INT > 9) {
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);
    }
    или 3. Переписать код выше с использованием многопоточности и отделить UI поток, от сетевых потоков.

    Как мне кажется третий путь будет более правильный.
    Ждем новую статью реализованную по третьему пути. :)

  7. Выдает ошибку в этой строчке:
    new LoadAllProducts().execute();

  8. К сожалению, приложение вылетает, останавливается в new LoadAllProducts().execute();

  9. Добрый день. Отличный урок, как раз то что искал. Возникла проблема, добавил json библиотеку в проект, но при компиляции все равно выдает ошибку на строке
    JSONParser jParser = new JSONParser();
    ошибка
    java: cannot find symbol
    symbol: class JSONParser
    location: class ru.feenix.orders.loginActivity

    Не могу понять почему он не видит этот тип. Проект под андроид 4.0

  10. Люди, дайте пример с использованием многопоточности и отделением UI потока, от сетевых потоков.

  11. Подскажите, что я делаю не так, если у меня вот такая ошибка:
    Error parsing data org.json.JSONException: Value <table of type java.lang.String cannot be converted to JSONObject
    Все сделал точно по уроку

    • у меня в db_config.php для базы стоял пароль, но денвер поставил все с пустым паролем для mysql. После редактирования db_config.php (‘DB_PASSWORD’, “”). все заработало, спасибо за урок

  12. у меня не получается соединение с сервером , как можно ? Скажите пожалуйста !!!

    • я написал так : private static String url_all_products = “http://127.0.0.1/androidTestLessons/admin/get_all_products.php”;

      • Тут нужно смотреть, какая именно ошибка. Попробуйте скачать исходники, и проверить их.

        • я этот же приложений запускал через Wamp сервер , все отлично работает
          код: private static String url_all_products = «http://10.0.2.2/androidTestLessons/admin/get_all_products.php»;
          В общем я хочу сделать админку с php , админка будут добавить , изменить , удалить уроки.А приложение будут только читать из базы.Приложение работает через wamp server , но админка нет(админка через Denwer работают )) ),что мне делать?

  13. я на Oracle VM VirtualBox развернул виртуалку с андроидом, в настройках сети тип подключения прописал – виртуальный адаптер хоста. Андроид пингует 192.168.56.1., далее я в db_config.php прописал свой адрес

    и на виртуалке у меня ошибка :((
    The application AndroidAndMySQL (process com.devcolibri.androidandmysql) has stopped unexpectedly. Please try again.

    что я не так сделал?

  14. Скажите пожалуйста, как выглядит общая структура работы приложения? Android приложение>Apache сервер>PHP скрипт>MySQL. Не ругайтесь громко, я не силён в этом:(

  15. Я вам очень благодарен за статью, она мне нереально помогла!

  16. Код в исходных файлах, в некоторых местах отличается от статьи.

  17. Выдает ошибку JSONParser cannot be resolved to a type

  18. Извините, не понял, где найти исходники, прикрепленные к посту?

  19. Как правильно делать подобного рода действия во ViewPager с фрагментами(JSON парсинг и прочее)
    Заранее спасибо за ответ!

  20. Народ! Помогите пожалуйста, замучился уже. Проблема такая приложение запускатся но когда нажимаешь на View Product выдает ошибку в приложении и выкидывает. Базу сделал на Локалке на Денвере. Работаю в Еклипс. Ругается на com.devcolibri.androidandmysql .В Андроиде и Джава недавно. Что я делаю не правильно? Все делал по уроку по уроку.

    • Наверно вам wamp тут не поможет, нужно вставить фактический адрес в файле db_config.php. Эти данные видны только для того браузера через чей ip хост был развернут. При эмуляции android получает другой ip.

  21. Приложение вылетает при попытке соединения с mysql. В самом браузере все открывается, и я подумал, что ошибка в коде приложения. Так и оказалось. После проверки всех функции try-catch-ом, выяснил, что во всех активити проблема кроется в protected String doInBackground(String… args). Как решить эту проблему?

    • Все исправил, это из-за виртуального хоста wamp. Перекинул файлы на сервер хостинга – все работает (видит весь список, добовляет), кроме обновление данных, после выбора пункта, этот(EditProduct) activity вылетает. Попробовал изменить все варианты get_product_details.php, и скорее всего, дело в EditProductActivity.
      P.S. Будет правильно писать mysql_query(‘SET names utf8’);
      после $db = new DB_CONNECT();

  22. JSONObject json = jParser.makeHttpRequest(url_all_products, “GET”, params); – ругается на эту строку в чем может быть причина

  23. Здравствуйте! Такой вопрос, когда при обновлении продукта что-то не получается и мы переходим по else к логическому “продукт не обновлен” не получается вывести об этом сообщение при помощи Toast. Прога тут же вылетает с ошибкой! Как это можно решить?

  24. Спасибо очень полезный урок. И главное РНР описан. Подскажите пожалуйста как можно сделать кнопку обновления продуктов когда находишся в окне просмотра всех продуктов или лучше, чтоб продукты обновлялись (добовлались, идалялись) по мере появления/удаления их на сервере. Т.е. если один человек видит список и ктото добавил/удалил продукт, продукт в списке автоматом появился/исчез.

  25. Доброе время суток!
    Ошибка такая:
    06-24 08:01:55.115: E/Buffer Error(4586): Error converting result java.lang.NullPointerException: lock == null
    06-24 08:01:55.255: E/JSON Parser(4586): Error parsing data org.json.JSONException: End of input at character 0 of

    Какие мысли есть по этому поводу?

    • Приложение крэшится с этой ошибкой при попытке прочитать базу и при попытке создать новый продукт

    • с той ошибкой понятно стало – эмулятор не коннектился к локалхосту.
      Со смарта другая ошибка:
      06-24 15:59:40.955: E/JSON Parser(7762): Error parsing data org.json.JSONException: Value Access of type java.lang.String cannot be converted to JSONObject
      06-24 15:59:40.956: W/dalvikvm(7762): threadid=12: thread exiting with uncaught exception (group=0x40d439a8)
      06-24 15:59:40.958: E/AndroidRuntime(7762): FATAL EXCEPTION: AsyncTask #1
      06-24 15:59:40.958: E/AndroidRuntime(7762): java.lang.RuntimeException: An error occured while executing doInBackground()
      06-24 15:59:40.958: E/AndroidRuntime(7762): at android.os.AsyncTask$3.done(AsyncTask.java:299)

  26. Подскажите, пожалуйста, как решить проблему с вылетом программы при выборе продукта в All Products?

  27. Здравствуйте. Я новичок в Дроид среде. 2 дня мучаюсь на Вашем примере отобразить картинки в ListView c URL взятые с базы. Буду премного благодарен за любую помощь.

  28. Здравствуйте, у меня проблема с кодировкой кирилиці: сервер Денвер, кодировка БД ut8_general_ci. При подключении к БД ставлю кодировку cp1251, в результате:
    {
    “id”: “2”,
    “url”: “about”,
    “title”: null
    },
    {
    “id”: “3”,
    “url”: “new_student”,
    “title”: null
    },
    вместо украинских символов получаю null

    • Спасибо большое, за проделанную работу!!!
      Несколько советов, тем кто делает отправку прием данных на php сервер:
      1) Здесь приложение обращается к серверу посредством POST и GET запросов. Если будете делать с реальным сайтом приложение, то на бэкэнде надо проверять чтобы в этих запросах не было символов которые могут получить доступ к БД.
      2) Все кодировки ставьте utf8, не один час времени был потрачен на исправлении этой мелочи. Если на сервере utf8 то и на клиентской части выбираете utf8
      3) В комментариях иногда пишут не корректные ответы. Поэтому советую прежде, чем воспользоваться этим советом прочитайте о том или ином методе(функции) в интернете.
      4) Упорствуйте и будет Вам счастье.
      Александру Большое Спасибо, за Ваш труд.

  29. Спасибо за статью. Но у меня не работает подробный вывод продукта, добавление и вывод всех работает, а вот подробное нет. Вот все ошибки при переходе на определенный продукт. Нашел что из за ошибки NetworkOnMainThreadException нельзя работать с инет в главном потоке(

    10-29 16:05:44.705: E/AndroidRuntime(29044): FATAL EXCEPTION: main
    10-29 16:05:44.705: E/AndroidRuntime(29044): Process: com.devcolibri.androidandmysql, PID: 29044
    10-29 16:05:44.705: E/AndroidRuntime(29044): android.os.NetworkOnMainThreadException
    10-29 16:05:44.705: E/AndroidRuntime(29044): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1239)
    10-29 16:05:44.705: E/AndroidRuntime(29044): at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:84)
    10-29 16:05:44.705: E/AndroidRuntime(29044): at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
    10-29 16:05:44.705: E/AndroidRuntime(29044): at libcore.io.IoBridge.connect(IoBridge.java:112)
    10-29 16:05:44.705: E/AndroidRuntime(29044): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
    10-29 16:05:44.705: E/AndroidRuntime(29044): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:459)
    10-29 16:05:44.705: E/AndroidRuntime(29044): at java.net.Socket.connect(Socket.java:873)
    10-29 16:05:44.705: E/AndroidRuntime(29044): at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:125)
    10-29 16:05:44.705: E/AndroidRuntime(29044): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:144)
    10-29 16:05:44.705: E/AndroidRuntime(29044): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
    10-29 16:05:44.705: E/AndroidRuntime(29044): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
    10-29 16:05:44.705: E/AndroidRuntime(29044): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:367)
    10-29 16:05:44.705: E/AndroidRuntime(29044): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:754)
    10-29 16:05:44.705: E/AndroidRuntime(29044): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:519)
    10-29 16:05:44.705: E/AndroidRuntime(29044): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:497)
    10-29 16:05:44.705: E/AndroidRuntime(29044): at com.devcolibri.parser.JSONParser.makeHttpRequest(JSONParser.java:68)
    10-29 16:05:44.705: E/AndroidRuntime(29044): at com.devcolibri.androidandmysql.EditProductActivity$GetProductDetails$1.run(EditProductActivity.java:127)
    10-29 16:05:44.705: E/AndroidRuntime(29044): at android.os.Handler.handleCallback(Handler.java:733)
    10-29 16:05:44.705: E/AndroidRuntime(29044): at android.os.Handler.dispatchMessage(Handler.java:95)
    10-29 16:05:44.705: E/AndroidRuntime(29044): at android.os.Looper.loop(Looper.java:157)
    10-29 16:05:44.705: E/AndroidRuntime(29044): at android.app.ActivityThread.main(ActivityThread.java:5867)
    10-29 16:05:44.705: E/AndroidRuntime(29044): at java.lang.reflect.Method.invokeNative(Native Method)
    10-29 16:05:44.705: E/AndroidRuntime(29044): at java.lang.reflect.Method.invoke(Method.java:515)
    10-29 16:05:44.705: E/AndroidRuntime(29044): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
    10-29 16:05:44.705: E/AndroidRuntime(29044): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:674)
    10-29 16:05:44.705: E/AndroidRuntime(29044): at dalvik.system.NativeStart.main(Native Method)

  30. у создаваемого jsonParser нет метода makeHttpRequest, и соответственно он подсвечивается красным, что делать? пишу в android studio

  31. У меня Unfortunately, AndroidAndMySQL has stopped. Что это?

  32. Читал комменты и думал, что у меня НЕ получится… т.к. я не создал ни одного приложения для андроида самостоятельно. Мало того я и эклипс то кое-как настроил. Но представьте, как я рад, когда увидел, что всё работает. И записи в БД на хостинге обновляются и добавляются)))
    Большое спасибо автору!

  33. Добрый день, подскажите как подключить JSONParser, добавил в Gradle ” compile files(‘libs/AndroidAndMySQL/libs/json-20090211.jar’)” но почему то не работает.

    Везде ругается на на JSONParser jParser = new JSONParser(); -> Cannot resolve symbol ‘JSONParser’

    И та же проблема “import net.netai.socium.parser.JSONParser;” ругается на фразу parser. Помогите решить проблему пожалуйста :)

    С Уважением Алексей

    • Такая же проблема Android Studio ругается на строку: JSONObject json = jParser.makeHttpRequest(url_all_products, “GET”, params); библиотеку 20090211.jar подключил. Кто нибудь решил эту проблему? В eclipse’е все работает.

      • Решил проблему созданием нового класса JSONParser.
        Содержание класса:
        package *адрес Вашего пакета*;

        import android.util.Log;
        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 java.io.*;
        import java.util.List;

        public class JSONParser {

        static InputStream is = null;
        static JSONObject jObj = null;
        static String json = “”;

        // constructor
        public JSONParser() {

        }

        // function get json from url
        // by making HTTP POST or GET method
        public JSONObject makeHttpRequest(String url, String method,
        List params) {

        // Making HTTP request
        try {

        // check for request method
        if(method == “POST”){
        // request method is POST
        // defaultHttpClient
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost(url);
        httpPost.setEntity(new UrlEncodedFormEntity (params));

        HttpResponse httpResponse = httpClient.execute(httpPost);
        HttpEntity httpEntity = httpResponse.getEntity();
        is = httpEntity.getContent();

        }else if(method == “GET”){
        // request method is GET
        DefaultHttpClient httpClient = new DefaultHttpClient();
        String paramString = URLEncodedUtils.format (params, “utf-8”);
        url += “?” + paramString;
        HttpGet httpGet = new HttpGet(url);

        HttpResponse httpResponse = httpClient.execute(httpGet);
        HttpEntity 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, “iso-8859-1”), 8);
        StringBuilder sb = new StringBuilder();
        String line = null;
        while ((line = reader.readLine()) != null) {
        sb.append(line + “\n”);
        }
        is.close();
        json = sb.toString();
        } catch (Exception e) {
        Log.e (“Buffer Error”, “Error converting result ” + e.toString ());
        }

        // try parse the string to a JSON object
        try {
        jObj = new JSONObject (json);
        } catch (JSONException e) {
        Log.e(“JSON Parser”, “Error parsing data ” + e.toString());
        }

        // return JSON String
        return jObj;

        }
        }

        • П.С. Работает на реальном сервере :) парсит данные из приложения в базу и обратно

        • Кто-нибудь подскажет? У меня Android Studio и с этим классом тоже пишет E/JSON Parser﹕ Error parsing data org.json.JSONException: Value <!DOCTYPE of type java.lang.String cannot be converted to JSONObject.
          Ругается получается вот на это:
          try {
          BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"), 8);
          StringBuilder sb = new StringBuilder();
          String line = null;
          while ((line = reader.readLine()) != null) {
          sb.append(line).append("\n");
          }
          is.close();
          json = sb.toString();
          } catch (Exception e) {
          Log.e("Buffer Error", "Error converting result " + e.toString());
          }

          // пробуем распарсит JSON объект
          try {
          jObj = new JSONObject(json);
          } catch (JSONException e) {
          Log.e("JSON Parser", "Error parsing data " + e.toString());
          }
          Это без блока try в AllProductsActivity.java, а если блок try расскоментирую, то вылетает с ошибкой при нажатии на просмотр продуктов.

  34. помогите очень нужен данный проект. на емуляторе работает а на девайсе нет не могу понять в чем проблема.

  35. Помогите плз, мне нужно получить по id json строку с сервера. Серверную часть сделал. А вот как конкретно отправить и получить json строку?

  36. Спасибо большое. Супер. Могли бы такое приложение на андроиде с применением протобуф (Google Protcol Buffers) выпустить показать.

    Благодарю.

  37. За материал огромнейшее спасибо! Эта тема не потеряла своей актуальности до сих пор)

    Совет тем, кто только начал работать через Android с MySQL:
    в php скриптах за пределами пхп кода не должно быть никаких тегов html

  38. Подскажите проблема которая не раз описывалась, андроид студия ругается на строку JSONObject json = jParser.makeHttpRequest(url_all_products, “GET”, params);
    Библиотеку подключил, в JSONObject нет метода makeHttpRequest.

    Как это исправить?

  39. Кто то может выложить сборку, под сервер на UTF.

  40. Подскажите, у всех работает форма редактирование элемента списка listview. У меня вылетает на этом.

  41. Подскажите люди добрые начинающему, в каком моменте листвью(lv который) присваивает данные которые мы парсим?

  42. Здравствуйте! Подскажите пожалуйста, в какой программе создавать андроид приложения? Спасибо!

  43. Здравствуйте! Помогите пожалуйста, с сайта выходит такого вида строка {“otdel”:[{“_id”:”1″},{“_id”:”2″},{“_id”:”3″}],”success”:1}{“dolzno”:[{“_id”:”1″},{“_id”:”2″},{“_id”:”4″}]}{“spec”:[{“_id”:”1″},{“_id”:”2″},{“_id”:”3″}],”success”:1} , когда я ее пытаюсь распарсить то получается вытащить только первый объект (otdel), если очередность поменять в php файле, то программа перестанет отображать данные пока не начнешь обращаться именно к первому объекту json(от его названия не зависит, проверял). Все голову себе сломал уже((

  44. Подскажите, на телефоне вылетает при просмотре списка:
    E/Buffer Error﹕ Error converting result java.lang.NullPointerException: lock == null
    E/JSON Parser﹕ Error parsing data org.json.JSONException: End of input at character 0 of
    E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #1
    Process: com.devcolibri.androidandmysql, PID: 28551
    java.lang.RuntimeException: An error occured while executing doInBackground()

  45. Добрый день всем! Спасибо за подробные уроки авторам проекта.
    Начал пробовать делать этот урок и не могу подключить библиотеку к Android Studio из приложения. Когда выбираю ее из project structure в папке libs не отображается ни одного файла. Когда вручную ее прописал, она там появилась, но все равно при компиляции вылазит ошибка Error:(7, 29) error: package com.devcolibri.parser does not exist
    Помогите разобраться что к чему.

  46. Здравствуйте, Александр. Спасибо вам за столь хорошие уроки, благодаря вашим уроком написал курсовую на JAVA. И вот решил что диплом мой будет на Android, но возникла огромная проблема: не мог найти грамотных уроков взаимодействия Android и MySQL. В итоге наткнулся на эту статью, но по какой то причине некоторые библиотеки не импортируются, да и вообще некоторые куки кода не совсем понятны. Я хотел спросить будет ли видео переиздание этой статьи?

  47. Для тех, у кого не работает EditProductActivity:
    В этом классе, в методе onCreate, оберните вызов “new GetProductDetails().execute()” в новый поток – создаете new Thread,а execute() запихиваете в run(). Джава ругается, т.к. происходит работа с сетью в основном потоке, что может привести к замедлению выполнения всей программы.
    Еще, скорее всего, вам придется повозиться с классом сохранения в этой же активности. Там необходимо инициализировать ваши Edit поля. Думаю, вы справитесь, успехов! c:

  48. Error:(4, 23) java: package org.apache.http does not exist ( Не пойму что за пак нужно добавлять ?)

  49. Доброго времени суток
    Скачал ваш проект,поднял denwer не могу подключиться к базе
    private static String url_all_products = “http://127.0.0.1/test1/get_all_products.php”;
    подскажите как с виртуального девайса подключиться к базе.Все стоит на локалке

  50. Всем привет!
    Ошибка NetworkOnMainThreadException есть решение в активити ЕдитПродукт.
    Там на самом деле две ошибки, возможно на предыдущих версиях андроид, они не выходили, но сейчас на 6 версии ексепшены кидает.
    Остальные модули вроде в порядке, а в EditProductActivity: нужно парочку изменений сделать в class GetProductDetails:
    1 . убрать блок % runOnUiThread(new Runnable() { public void run() { %(не забудьте про закрывающие скобки.
    2. перенести инициализацию // продукт с pid найден
    // Edit Text
    txtName = (EditText) findViewById(R.id.inputName);
    txtPrice = (EditText) findViewById(R.id.inputPrice);
    txtDesc = (EditText) findViewById(R.id.inputDesc);
    в public void onCreate(.

    3. Перенести // покаываем данные о продукте в EditText
    txtName.setText(product.getString(TAG_NAME));
    txtPrice.setText(product.getString(TAG_PRICE));
    txtDesc.setText(product.getString(TAG_DESCRIPTION));
    Из protected String doInBackground(String[] args) в protected void onPostExecute(.

    После этих манипуляций все должно работать, я еще на всякий случай добавил в catch NetworkOnMainThreadException, в случае его срабатывания переходить обратно на Активити AllProductsActivity, но это не обязательно.

  51. Добавил Вашу либу в структуру проекта, пишу импорт, о идет ругань на com.devcolibri.parser.JSONParser; – подчеркивает красным . Где я туплю?

  52. Коллеги, в упор не вижу ссылку с библиотекой json.jar. Где ее взять?

    • Кнопка “скачать” в самом верху этой страницы, там в архиве этот класс лежит

      • Могу только с сожалением привести сообщение отладчика An error occured while executing doInBackground(). Как дальше отлаживаться? Если в браузере ввожу строку url_all_products, то получаю номальный ответ от сервера в формате json, а вот эмулятор андройда в студии пишет, что “к несчастью приложение закрылось”… что делать?

  53. ошибка
    Error:The processing instruction target matching “[xX][mM][lL]” is not allowed.
    Error:Exception while parsing the supplied manifest file C:\Users\ven\AndroidStudioProjects\AndroidAndMySQL\app\src\main\AndroidManifest.xml
    > The processing instruction target matching “[xX][mM][lL]” is not allowed.
    Помогите пожалуйста

  54. скачал файлы проекта по ссылке сверху страницы. первым делом начал ругаться на то, что в protected String doInBackground мы обращаемся к элементам UI из асинхронного потока:
    String name = inputName.getText().toString();
    String price = inputPrice.getText().toString();
    String description = inputDesc.getText().toString();
    выдаёт ошибку “Method getText must be called from the UI thread, currently inferred thread is worker less… (Ctrl+F1)
    This inspection looks at Android API calls that have been annotated with various support annotations (such as RequiresPermission or UiThread) and flags any calls that are not using the API correctly as specified by the annotations.”

    ну да это ладно. для текста просто присвоил переменным явные значения…

    и всё равно фигу. выдаёт следующее:

    !!! JUnit version 3.8 or later expected:

    java.lang.NoClassDefFoundError: junit/textui/TestRunner
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:264)
    at com.intellij.rt.execution.junit.JUnitStarter.getAgentClass(JUnitStarter.java:275)
    at com.intellij.rt.execution.junit.JUnitStarter.junitVersionChecks(JUnitStarter.java:231)
    at com.intellij.rt.execution.junit.JUnitStarter.canWorkWithJUnitVersion(JUnitStarter.java:216)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:75)
    Caused by: java.lang.ClassNotFoundException: junit.textui.TestRunner
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    … 18 more

    Process finished with exit code -3

  55. Интересно как будет если попробовать в вебсервере, точнее куда кидать php файлы? Как подключиться потом к этому серверу?

Добавить комментарий