티스토리 뷰
위 영상에 있는 앱 코드를 기록하려고 합니다.
나중에 필요할 때 보려는 용도로 기록하는 느낌이 강해서 설명은 거의 없고 코드가 대부분을 차지합니다.
궁금한 부분은 댓글로 적어두시면 금방 답합니다.
만들기 위해서는 서버가 필요한데 저는 다른 서버를 사용했지만 없으신 분은 연습용 정도는 무료로 쓸 수 있는 닷홈을 추천합니다.
안드로이드는 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);
?>
'안드로이드 네이티브' 카테고리의 다른 글
안드로이드 화면 전환 애니메이션 5가지 (0) | 2021.12.20 |
---|---|
안드로이드 위치 서비스가 꺼져있으면 키라는 창 뜨게 하기 (0) | 2020.11.09 |
안드로이드 뒤로 가기 버튼 두 번 눌러야 꺼지도록 하기 (0) | 2020.11.04 |
안드로이드 버튼 누르고 있으면 숫자 올라가거나 내려가기 (0) | 2020.10.26 |
안드로이드 진동, 소리, 음악 파일 제어하기 (0) | 2020.10.04 |
- Total
- Today
- Yesterday
- 앱개발
- 로또
- 구구단어플
- 자바스크립트
- 구구단
- 안드로이드
- 오토핫키
- 플러터
- 챗봇
- 노래
- 명언
- 코틀린
- 안드로이드스튜디오
- 안드로이드클라이언트
- 매크로
- MouseMove
- sendinput
- JS
- 자동답장
- 카카오톡
- 카카오봇
- 안드로이드네이티브
- inputbox
- Flutter
- 안드로이드앱
- 구구단앱
- 채팅
- 안드로이드앱개발
- loop
- 구구단공부
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |