반응형




데이터베이스에 데이터를 입력하고 JSON 형식으로 데이터를 가져오는 예제입니다. 

검색 결과를 가져올 수도 있습니다.



다음 세 개의 포스팅에 있는 코드를 하나의 앱에서 동작하도록 수정한 결과입니다.

나라만 검색하다록 query.php를 수정하였고  안드로이드 코드는 RecyclerView를 사용합니다.



최초 작성 - 2018.   6. 17

                   2018.   6. 27 -  ListVIew를 RecyclerView로 변경.

                   2019. 11.  17 - androidx 사용하도록 변경





1. 동작 설명


2. 전체 소스코드 및 사용방법


3. 관련 포스팅


4. 참고






1. 동작 설명


이름, 나라 항목에 데이터를 입력하고 입력 버튼을 터치하면 데이터베이스에 데이터가 저장됩니다. 


 




전체 버튼을 클릭하면 입력되어 있는 모든 데이터를 보여줍니다. 





검색할 나라를 입력하고 검색 버튼을 클릭하면 해당 데이터만 보여줍니다.


 




2. 전체 소스코드 및 사용방법

RecyclerView를 사용하려면  build.gradle에 다음 노란줄을 추가해야 합니다. 


dependencies {

    implementation fileTree(dir: 'libs', include: ['*.jar'])

    implementation 'androidx.appcompat:appcompat:1.0.2'

    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'

    implementation 'androidx.recyclerview:recyclerview:1.0.0'

    testImplementation 'junit:junit:4.12'

    androidTestImplementation 'androidx.test.ext:junit:1.1.0'

    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'

}



2-1. 데이터베이스 및 테이블 생성

MySQL에서 데이터베이스 및 테이블을 생성합니다.


create database testdb DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;

use testdb;

create table Person(
    id bigint(20) unsigned not null auto_increment,
    name varchar(255) not null,
    country varchar(255) not null,
    primary key (id)
) DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;



2-2. PHP 코드

php 파일은 우분투라면 /var/www/html 위치에, 윈도우에서 wamp를 사용한다면  C:\wamp\www 위치에 파일들을 생성합니다.


dbcon.php


<?php

    $host = 'localhost';
    $username = 'webnautes'; # MySQL 계정 아이디
    $password = 'apple9!'; # MySQL 계정 패스워드
    $dbname = 'testdb'# DATABASE 이름


    $options = array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8');
   
    try {

        $con = new PDO("mysql:host={$host};dbname={$dbname};charset=utf8",$username, $password);
    } catch(PDOException $e) {

        die("Failed to connect to the database: " . $e->getMessage());
    }


    $con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $con->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);

    if(function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) {
        function undo_magic_quotes_gpc(&$array) {
            foreach($array as &$value) {
                if(is_array($value)) {
                    undo_magic_quotes_gpc($value);
                }
                else {
                    $value = stripslashes($value);
                }
            }
        }

        undo_magic_quotes_gpc($_POST);
        undo_magic_quotes_gpc($_GET);
        undo_magic_quotes_gpc($_COOKIE);
    }

    header('Content-Type: text/html; charset=utf-8');
    #session_start();
?>


insert.php


안드로이드 앱에서 POST 방식으로 전송한 데이터를 받아서 데이터베이스의 테이블에 저장합니다.


<?php

    error_reporting(E_ALL);
    ini_set('display_errors',1);

    include('dbcon.php');


    $android = strpos($_SERVER['HTTP_USER_AGENT'], "Android");


    if( (($_SERVER['REQUEST_METHOD'] == 'POST') && isset($_POST['submit'])) || $android )
    {

        // 안드로이드 코드의 postParameters 변수에 적어준 이름을 가지고 값을 전달 받습니다.

        $name=$_POST['name'];
        $country=$_POST['country'];

        if(empty($name)){
            $errMSG = "이름을 입력하세요.";
        }
        else if(empty($country)){
            $errMSG = "나라를 입력하세요.";
        }

        if(!isset($errMSG)) // 이름과 나라 모두 입력이 되었다면
        {
            try{
                // SQL문을 실행하여 데이터를 MySQL 서버의 person 테이블에 저장합니다.
                $stmt = $con->prepare('INSERT INTO person(name, country) VALUES(:name, :country)');
                $stmt->bindParam(':name', $name);
                $stmt->bindParam(':country', $country);

                if($stmt->execute())
                {
                    $successMSG = "새로운 사용자를 추가했습니다.";
                }
                else
                {
                    $errMSG = "사용자 추가 에러";
                }

            } catch(PDOException $e) {
                die("Database error: " . $e->getMessage());
            }
        }

    }

?>


<?php
    if (isset($errMSG)) echo $errMSG;
    if (isset($successMSG)) echo $successMSG;

$android = strpos($_SERVER['HTTP_USER_AGENT'], "Android");
 
    if( !$android )
    {
?>
    <html>
      <body>

            <form action="<?php $_PHP_SELF ?>" method="POST">
                Name: <input type = "text" name = "name" />
                Country: <input type = "text" name = "country" />
                <input type = "submit" name = "submit" />
            </form>
     
      </body>
    </html>

<?php
    }
?>




getjson.php

데이터베이스의 테이블에 있는 모든 데이터를 안드로이드 앱으로 가져오기 위해서 사용됩니다. 


<?php

    error_reporting(E_ALL);
    ini_set('display_errors',1);

    include('dbcon.php');
       

    $stmt = $con->prepare('select * from person');
    $stmt->execute();

    if ($stmt->rowCount() > 0)
    {
        $data = array();

        while($row=$stmt->fetch(PDO::FETCH_ASSOC))
        {
            extract($row);
   
            array_push($data,
                array('id'=>$id,
                'name'=>$name,
                'country'=>$country
            ));
        }

        header('Content-Type: application/json; charset=utf8');
        $json = json_encode(array("webnautes"=>$data), JSON_PRETTY_PRINT+JSON_UNESCAPED_UNICODE);
        echo $json;
    }

?>



query.php

안드로이드 앱에서 입력한 나라 이름에 대응하는 레코드만 조회하여  안드로이드앱으로 리턴하기 위해서 사용됩니다.  


<?php 
error_reporting(E_ALL);
ini_set('display_errors',1);

include('dbcon.php');



//POST 값을 읽어온다.
$country=isset($_POST['country']) ? $_POST['country'] : '';
$android = strpos($_SERVER['HTTP_USER_AGENT'], "Android");


if ($country != "" ){

    $sql="select * from person where country='$country'";
    $stmt = $con->prepare($sql);
    $stmt->execute();

    if ($stmt->rowCount() == 0){

        echo "'";
        echo $country;
        echo "'은 찾을 수 없습니다.";
    }
else{

  $data = array();

        while($row=$stmt->fetch(PDO::FETCH_ASSOC)){

        extract($row);

            array_push($data,
                array('id'=>$row["id"],
                'name'=>$row["name"],
                'country'=>$row["country"]
            ));
        }


        if (!$android) {
            echo "<pre>";
            print_r($data);
            echo '</pre>';
        }else
        {
            header('Content-Type: application/json; charset=utf8');
            $json = json_encode(array("webnautes"=>$data), JSON_PRETTY_PRINT+JSON_UNESCAPED_UNICODE);
            echo $json;
        }
    }
}
else {
    echo "검색할 나라를 입력하세요 ";
}

?>



<?php

$android = strpos($_SERVER['HTTP_USER_AGENT'], "Android");

if (!$android){
?>

<html>
  <body>
 
      <form action="<?php $_PHP_SELF ?>" method="POST">
        나라 이름: <input type = "text" name = "country" />
        <input type = "submit" />
      </form>
 
  </body>
</html>
<?php
}

 
?>





2-3. 안드로이드 XML 코드

AndroidManifest.xml 

인터넷 사용 권한을 추가합니다.


android 9.0 이상에서 동작하게 하려면 usesCleartextTraffic 옵션도 추가해야 합니다. 해주지 않으면 “cleartext http traffic to not permitted” 라는 에러가 발생합니다.  



<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.tistory.webnautes.phptest">

    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:usesCleartextTraffic="true"
        android:allowBackup="true"



styles.xml 


다음 두 줄을 추가하여 타이틀 바를 보이지않게 합니다.


<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <!-- 타이틀바 제거 -->
       <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>

</resources>




activity_main.xml

디폴트 액티비티인 MainActivity의 사용자 인터페이스(UI)로 사용되는 레이아웃 파일입니다. 


<?xml version="1.0" encoding="utf-8"?>
<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"
    tools:context=".MainActivity"
    android:padding="10dp">


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="8.5"
        android:orientation="vertical">

    <TextView
        android:layout_marginBottom="5dp"
        android:text="이름과 나라를 입력 후 입력 버튼을 터치하세요."
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/textView_main_input" />

    <EditText
        android:layout_margin="5dp"
        android:hint = "이름을 입력하세요."
        android:inputType="text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/editText_main_name" />

    <EditText
        android:layout_margin="5dp"
        android:hint = "나라를 입력하세요."
        android:inputType="text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/editText_main_country" />

    <Button
        android:layout_margin="5dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="입력"
        android:id="@+id/button_main_insert" />

    <TextView
        android:layout_marginTop="20dp"
        android:layout_marginBottom="5dp"
        android:text="나라 이름을 입력 후 검색 버튼을 터치하세요."
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/textView_main_search" />

    <LinearLayout
        android:layout_margin="5dp"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:orientation="horizontal">

        <EditText
            android:layout_margin="2dp"
            android:hint = "검색할 나라를 입력하세요"
            android:inputType="text"
            android:id="@+id/editText_main_searchKeyword"
            android:layout_width="0dp"
            android:layout_weight="0.7"
            android:layout_height="wrap_content" />

        <Button
            android:layout_margin="2dp"
            android:id="@+id/button_main_search"
            android:layout_width="0dp"
            android:layout_weight="0.3"
            android:layout_height="wrap_content"
            android:text="검색" />

        <Button
            android:layout_margin="2dp"
            android:id="@+id/button_main_all"
            android:layout_width="0dp"
            android:layout_weight="0.3"
            android:layout_height="wrap_content"
            android:text="전체보기" />

    </LinearLayout>

    <androidx.recyclerview.widget.RecyclerView
        android:layout_margin="5dp"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="6"
        android:id="@+id/listView_main_list" />


    <!--- 디버깅 용 -->
    <TextView
        android:layout_marginTop="20dp"
        android:layout_marginBottom="5dp"
        android:text="디버깅 용"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/textView_main_debug" />

    <TextView
        android:layout_margin="5dp"
        android:id="@+id/textView_main_result"
        android:scrollbars = "vertical"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1.5" />
    </LinearLayout>


</LinearLayout>



데이터 입력,  데이터 조회, 디버깅용 정보 출력으로 구성됩니다. 




item_list.xml

layout 폴더에 추가합니다.

RecyclerView의 한 줄에 세 개의 컬럼을 만들기 위해 사용됩니다. 


<?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="horizontal"
    android:layout_margin="5dp"
    android:padding="5dp">

    <TextView
        android:id="@+id/textView_list_id"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:padding="5dp" />


    <TextView
        android:id="@+id/textView_list_name"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
                android:layout_margin="5dp"
        android:padding="5dp" />


    <TextView
        android:id="@+id/textView_list_address"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:padding="5dp" />

</LinearLayout>






2-4. 안드로이드 앱 자바코드

자바코드들은 똑같은 패키지 이름이 첫줄에 명시되어 있어야 합니다. 

포스팅에서는 다음과 같은 패키지 이름을 사용합니다.


package com.tistory.webnautes.phpexample;



PersonalData.java


package com.tistory.webnautes.phpexample;


public class PersonalData {
    private String member_id;
    private String member_name;
    private String member_address;

    public String getMember_id() {
        return member_id;
    }

    public String getMember_name() {
        return member_name;
    }

    public String getMember_address() {
        return member_address;
    }

    public void setMember_id(String member_id) {
        this.member_id = member_id;
    }

    public void setMember_name(String member_name) {
        this.member_name = member_name;
    }

    public void setMember_address(String member_address) {
        this.member_address = member_address;
    }
}




UsersAdapter.java

ArrayList에 있는 PersonalData 타입의 데이터를 RecyclerView에 보여주는 작업을 합니다. 


package com.tistory.webnautes.phpexample;


import android.app.Activity;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.ArrayList;


public class UsersAdapter extends RecyclerView.Adapter<UsersAdapter.CustomViewHolder> {

    private ArrayList<PersonalData> mList = null;
    private Activity context = null;


    public UsersAdapter(Activity context, ArrayList<PersonalData> list) {
        this.context = context;
        this.mList = list;
    }

    class CustomViewHolder extends RecyclerView.ViewHolder {
        protected TextView id;
        protected TextView name;
        protected TextView address;


        public CustomViewHolder(View view) {
            super(view);
            this.id = (TextView) view.findViewById(R.id.textView_list_id);
            this.name = (TextView) view.findViewById(R.id.textView_list_name);
            this.address = (TextView) view.findViewById(R.id.textView_list_address);
        }
    }


    @Override
    public CustomViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_list, null);
        CustomViewHolder viewHolder = new CustomViewHolder(view);

        return viewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull CustomViewHolder viewholder, int position) {

        viewholder.id.setText(mList.get(position).getMember_id());
        viewholder.name.setText(mList.get(position).getMember_name());
        viewholder.address.setText(mList.get(position).getMember_address());
    }

    @Override
    public int getItemCount() {
        return (null != mList ? mList.size() : 0);
    }

}




MainActivity.java


다음 줄에 있는 IP 주소를 MySQL 서버가 설치된  컴퓨터의 IP로 수정하세요.


    private static String IP_ADDRESS = "IP_ADDRESS";


package com.tistory.webnautes.phpexample;

import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;


import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;

import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;


public class MainActivity extends AppCompatActivity {

    private static String IP_ADDRESS = "IP_ADDRESS";
    private static String TAG = "phpexample";

    private EditText mEditTextName;
    private EditText mEditTextCountry;
    private TextView mTextViewResult;
    private ArrayList<PersonalData> mArrayList;
    private UsersAdapter mAdapter;
    private RecyclerView mRecyclerView;
    private EditText mEditTextSearchKeyword;
    private String mJsonString;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mEditTextName = (EditText)findViewById(R.id.editText_main_name);
        mEditTextCountry = (EditText)findViewById(R.id.editText_main_country);
        mTextViewResult = (TextView)findViewById(R.id.textView_main_result);
        mRecyclerView = (RecyclerView) findViewById(R.id.listView_main_list);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));

        mEditTextSearchKeyword = (EditText) findViewById(R.id.editText_main_searchKeyword);

        mTextViewResult.setMovementMethod(new ScrollingMovementMethod());



        mArrayList = new ArrayList<>();

        mAdapter = new UsersAdapter(this, mArrayList);
        mRecyclerView.setAdapter(mAdapter);


        Button buttonInsert = (Button)findViewById(R.id.button_main_insert);
        buttonInsert.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                String name = mEditTextName.getText().toString();
                String country = mEditTextCountry.getText().toString();

                InsertData task = new InsertData();
                task.execute("http://" + IP_ADDRESS + "/insert.php", name,country);


                mEditTextName.setText("");
                mEditTextCountry.setText("");

            }
        });


        Button button_search = (Button) findViewById(R.id.button_main_search);
        button_search.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {

                mArrayList.clear();
                mAdapter.notifyDataSetChanged();


                String Keyword =  mEditTextSearchKeyword.getText().toString();
                mEditTextSearchKeyword.setText("");

                GetData task = new GetData();
                task.execute( "http://" + IP_ADDRESS + "/query.php", Keyword);
            }
        });


        Button button_all = (Button) findViewById(R.id.button_main_all);
        button_all.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {

                mArrayList.clear();
                mAdapter.notifyDataSetChanged();

                GetData task = new GetData();
                task.execute( "http://" + IP_ADDRESS + "/getjson.php", "");
            }
        });

    }


    class InsertData extends AsyncTask<String, Void, String>{
        ProgressDialog progressDialog;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

            progressDialog = ProgressDialog.show(MainActivity.this,
                    "Please Wait", null, true, true);
        }


        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);

            progressDialog.dismiss();
            mTextViewResult.setText(result);
            Log.d(TAG, "POST response  - " + result);
        }


        @Override
        protected String doInBackground(String... params) {

            String name = (String)params[1];
            String country = (String)params[2];

            String serverURL = (String)params[0];
            String postParameters = "name=" + name + "&country=" + country;


            try {

                URL url = new URL(serverURL);
                HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();


                httpURLConnection.setReadTimeout(5000);
                httpURLConnection.setConnectTimeout(5000);
                httpURLConnection.setRequestMethod("POST");
                httpURLConnection.connect();


                OutputStream outputStream = httpURLConnection.getOutputStream();
                outputStream.write(postParameters.getBytes("UTF-8"));
                outputStream.flush();
                outputStream.close();


                int responseStatusCode = httpURLConnection.getResponseCode();
                Log.d(TAG, "POST response code - " + responseStatusCode);

                InputStream inputStream;
                if(responseStatusCode == HttpURLConnection.HTTP_OK) {
                    inputStream = httpURLConnection.getInputStream();
                }
                else{
                    inputStream = httpURLConnection.getErrorStream();
                }


                InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
                BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

                StringBuilder sb = new StringBuilder();
                String line = null;

                while((line = bufferedReader.readLine()) != null){
                    sb.append(line);
                }


                bufferedReader.close();


                return sb.toString();


            } catch (Exception e) {

                Log.d(TAG, "InsertData: Error ", e);

                return new String("Error: " + e.getMessage());
            }

        }
    }


    private class GetData extends AsyncTask<String, Void, String>{

        ProgressDialog progressDialog;
        String errorString = null;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

            progressDialog = ProgressDialog.show(MainActivity.this,
                    "Please Wait", null, true, true);
        }


        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);

            progressDialog.dismiss();
            mTextViewResult.setText(result);
            Log.d(TAG, "response - " + result);

            if (result == null){

                mTextViewResult.setText(errorString);
            }
            else {

                mJsonString = result;
                showResult();
            }
        }


        @Override
        protected String doInBackground(String... params) {

            String serverURL = params[0];
            String postParameters = "country=" + params[1];


            try {

                URL url = new URL(serverURL);
                HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();


                httpURLConnection.setReadTimeout(5000);
                httpURLConnection.setConnectTimeout(5000);
                httpURLConnection.setRequestMethod("POST");
                httpURLConnection.setDoInput(true);
                httpURLConnection.connect();


                OutputStream outputStream = httpURLConnection.getOutputStream();
                outputStream.write(postParameters.getBytes("UTF-8"));
                outputStream.flush();
                outputStream.close();


                int responseStatusCode = httpURLConnection.getResponseCode();
                Log.d(TAG, "response code - " + responseStatusCode);

                InputStream inputStream;
                if(responseStatusCode == HttpURLConnection.HTTP_OK) {
                    inputStream = httpURLConnection.getInputStream();
                }
                else{
                    inputStream = httpURLConnection.getErrorStream();
                }


                InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
                BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

                StringBuilder sb = new StringBuilder();
                String line;

                while((line = bufferedReader.readLine()) != null){
                    sb.append(line);
                }

                bufferedReader.close();

                return sb.toString().trim();


            } catch (Exception e) {

                Log.d(TAG, "InsertData: Error ", e);
                errorString = e.toString();

                return null;
            }

        }
    }


    private void showResult(){

        String TAG_JSON="webnautes";
        String TAG_ID = "id";
        String TAG_NAME = "name";
        String TAG_COUNTRY ="country";


        try {
            JSONObject jsonObject = new JSONObject(mJsonString);
            JSONArray jsonArray = jsonObject.getJSONArray(TAG_JSON);

            for(int i=0;i<jsonArray.length();i++){

                JSONObject item = jsonArray.getJSONObject(i);

                String id = item.getString(TAG_ID);
                String name = item.getString(TAG_NAME);
                String address = item.getString(TAG_COUNTRY);

                PersonalData personalData = new PersonalData();

                personalData.setMember_id(id);
                personalData.setMember_name(name);
                personalData.setMember_address(address);

                mArrayList.add(personalData);
                mAdapter.notifyDataSetChanged();
            }



        } catch (JSONException e) {

            Log.d(TAG, "showResult : ", e);
        }

    }

}



3. 관련 포스팅



Android PHP MySQL 예제 - 데이터베이스에 데이터 입력하기

http://webnautes.tistory.com/828 


Android PHP MySQL 예제 - 데이터베이스에서 데이터를 JSON 형식으로 가져오기

http://webnautes.tistory.com/829


Android PHP MySQL 예제 - 데이터베이스 질의(query) 결과 출력하기

https://webnautes.tistory.com/1159




4. 참고


[1] https://developer.android.com/guide/topics/ui/layout/recyclerview


[2] http://stacktips.com/tutorials/android/android-recyclerview-example




반응형

포스트 작성시에는 문제 없었지만 이후 문제가 생길 수 있습니다.
댓글로 알려주시면 빠른 시일내에 답변을 드리겠습니다.

여러분의 응원으로 좋은 컨텐츠가 만들어집니다.
지금 본 내용이 도움이 되었다면 유튜브 구독 부탁드립니다. 감사합니다 : )

유튜브 구독하기


제가 쓴 책도 한번 검토해보세요.

  1. 이전 댓글 더보기
  2. 1 2018.11.13 11:59

    Value of type java.lang.String cannot be converted to JSONObject 로
    디버깅에는 제이슨이 바르게 표기되는데

    listView_main_list에는 안나오는 현상
    어떻게 해결해야 할까요?
    쓰레기값이 들어가나....

    • 1 2018.11.13 12:12

      { "webnautes": [ { "id": "10", "name": "32", "country": "네몰" } ]}

      이렇게 나오는데...ㅜㅜ

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2018.11.13 12:31 신고

      이 부분에서 에러가 나는게 아닐까 싶네요.

      JSONObject jsonObject = new JSONObject(mJsonString);
                 JSONArray jsonArray = jsonObject.getJSONArray(TAG_JSON);

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2018.11.13 12:31 신고

      코드 수정한 부분이 있나요?

  3. Favicon of http://www.facebook.com/appsu123 BlogIcon Won 2018.11.26 22:57

    안녕하세요 코드를 보면서 공부하고 있는 대학생입니다.

    현재 이렇게 입력한 데이터값을 안드로이드 스튜디오에서 그래프화 시키고싶은데 어떻게 해야할지 하나도 감이 안잡힙니다..

    조언 부탁드립니다!!



    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2018.11.26 23:04 신고

      해보지는 않았지만 구글에서 검색해보니 몇가지 라이브러리가 있습니다.

      android graph library 로 찾아보세요.

    • W 2018.11.26 23:10

      혹시 그러면 데이터값이 앱 내에 변수로 저장이 되어있는건가요???

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2018.11.26 23:18 신고

      mArrayList에 저장됩니다.

    • 2018.11.27 03:46

      비밀댓글입니다

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2018.11.27 07:06 신고

      다음처럼 입력됩니다.


      PersonalData personalData = new PersonalData();

                     personalData.setMember_id(id);
                     personalData.setMember_name(name);
                     personalData.setMember_address(address);

                     mArrayList.add(personalData);
       

    • W 2018.11.27 09:31

      ArrayList<BarEntry> entries = new ArrayList<>();

      for (int i = 0; i<11; i++) {
      entries.add(mArrayList.get(i).getMember_time(), mArrayList.get(i).getMember_number());
      }

      이런식으로 작성하면 entries라는 배열에 mArrayList의 값이 저장되는것이 맞나요??

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2018.11.27 12:12 신고

      BarEntry 클래스를 어떻게 선언했나요?

    • w 2018.11.27 13:37

      BarChart barChart = (BarChart) findViewById(R.id.bargraph);

      ArrayList<String> entries = new ArrayList<String>();
      ArrayList<BarEntry> values = new ArrayList<BarEntry>();
      ArrayList<BarDataSet> dataSets = new ArrayList<BarDataSet>();
      BarDataSet set1;

      for (int i = 0; i<11; i++) {
      entries.add(mArrayList.get(i).getMember_time());
      values.add(mArrayList.get(i).getMember_number());
      }

      set1 = new BarDataSet(values, "Number");
      dataSets.add(set1);

      BarData data = new BarData(entries, values);

      data.setValueTextSize(10f);

      BarChart.setData(data);

      이렇게 했는데 현재

      BarData data = new BarData(entries, values); 에서 entries, values부분이 빨간줄뜨고,

      BarChart.setData(data); 부분에서 setData부분이 빨간줄이뜹니다

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2018.11.27 15:33 신고

      빨간줄이 보이는 부분에 마우스 커서를 가져가면 에러 원인이 보일듯합니다.

      또는 로그창에 보일듯합니다.

  4. sam 2018.12.05 00:41

    안녕하세요. 자세한 설명과 답글들을 참고하여 DB로부터 데이터 불러오기까지 되었습니다.
    이 점에서 감사인사드립니다.
    알려주신 코드중에서
    GetData task = new GetData();
    task.execute( "http://" + IP_ADDRESS + "/getjson.php", "");
    이 부분을 일정시간간격으로 반복하여 실행함으로써
    최종적으로 저장된(가장 최신의) 데이터를 불러오고 싶어서 아래와 같이 타이머기능을 사용하여 코드를 작성하여 실행하면
    오류메시지와 함께 앱이 종료됩니다. 아직은 코드참고하는 수준이라 조언부탁드립니다.
    mTimer = new Timer();
    TimerTask m_task = new TimerTask() {
    @Override
    public void run() {
    task.execute( "http://" + IP_ADDRESS + "/getjson.php", "");
    }
    };
    mTimer.schedule(m_task,5000,1000);

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2018.12.05 08:15 신고

      다음처럼 핸들러를 사용하도록 해서 onCreate 메소드 마지막 줄에 넣으면 됩니다.

      final Handler handler = new Handler();
      Runnable runnableCode = new Runnable() {
      @Override
      public void run() {
      mArrayList.clear();
      mAdapter.notifyDataSetChanged();

      GetData task = new GetData();
      task.execute( "http://" + IP_ADDRESS + "/getjson.php", "");

      handler.postDelayed(this, 5000);
      }
      };
      handler.post(runnableCode);

    • sam 2018.12.05 11:11

      알려주신 코드를 사용하니 2주넘게 오류만 보이던 화면이 정상동작되었습니다. 바쁘신데도 사소한 질문에 해결책을 알려주셔서 정말 감사드립니다.
      앞으로도 열심히 배우겠습니다^^

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2018.12.05 11:11 신고

      다행이네요 ^^

  5. 2019.04.09 18:44

    비밀댓글입니다

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.04.09 18:48 신고

      select로 일정수준 이상 값을 가진 레코드를 조회해서 발견하면 알림을 보여주면 될듯합니다 .

    • 2019.04.09 19:29

      비밀댓글입니다

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.04.09 20:04 신고

      그렇다면.. 데이터베이스에 넣기 전에 센서값을 검사하여 일정 수준 이상인지 체크하는 게 더 나을듯합니다.

    • 2019.04.09 20:20

      비밀댓글입니다

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.04.09 21:39 신고

      아두이노에서 특정값 이상이면 2 특정값 이하이면 1을 보내주면 될듯합니다.

      안드로이드에서는 컬럼값만 읽어서 1인지 2인지 판단하여 알람을 띄우면 됩니다.

    • Favicon of https://dodoitdo.tistory.com BlogIcon hanirym 2019.04.09 23:11 신고

      이렇게 빠르고 친절하게 피드백 해주셔서 감사합니다. 문뜩 든 생각인데 PersonalData에서 String으로 선언된 멤버를(예를들어 member_name) int형으로 바꾸면 값을 정수로 받아올 수 있지 않을까 했는데 그렇게 되면 많은 것들을 수정해야 하는건가요?

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.04.09 23:22 신고

      숫자를 문자열로 받은후 자바에서 다시 숫자로 바꾸어야 합니다.

    • 2019.04.09 23:49

      비밀댓글입니다

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.04.09 23:56 신고

      다음처럼해야 스트링으로 가져온걸 int로 변환해야 합니다

      arraylist.get(0).toString()

    • Favicon of https://dodoitdo.tistory.com BlogIcon hanirym 2019.04.10 00:31 신고

      int result = Integer.parseInt(mArrayList.get(1).toString());
      해당 코드를 1초마다 리스트를 갱신하는 핸들러 안에있는 run 안에 넣기만 해도 앱이 중지됩니다..... 선언을 잘못한걸까요?

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.04.10 07:43 신고

      로그캣에서 에러 메시지를 찾아보세요.

    • 2019.04.10 11:51

      비밀댓글입니다

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.04.10 12:11 신고

      에러 발생한것과 관련 없는 메시지 같습니다..

  6. 2019.05.02 10:18

    비밀댓글입니다

  7. pola 2019.05.02 13:00

    앞에 테이블생성할때 address가 아닌 country로 바꿔서 생성해야 작동하더라구요 혹시나 실행안되시는분들은 이 부분 주의해서 보시면될거같습니다.
    그리고 여쭤볼것이 있습니다만
    위의 테이블을 이용해서 다른테이블의 내용을 불러올수 있을까요?
    몇가지 재료를 입력하면 만들수있는 요리가 나오도록하는 어플을 만들어보고 있는데
    제가 소스를 어떻게 짜야하는지 잘모르겠습니다 pk,fk를 사용하는건알고있습니다만 구체적으로 어떻게해야하는지 피드백 받고싶습니다

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.05.02 13:24 신고

      미쳐 안바뀐 부분이 있었군요.. 알려주셔서 감사합니다.. 수정해두었습니다.

      물어보신 점은

      여러 테이블을 JOIN을 해서 여러 테이블의 레코드를 하나로 묶어서 가져오면 됩니다.

      sql join으로 검색하면 관련 내용을 찾으실 수 있습니다.

    • pola 2019.05.02 13:41

      피드백 감사드립니다 이 글이 정말 도움이 많이되었습니다 골머리를 앓고있던부분이였는데 시원하게 해결되었습니다 감사드립니다

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.05.02 13:55 신고

      감사합니다 : )

    • 2019.05.02 14:12

      비밀댓글입니다

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.05.02 15:02 신고

      머신러닝 또는 딥러닝으로 풀어야할 문제처럼 보이네요..

      요리별로 재료를 데이터베이스에 입력하고 sql 질의해서 중복된 재료가 많은 요리를 보여주면 어떨까 싶습니다.
      테이블 구조에 대한 고민이 필요할듯하군요..

    • pola 2019.05.02 15:20

      저도 같은 생각이고 앞으로 그부분을 중점적으로 해결하려고합니다. 그런데 중간에 코드에서 protected String doInBackground(String... params)부분이 두번이나 있는데 두번이나 쓰는 이유와 그 차이점이 무엇인지 알수있을까요?

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.05.02 15:48 신고

      기존에 따로 작성되었던 두 개의 포스트에서 사용한 코드를 하나로 합치면서..
      중복된 부분을 하나로 합치지 않고 그냥 사용했기 때문입니다.

      중복된 부분을 합칠 수 있다면 하나로 해도 될듯합니다.

    • pola 2019.05.02 19:54

      친절한 답변 감사드립니다.

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.05.03 00:07 신고

      감사합니다 : )

  8. 안녕하세요 2019.05.21 16:39

    안녕하세요.. build.gradle에 implementation 'com.android.support:recyclerview-v7:28.0.0'를 넣고 useradapter에 import android.support.v7.widget.RecyclerView;를 넣으려고 했는데 v7 widget에 RecyclerView가 없네요ㅜㅜ 해결방법은 없을까요?

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.05.24 13:25 신고

      RecyclerView 사용하는 코드에서 Alt + enter를 입력하면 자동으로 입력됩니다.

  9. ggg 2019.05.24 12:13

    안녕하세요 데이터를 넣지않고 데이터베이스에 있는 정보만 검색해서 확인하려고 하는데 디버깅용에는 정보가 뜨는데 리스트뷰에는 아무것도 안떠요ㅠㅠ 오류같은것도 없는데 왜 이럴까요..

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.05.24 13:26 신고

      showResult에서 데이터가 확인되는지 보세요.

    • ggg 2019.05.24 13:44

      private void showResult(){

      String TAG_JSON="root";
      String TAG_ID = "id";
      String TAG_NAME = "name";
      String TAG_JUSO ="juso";

      try {
      JSONObject jsonObject = new JSONObject(mJsonString);
      JSONArray jsonArray = jsonObject.getJSONArray(TAG_JSON);

      for (int i = 0; i < jsonArray.length(); i++) {

      JSONObject item = jsonArray.getJSONObject(i);

      String id = item.getString(TAG_ID);
      String name = item.getString(TAG_NAME);
      String address = item.getString(TAG_JUSO);

      PersonalData personalData = new PersonalData();

      personalData.setMember_id(id);
      personalData.setMember_name(name);
      personalData.setMember_address(address);

      mArrayList.add(personalData);
      mAdapter.notifyDataSetChanged();
      }
      }catch (JSONException e) {

      Log.d(TAG, "showResult : ", e);
      }

      }
      showResult코드가 이렇게 되는데 빠진거라도 있나요?

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.05.24 13:47 신고

      값이 넘어오는지 테스트해서 뭐가 문제인지 찾아야 할듯합니다. 코드만 봐서는 오류를 놓칠 확률이 높습니다.

  10. 2019.05.28 14:38

    비밀댓글입니다

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.05.28 15:21 신고

      가능할듯합니다

    • 코딩이 2019.05.28 15:45

      넵 감사합니다^^ 다른 포스팅보며 공부하다가 어려운부분 여쭤보겠습니다.

  11. 우유비 2019.06.26 12:12

    안녕하세요. 포스팅에 큰 도움 받았습니다.

    문의드릴게 있습니다.
    dbcon.php 파일을 android app 단에 위치 시켜도 동작이 되나요??

  12. midnight 2019.08.24 01:48

    로그캣에 E/RecyclerView: No layout manager attached; skipping layout 라고 뜹니다.
    Adapter에서 context에 접근이 안되서 문제가 발생하는 거라고 보고 있습니다.
    그런데 제가 초보다 보니 context를 어떻게 접근 해야 할지 모르겠습니다.
    이전에 올려주신 버튼 눌러서 데이터를 추가하던 글을 성공적으로 실행해 보고 이 코드로 수정을 해본건데 잘 뜨던 recyclerview가 왜 안뜨는지 모르겠습니다ㅠ 팁을 조금만 주시면 그쪽으로 더 공부해보겠습니다ㅠ

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.08.24 08:41 신고

      아래 코드가 추가되어 있나요?

      mRecyclerView.setLayoutManager(new LinearLayoutManager(this));

    • midnight 2019.08.24 10:19

      코드 정말 여러번 확인했는데 왜 못 봤을까요(당황) 감사합니다ㅎㅎ
      알려주신대로 해서 로그캣은 오류없이 처리가 되는데, recyclerview에 데이터가 안뜹니다.
      context문제가 아닌가요??ㅠㅠ

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.08.24 10:26 신고

      context는 안사용하는게 맞습니다.
      context 대신에 다음처럼 처리했었네요.
      viewGroup.getContext()

      포스트의 코드설명이라는 부분을 참고하여 따라가며 로그캣으로 문제없는지 출력해봐야 할듯합니다.

    • midnight 2019.08.27 18:06

      자꾸 질문드려서 죄송합니다ㅠ 계속 같은 문제에 막힙니다ㅠㅠ
      로그캣을 다시 봤는데 org.json.JSONException: Value  of type java.lang.String cannot be converted to JSONObject 라고 뜹니다.
      JSONObject jsonObject = new JSONObject(mJsonString); JSONArray jsonArray = jsonObject.getJSONArray(TAG_JSON);
      코드도 맞게 넣었는데 왜 그럴까요

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.08.27 18:24 신고

      mJsonString에 공백이 포함된건 아닌지 확인해보세요.

    • midnight 2019.08.27 20:40

      공백도 없는데, 혹시 다른 이유는 없을까요??

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.08.27 20:56 신고

      mJsonString에 저장되어 있는 문자열이 JSON 프로토콜에 맞지 않아서 발생한 에러로 보입니다.

      로그캣으로 출력된 mJsonString이 어떻게 보이나요?

    • 2019.08.29 14:04

      비밀댓글입니다

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.08.29 14:12 신고

      에러나는게 아래 내용 땜이 아닐까 싶습니다.

      다음 부분을 새로 정의하신 JSON에 맞추어 변경해야 합니다.

      String TAG_JSON="webnautes";
      String TAG_ID = "id";
      String TAG_NAME = "name";
      String TAG_COUNTRY ="country";


    • midnight 2019.09.16 15:13

      말씀해 주신대로 해도 해결이 잘 안나서 계속 여쭤보기도 죄송해서 혼자 해결 해보다 보니 감사 댓글이 늦었습니다!!^^
      JSONObject jsonObject = new JSONObject(mJsonString.substring(mJsonString.indexOf("{"),mJsonString.lastIndexOf("}") +1));
      이렇게 한줄을 바꾸니까 해결이 되었습니다!
      선생님 블로그 보면서 진짜 많이 배웠습니다^^ 에러 관련해서 도움도 많이 주셔서 정말정말 너무 감사합니다^^

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.09.16 15:15 신고

      해결해서 다행입니다^^ 감사합니다

  13. 차도미 2019.09.03 14:12

    나라를 검색하는 부분에서 전체보기는 문제 없이 읽히는데,
    검색버튼을 누르면 아무것도 뜨지 않습니다.
    디버깅용 문자에는 검색할 나라를 입력하라고만 뜨는데, 어떠한 값을 입력해도
    위와 같은 문자만 출력이됩니다.

    혹시나해서 주소로 쳐서 들어가서 확인할때는 정상동작하는데,
    앱으로 실행했을 경우 위와같은 문제가 생기네요..

    EditText 부분을 못 읽는것 같은데 혹시 원인을 알 수 있을까요!?ㅎㅎ

    감사합니다...

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.09.03 14:27 신고

      다음 코드에서 Keyword가 출력되나 로그캣으로 확인해보세요.

      String Keyword = mEditTextSearchKeyword.getText().toString();
      mEditTextSearchKeyword.setText("");

      GetData task = new GetData();
      task.execute( "http://" + IP_ADDRESS + "/query.php", Keyword);

    • 차도미 2019.09.03 15:24

      mTextViewResult.setText(Keyword);
      Log.d(TAG, " Keyword - " + Keyword);

      밑에 추가해서 확인해봤는데, 로그켓에서는 값을 확인할 수 있었습니다...
      다른 문제가 있을까요..?

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.09.03 15:29 신고

      task.excute 아규먼트로 주어지는 URL을 로그캣으로 출력해서 웹브라우저에서 접속하는데 문제 없나 확인해보세요

    • 차도미 2019.09.03 15:57

      아 죄송합니다..
      doInBackground 이 부분에서
      String serverURL = params[0];
      String postParameters = "Country=" + params[1];

      이 부분이 잘못 되어있었네요..
      오타라니...
      귀한 시간 답변 해주셔서 감사합니다.

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.09.03 15:59 신고

      원인을 찾아서 다행입니다 : )

  14. 빨간머리차차 2019.12.14 17:22

    그 혹시 이미지도 저장 및 업로드 하는 방법을 해주실 생각은 없나요?

  15. ㅎㄹ 2020.04.20 12:31

    안녕하세요. 혹시 검색할 때 일정 단어를 포함한 단어들 모두 불러오는 방법은 없을까요?
    선생님 예제 같은 경우에 '이탈' 만 검색해도 이탈리아가 뜨는 경우로요,,!

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2020.04.20 12:34 신고

      sql에서 일부 문자열로 검색하는 방법을 찾아보시면 될거 같습니다. sql문만 수정하면 됩니다.

    • ㅎㄹ 2020.04.20 12:52

      선생님 예제 같은 경우에는
      SELECT name, country FROM person WHERE country LIKE '%이탈%'
      이렇게 수정하는 거 맞나요?

      이렇게 하면 테이블에서만 수정이 되고 안드로이드에서는 안되는거 같은데 단말기에서 특정 포함 검색 후 단어 불러오는 법은 없나요?
      아니면 제가 선생님의 말씀을 잘못 짚고 있는 걸까요ㅠㅠ

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2020.04.20 19:54 신고

      맞게 접근하신거 같습니다. mysql에선 질의 결과가 있는데 안드로이드와ㅜ연동하면 결과가 없나요?

  16. opppp 2020.05.07 16:59

    전체보기를 눌렀을때 아무것도 안나와요 ..

  17. 아이템클릭시 2020.05.15 19:27

    안녕하세요
    리사이클러뷰 아이템 클릭시 그 데이터값을 액티비티로 넘기는 방법좀알려주세요 ㅜ. 눌렀을때 액티비티로 넘어가는거까진했는데 데이터값을 어떻게 가지고오는지 모르겠어요
    예를들어 첫번째항목 제목 -- 내용 -- 작성자가 있을때 이걸 클릭하면 상세페이지로 넘어가면서 제목 내용 작성자 그대로 불러오고싶어요

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2020.05.16 02:49 신고

      리싸이클러뷰의 아이템 길게 누르면 해당 아이템 가져오는 건 아래 포스트를 참고하세요.

      https://webnautes.tistory.com/1222


      액티비티간 데이터 넘겨주는건 아래 포스트를 참고하세요

      https://webnautes.tistory.com/1012

  18. 초보계발 2020.05.26 11:52

    Deprecated: Function get_magic_quotes_gpc() is deprecated in C:\xampp\htdocs\dbcon.php on line 23

    이게 매번뜨는데 혹시 없애는 방법 있나요

    그리고 혹시 저 메세지도 앱으로 같이 들어오고
    Function get_magic_quotes_gpc() is deprecated in <b>C:\xampp\htdocs\dbconf.php</b> on line <b>23</b><br />{ "root": [ { "id": "5", "name": "Roony", "country": "USA" } ]}
    이런식으로 출력 됩니다..
    이것때문에 리사이클러뷰에 출력이 안되는것일까요?

    org.json.JSONException: Value <br of type java.lang.String cannot be converted to JSONObject
    이 에러가 발생하네요ㅎ 그래서 catch로 빠진게 아닐까 싶습니다.ㅠㅠ

    • 초보계발 2020.05.26 13:58

      PHP를 몰라서 ㅎㅎ..
      get_magic_quotes_gpc()
      이 함수가 이제 사용 안하는 함수인가봐요
      그래서 처음에
      if(function_exists('get_magic_quotes_gpc') && true) 로 했다가 사용안하는 함수인거 같아서 if문을 없애버렸습니다.
      그랬더니 이제 웹(?)에서도
      Deprecated: Function get_magic_quotes_gpc() is deprecated in C:\xampp\htdocs\dbcon.php on line 23
      문구가 없어졌습니다.
      물론 동작도 잘되구요(앱, php -> DB)
      ㅎㅎ PHP를 몰라서 함수를 제거해도 문제가 없는지는 모르겠지만 작동합니다.
      좋은예제 감사합니다.ㅎㅎ

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2020.05.26 20:05 신고

      PHP 최신 버전에서 get_magic_quotes_gpc() 함수가 deprecated되었나 봅니다. 언젠가 나오는 버전에서는 이 함수가 제거될거라는 의미입니다.

      해결되었다니 다행이네요.. 감사합니다.

  19. Neoc 2020.07.01 11:27

    안녕하세요.
    포스팅 보고 안드로이드와 php연결해서 FAQ를 하나 만들어봤는데요.
    상단에 회원/구매/기타 이런식으로 메뉴를 두고 클릭시
    mArrayList.clear();
    mAdapter.notifyDataSetChanged();

    GetData task = new GetData();
    task.execute( "http://" + IP_ADDRESS + "/getjson.php", "");
    포스팅처럼 구현했습니다.
    단 FAQ라서 질문만 보이고 답변은 클릭시 Adapter에서 setVisibility를 변경해서 보이게 해줬는데요.
    회원부분에서 첫번째를 클릭해서 답변을 보이게 변경하고, 구매탭을 눌러서 위의 4줄로 구매탭 내용이 보이는데
    구매탭의 첫번째 질문에 답변이 보인상태로 표시됩니다.
    여기저기 다 검색해봐도 마땅한 해결책을 못찾아서 어떻게 해야되는지 해결방법에 대한 자문을 좀 구할수 있을까요?
    https://dev-imaec.tistory.com/30 제목 클릭시 답변이 보이게 하는건 저 블로그를 참고해서 구현하였습니다.

  20. Favicon of https://rrojin.tistory.com BlogIcon rrojin 2020.07.10 20:44 신고

    좋은 글 감사합니다! 디비 전체 조회 결과를 다른 화면에 띄울려면 어떻게 해야하나요?
    버튼 onClick()에 아래와 같이 적은 후에,,
    Intent intent = new Intent(getApplicationContext(), MySqlActivity.class);
    startActivity(intent);

  21. hhhhhh 2020.10.21 23:20

    안녕하세요 덕분에 너무 도움이 많이 되었습니다. 친절하게 알려주신 덕분에 sql저장, 검색, 출력은 잘 이해하였는데 제가 지식이 부족해서 응용하는 법이 부족한것 같습니다. 혹시 수정이나 삭제는 어떤 방식으로 해야할지 알수 있을까요 바쁘실텐데 부탁드려요ㅠㅠ

+ Recent posts