티스토리 뷰

 

위 영상에 있는 앱 코드를 기록하려고 합니다.
나중에 필요할 때 보려는 용도로 기록하는 느낌이 강해서 설명은 거의 없고 코드가 대부분을 차지합니다.
궁금한 부분은 댓글로 적어두시면 금방 답합니다.
만들기 위해서는 서버가 필요한데 저는 다른 서버를 사용했지만 없으신 분은 연습용 정도는 무료로 쓸 수 있는 닷홈을 추천합니다.
안드로이드는 db와 연동하려면 웹을 거쳐야 합니다.
필자는 서버에 접속하는 프로그램으로 파일질라를 이용했으니 처음 해보시는 분들은 파일 질라를 쓰시면 됩니다.

우선 사용하는 java와 xml 파일입니다.

xml은 총 3개를 사용하였고 java은 총 6개를 사용했습니다.
우선 인터넷 접속을 위해 AndroidManifest.xml부터 수정합니다.


AndroidManifest.xml

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

    <uses-permission android:name="android.permission.INTERNET" />
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Osc"
        android:usesCleartextTraffic="true">
        <activity
            android:name=".Main"
            android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".Item"
            android:screenOrientation="portrait" />
    </application>
</manifest>

인터넷 접속을 위해

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

를 추가하고 http에 접속을 하려면 추가로

android:usesCleartextTraffic="true"

를 추가해 줍니다.


main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Main">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:orientation="vertical"
        app:layout_constraintBottom_toTopOf="@+id/main_edit"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
            android:id="@+id/main_swipe"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/main_recycler"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />
        </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
    </LinearLayout>

    <EditText
        android:id="@+id/main_edit"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:textSize="20dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/main_but"
        app:layout_constraintStart_toStartOf="parent" />

    <Button
        android:id="@+id/main_but"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="입력"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

앱을 처음 키면 나오는 화면입니다.
리스트를 보여줄 리사이클러뷰와 내용을 적을 에딧 텍스트, 입력을 위한 버튼이 있습니다.


list.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:focusable="true"
    android:foreground="?android:attr/selectableItemBackground">

    <TextView
        android:id="@+id/list_text_number"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:hint="번호"
        android:textColor="@color/black"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/list_text_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:hint="내용"
        android:padding="20dp"
        android:textColor="@color/black"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

Mian.xml에 리스트로 나타날 뷰입니다.
db에서 받아올 번호와 내용이 들어갈 텍스트뷰들이 있습니다.


item.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintBottom_toTopOf="@+id/item_edit"
        app:layout_constraintTop_toTopOf="parent">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <TextView
                android:id="@+id/item_text_number"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:hint="번호"
                android:textColor="@color/black" />

            <TextView
                android:id="@+id/item_text_content"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:hint="내용"
                android:textColor="@color/black" />
        </LinearLayout>
    </ScrollView>

    <Button
        android:id="@+id/item_but_delete"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="삭제"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

    <EditText
        android:id="@+id/item_edit"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:textSize="20dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/item_but_update"
        app:layout_constraintStart_toEndOf="@+id/item_but_delete" />

    <Button
        android:id="@+id/item_but_update"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="수정"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

리스트에 있는 항목을 누르면 나타나는 뷰입니다.
글이 길면 스크롤이 되도록 스크롤 뷰를 사용했고 번호와 내용이 뜰 텍스트뷰와 수정할 내용을 적는 에딧 텍스트와 내용을 수정할 때 쓸 버튼과 삭제할 때 쓸 버튼이 있습니다.


Main.java

package com.ehsehsl.osc;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import java.util.ArrayList;

public class Main extends AppCompatActivity implements SwipeRefreshLayout.OnRefreshListener {   // 스와이프 임폴트하기
    EditText edit;  // 글자 적는 에딧텍스트
    Button but; // 확인 버튼
    SwipeRefreshLayout swipe; // 스와이프
    Boolean sw = false; // 스레드 중인지 체크하기 용도 (스레드 중인데 다시 실행되는 거 방지)
    ListAdapter adapter;  // 어댑터
    RecyclerView recycler;  // 리사이클러뷰

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

        swipe = findViewById(R.id.main_swipe);   // 스와이프
        swipe.setOnRefreshListener(this);

        edit = findViewById(R.id.main_edit);    // 에딧텍스트 받아오기
        but = findViewById(R.id.main_but); // 버튼 뷰 받아오기

        but.setOnClickListener(new View.OnClickListener() { // 버튼 클릭 설정
            @Override
            public void onClick(View v) {
                Thread_insert thread = new Thread_insert(); // 인설트 스레드 생성
                thread.start(); // 스레드 시작
            }
        });

        recycler = findViewById(R.id.main_recycler);   // 리사이클러뷰 받아오기
        LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
        recycler.setLayoutManager(layoutManager);

        adapter = new ListAdapter();
        recycler.setAdapter(adapter);   // UI 변경

        adapter.setOnItemClickListener(new ListAdapterClickListener() { // 어댑터 클릭 설정
            @Override
            public void onItemClick(ListAdapter.ViewHolder holder, View view, int position) {
                Info item = adapter.getItem(position);

                Intent intent = new Intent(getBaseContext(), Item.class);
                intent.putExtra("number", item.getNumber());    // 인텐트에 변수 저장
                intent.putExtra("content", item.getContent());  // 인텐트에 변수 저장
                startActivity(intent); // 뷰 열기
            }
        });
    }

    @Override
    protected void onResume() { // 화면 재개될 때 리스트 최신화 하도록(처음 시작할떄도 onCreate가 끝나고 실행됨)
        super.onResume();
        select();   // 리스트 받아오는 셀렉트 함수 실행
    }

    private void select() {  // 리스트 받아오는 셀렉트 함수
        Thread_select thread = new Thread_select();
        thread.start();
    }

    class Thread_select extends Thread {    // 리스트 받아오는 스레드
        public void run() {
            if (sw == false) {  // 스레드가 아닐때만 실행하게
                sw = true;  // 스레드 중이므로 트루로
                ArrayList<Info> result = Web.select();  // db에서 정보 받아오기
                adapter.setItems(result);   // 어댑터에 받아온 정보 저장

                runOnUiThread(new Runnable() {  // 스레드에서 Ui 수정하려면 추가
                    @Override
                    public void run() {
                        adapter.notifyDataSetChanged(); // 어댑터 최신화
                        swipe.setRefreshing(false); // 스와이프 이미지 제거
                    }
                });
                sw = false; // 스레드 끝나면 펄스로
            }
        }
    }


    class Thread_insert extends Thread {    // 버튼 누르면 실행하는 인설트
        public void run() {
            if (sw == false) {  // 스레드가 아닐때만 실행하게
                sw = true;  // 스레드 중이므로 트루로
                if (edit.getText().toString().length() > 0) {   // 글자를 입력했는지 체크
                    String text = Web.insert(edit.getText().toString());
                    runOnUiThread(new Runnable() {  // 스레드에서 Ui 수정하려면 추가
                        @Override
                        public void run() {
                            Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show();   // 토스트 메시지
                            if (text.equals("성공")) {
                                edit.setText("");   // 성공했으면 에딧텍스트 지우기
                                select();   // 입력했으니 리스트 최신화
                            }
                        }
                    });
                } else {    // 입력한 글자가 없을 때 실행
                    runOnUiThread(new Runnable() {  // 스레드에서 Ui 수정하려면 추가
                        @Override
                        public void run() {
                            Toast.makeText(getApplicationContext(), "입력한 글자가 없음", Toast.LENGTH_SHORT).show();   // 토스트 메시지
                        }
                    });
                }
                sw = false; // 스레드 끝나면 펄스로
            }
        }
    }

    @Override
    public void onRefresh() {   // 리사이클러뷰 아래로 당기면 스와이프 시작
        swipe.setRefreshing(true);  // 스와이프 이미지 시작
        select();   // 리스트 받아오는 셀렉트 함수 실행
    }
}

스와이프와 리사이클러뷰와 어댑터 그리고 db에 insert와 select 하는 코드 등이 있습니다.


ListAdapter.java

package com.ehsehsl.osc;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;

public class ListAdapter extends RecyclerView.Adapter<ListAdapter.ViewHolder> implements ListAdapterClickListener {
    ArrayList<Info> items = new ArrayList<Info>();
    ListAdapterClickListener listener;
    Context context;    // 다이얼로그를 위해 받아오기
    Handler handler = new Handler();

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(viewGroup.getContext());
        View itemView = inflater.inflate(R.layout.list, viewGroup, false);

        this.context = viewGroup.getContext();  // 다이얼로그를 위해 받아오기

        return new ViewHolder(itemView, this);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder viewHolder, int position) {
        Info item = items.get(position);
        viewHolder.setItem(item);
    }

    @Override
    public int getItemCount() {
        return items.size();
    }

    public void addItem(Info item) {
        items.add(item);
    }

    public void setItems(ArrayList<Info> items) {
        this.items = items;
    }

    public Info getItem(int position) {
        return items.get(position);
    }

    public void setItem(int position, Info item) {
        items.set(position, item);
    }

    public void setOnItemClickListener(ListAdapterClickListener listener) {
        this.listener = listener;
    }

    @Override
    public void onItemClick(ViewHolder holder, View view, int position) {
        if (listener != null) {
            listener.onItemClick(holder, view, position);
        }
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        TextView number, content;   // list.xml 에 있는 텍스트 뷰 2개 선언

        public ViewHolder(View itemView, final ListAdapterClickListener listener) {
            super(itemView);

            number = itemView.findViewById(R.id.list_text_number);
            content = itemView.findViewById(R.id.list_text_content);

            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    int position = getAdapterPosition();

                    if (listener != null) {
                        listener.onItemClick(ViewHolder.this, view, position);
                    }
                }
            });

            itemView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View view) {
                    delete(number.getText().toString(), getAdapterPosition());  // 삭제 함수 실행
                    return false;
                }
            });
        }

        public void setItem(Info item) {    // 가져온 값 설정
            number.setText(item.getNumber());
            content.setText(item.getContent());
        }
    }

    private void delete(String number, int position) {  // 다이얼로그 호출과 삭제하는 코드
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setMessage("삭제할까요?");
        builder.setCancelable(false);   // 다이얼로그 화면 밖 터치 방지

        builder.setPositiveButton("삭제", new androidx.appcompat.app.AlertDialog.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                new Thread(new Runnable() { // 스레드 생성
                    @Override
                    public void run() { // 스레드 런
                        String text = Web.delete(number);

                        handler.post(new Runnable() {
                            @Override
                            public void run() {
                                if (text.equals("삭제")) {    // db에서 삭제가 됐으면 리스트에서도 지우기
                                    items.remove(position);
                                    notifyItemRemoved(position);
                                    notifyItemRangeChanged(position, items.size());
                                }
                                Toast.makeText(context, text, Toast.LENGTH_SHORT).show();   // 토스트 메시지
                            }
                        });
                    }
                }).start();
            }
        });
        builder.setNegativeButton("취소", new androidx.appcompat.app.AlertDialog.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
            }
        });
        builder.show();
    }
}

리사이클러뷰를 사용하려면 어댑터가 필요합니다.
외 다이얼로그와 삭제하는 기능이 있습니다.


ListAdapterClickListener.java

package com.ehsehsl.osc;

import android.view.View;

public interface ListAdapterClickListener {
    public void onItemClick(ListAdapter.ViewHolder holder, View view, int position);
}

리사이클러뷰 클릭이 가능하도록 만들어줍니다.


Info.java

package com.ehsehsl.osc;

public class Info {
    String number;    // 글번호
    String content;    // 내용

    public Info(String number, String content) {
        this.number = number;
        this.content = content;
    }

    public String getNumber() {
        return number;
    }

    public String getContent() {
        return content;
    }
}

db에서 select할 때 ArrayList 형식으로 받아오기 위해 만들어줍니다.
만들 때 변수만 설정하고 Alt+insert를 누르면 목록이 나오는데 Constructor와 Getter를 추가하면 됩니다.


Item.java

package com.ehsehsl.osc;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

public class Item extends AppCompatActivity {
    String number, content;
    TextView text_number, text_content;
    Button but_update, but_delete;
    EditText edit;
    Boolean sw = false; // 스레드 중인지 체크하기 용도 (스레드 중인데 다시 실행되는 거 방지)


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

        Intent intent = getIntent();    // 인텐트 받아오기 위해서 선언
        number = intent.getStringExtra("number");   // 넘버 받아오기
        content = intent.getStringExtra("content"); // 내용 받아오기

        text_number = findViewById(R.id.item_text_number);  // 글번호
        text_content = findViewById(R.id.item_text_content);    // 내용
        but_update = findViewById(R.id.item_but_update);    // 수정 버튼
        but_delete = findViewById(R.id.item_but_delete);    // 삭제 버튼
        edit = findViewById(R.id.item_edit);    // 입력 에딧 텍스트

        text_number.setText(number);
        text_content.setText(content);

        but_update.setOnClickListener(new View.OnClickListener() { // 업데이트 버튼 클릭 설정
            @Override
            public void onClick(View v) {
                Thread_update thread = new Thread_update(); // 스레드 생성
                thread.start(); // 스레드 시작
            }
        });
        but_delete.setOnClickListener(new View.OnClickListener() { // 딜리트 버튼 클릭 설정
            @Override
            public void onClick(View v) {
                Thread_delete thread = new Thread_delete(); // 스레드 생성
                thread.start(); // 스레드 시작
            }
        });
    }

    class Thread_update extends Thread {    // 수정 버튼 누르면 실행하는 업데이트
        public void run() {
            sw = true;  // 스레드 중이므로 트루로
            if (edit.getText().toString().length() > 0) {   // 글자를 입력했는지 체크
                String text = Web.update(number, edit.getText().toString());
                runOnUiThread(new Runnable() {  // 스레드에서 Ui 수정하려면 추가
                    @Override
                    public void run() {
                        Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show();   // 토스트 메시지
                        if (text.equals("수정")) {
                            text_content.setText(edit.getText().toString()); // 적은 값으로 내용 변경
                            edit.setText("");   // 성공했으면 에딧텍스트 지우기
                        }
                    }
                });
            } else {    // 입력한 글자가 없을 때 실행
                runOnUiThread(new Runnable() {  // 스레드에서 Ui 수정하려면 추가
                    @Override
                    public void run() {
                        Toast.makeText(getApplicationContext(), "입력한 글자가 없음", Toast.LENGTH_SHORT).show();   // 토스트 메시지
                    }
                });
            }
            sw = false; // 스레드 끝나면 펄스로
        }
    }

    class Thread_delete extends Thread {    // 삭제 버튼 누르면 실행하는 딜리트
        public void run() {
            sw = true;  // 스레드 중이므로 트루로
            String text = Web.delete(number);
            runOnUiThread(new Runnable() {  // 스레드에서 Ui 수정하려면 추가
                @Override
                public void run() {
                    Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show();   // 토스트 메시지
                    if (text.equals("삭제")) {
                        finish();   // 삭제했으면 뷰 닫기
                    }
                }
            });
            sw = false; // 스레드 끝나면 펄스로
        }
    }
}

메인에서 리스트 항목을 누르면 나타나는 뷰의 java코드입니다.
db에서 내용을 수정, 삭제하는 기능 등이 있습니다.


Web.java

package com.ehsehsl.osc;

import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;

public class Web {
    private static String address = "http://xxx.xx.xx.xx:xxxx/test/";  // 사용하는 url 적기

    public static String insert(String content) {
        String result = "";
        try {
            //연결
            URL url = new URL(address + "insert.php");  // url 적기
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(10000);  // 10초간 연결 시도
            conn.setRequestMethod("POST");    // 전송 방식은 POST
            conn.setDefaultUseCaches(false);
            conn.setDoInput(true);    // 서버에서 읽기 모드 지정
            conn.setDoOutput(true);    // 서버로 쓰기 모드 지정
            conn.setRequestProperty("Accept-Language", "ko-kr,ko;q=0.8,en-us;q=0.5,en;q=0.3");

            String param = URLEncoder.encode("content", "UTF-8") + "=" + URLEncoder.encode(content, "UTF-8");
//            param += "&" + URLEncoder.encode("text", "UTF-8") + "=" + URLEncoder.encode(text, "UTF-8");

            //전송
            OutputStreamWriter osw = new OutputStreamWriter(conn.getOutputStream());

            osw.write(param);
            osw.flush();

            //응답
            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));

            StringBuilder builder = new StringBuilder();
            String str;
            while ((str = br.readLine()) != null) { // 웹에 있는 텍스트 받아오는 코드들
                builder.append(str);
            }
            result = builder.toString();

            //닫기
            osw.close();
            br.close();

        } catch (IOException e) {
            result = "네트워크 연결 실패";  // 네트워크 문제인지 알기 위해
            e.printStackTrace();
        }
        return result;
    }

    public static ArrayList<Info> select() {
        ArrayList<Info> result = new ArrayList<Info>();
        try {
            //   URL 설정하고 접속하기
            URL url = new URL(address + "select.php");  // url 적기
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(10000);
            conn.setRequestMethod("POST");    // 전송 방식은 POST
            conn.setDefaultUseCaches(false);
            conn.setDoInput(true);    // 서버에서 읽기 모드 지정
            conn.setDoOutput(true);    // 서버로 쓰기 모드 지정
            conn.setRequestProperty("Accept-Language", "ko-kr,ko;q=0.8,en-us;q=0.5,en;q=0.3");

            //--------------------------
            //   Response Code
            //--------------------------
            //http.getResponseCode();

//            String param = URLEncoder.encode("content", "UTF-8") + "=" + URLEncoder.encode(content, "UTF-8");
//            param += "&" + URLEncoder.encode("text", "UTF-8") + "=" + URLEncoder.encode(text, "UTF-8");

            //전송
//            OutputStreamWriter osw = new OutputStreamWriter(conn.getOutputStream());

//            osw.write(param);
//            osw.flush();
            //--------------------------
            //   서버에서 전송받기
            //--------------------------
            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
            String str;
            result = new ArrayList<>();

            JSONObject object;
            while ((str = br.readLine()) != null) {
                object = new JSONObject(str);   // json 형태로 받아오가
                String number = object.getString("_list");
                String content = object.getString("content");

                Info info = new Info(number, content);
                result.add(info);
            }

//            osw.close();
            br.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    public static String update(String number, String content) {
        String result = "";
        try {
            //연결
            URL url = new URL(address + "update.php");  // url 적기
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(10000);  // 10초간 연결 시도
            conn.setRequestMethod("POST");    // 전송 방식은 POST
            conn.setDefaultUseCaches(false);
            conn.setDoInput(true);    // 서버에서 읽기 모드 지정
            conn.setDoOutput(true);    // 서버로 쓰기 모드 지정
            conn.setRequestProperty("Accept-Language", "ko-kr,ko;q=0.8,en-us;q=0.5,en;q=0.3");

            String param = URLEncoder.encode("number", "UTF-8") + "=" + URLEncoder.encode(number, "UTF-8");
            param += "&" + URLEncoder.encode("content", "UTF-8") + "=" + URLEncoder.encode(content, "UTF-8");

            //전송
            OutputStreamWriter osw = new OutputStreamWriter(conn.getOutputStream());

            osw.write(param);
            osw.flush();

            //응답
            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));

            StringBuilder builder = new StringBuilder();
            String str;
            while ((str = br.readLine()) != null) { // 웹에 있는 텍스트 받아오는 코드들
                builder.append(str);
            }
            result = builder.toString();
            //닫기
            osw.close();
            br.close();

        } catch (Exception e) {
            result = "네트워크 연결 실패";  // 네트워크 문제인지 알기 위해
            e.printStackTrace();
        }
        return result;
    }

    public static String delete(String number) {
        String result = "";
        try {
            //연결
            URL url = new URL(address + "delete.php");  // url 적기
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(10000);  // 10초간 연결 시도
            conn.setRequestMethod("POST");    // 전송 방식은 POST
            conn.setDefaultUseCaches(false);
            conn.setDoInput(true);    // 서버에서 읽기 모드 지정
            conn.setDoOutput(true);    // 서버로 쓰기 모드 지정
            conn.setRequestProperty("Accept-Language", "ko-kr,ko;q=0.8,en-us;q=0.5,en;q=0.3");

            String param = URLEncoder.encode("number", "UTF-8") + "=" + URLEncoder.encode(number, "UTF-8");
//            param += "&" + URLEncoder.encode("text", "UTF-8") + "=" + URLEncoder.encode(text, "UTF-8");

            //전송
            OutputStreamWriter osw = new OutputStreamWriter(conn.getOutputStream());

            osw.write(param);
            osw.flush();

            //응답
            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));

            StringBuilder builder = new StringBuilder();
            String str;
            while ((str = br.readLine()) != null) { // 웹에 있는 텍스트 받아오는 코드들
                builder.append(str);
            }
            result = builder.toString();

            //닫기
            osw.close();
            br.close();

        } catch (IOException e) {
            result = "네트워크 연결 실패";  // 네트워크 문제인지 알기 위해
            e.printStackTrace();
        }
        return result;
    }
}

웹과 통신하는 코드입니다.
http통신을 사용해서 insert. select, update, delete 하는 모든 코드가 있습니다.
address에 x로 표시된 부분에 아이피 숫자들을 적으면 됩니다.


이제 서버 개발입니다.
서버가 없으신 분은 닷홈을 통해 서버를 생성합니다.
생성하고 phpMyAdmin을 접속합니다.

사진처럼 테이블을 만들어줍니다.
_list는 자동으로 1씩 올라갈 번호고 content는 내용입니다.


insert.php

<?php
$connect = mysqli_connect("localhost", "아이디", "비밀번호", "test");
mysqli_query($connect, 'SET NAMES utf8');

$content = $_POST['content'];	// 포스트로 변수 받아오기

if ($content != '') {	// 사이트에 접속했을 때 공백 입력되는 거 방지
	$query = "INSERT INTO list (content) VALUES ('$content')";	// 여러개면 , 찍고 뒤에 이어서 적기
}

if (mysqli_query($connect, $query)) {	// 쿼리 실행하고 성공인지 실패인지 알려주는 조건문
	echo '성공';
} else {
	echo '실패';
}

mysqli_close($connect);
?>

아이디와 비밀번호에는 phpMyAdmin에 접속할 때 쓰는 아이디와 비밀번호를 적어주면 됩니다.


select.php

<?php
$connect = mysqli_connect("localhost", "아이디", "비밀번호", "test");
mysqli_query($connect, 'SET NAMES utf8');

$query = "SELECT * FROM list ORDER BY _list DESC;";	// order by(정렬) 여러개면 , 찍고 추가

$result = mysqli_query($connect, $query);

while ($row = mysqli_fetch_array($result)) {
	$x = json_encode($row, JSON_UNESCAPED_UNICODE);
	echo $x . "\n";
}

mysqli_close($connect);
?>

update.php

<?php
$connect = mysqli_connect("localhost", "아이디", "비밀번호", "test");
mysqli_query($connect, 'SET NAMES utf8');

$number = $_POST['number'];
$content = $_POST['content'];

$query = "UPDATE list SET content = '$content' WHERE _list ='$number'";

if (mysqli_query($connect, $query)) {	// 쿼리 실행하고 성공인지 실패인지 알려주는 조건문
	echo '수정';
} else {
	echo '실패';
}

mysqli_close($connect);
?>

delete.php

<?php
$connect = mysqli_connect("localhost", "아이디", "비밀번호", "test");
mysqli_query($connect, 'SET NAMES utf8');

$number = $_POST['number'];

if ($number != '') {
	$query = "DELETE FROM list WHERE _list = '$number'";
}

if (mysqli_query($connect, $query)) {
	echo '삭제';
} else {
	echo '삭제 실패';
}

mysqli_close($connect);
?>

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
글 보관함