안드로이드는 직접적으로 외부 DB를 연결할 수가 없다고 했을 때가 지금 어플을 만들면서 가장 당황하였던 부분이 아닌가 싶다.
<!-- (2019.8.5 추가) JDBC로 연결이 가능하다. -->
안드로이드는 내부에 sqlite를 이용할 때는 바로 연결할 수 있는 듯 하지만, 외부의 DB를 연결할 때는 php로 DB를 Json으로 파싱하여 웹으로 뿌려 준 후 안드로이드에서 그 Json을 받아 오는 방법으로 정보를 가져와야 한다.
구글링을 통하여 얻은 결과 가장 보편적인 방법 같은 HttpURLConnection 을 이용해볼 것이다.
//SELECT SQL문을 받아 줄 php
<?php
error_reporting(E_ALL);
ini_set('display_errors',1);
require('/*DB 커넥션 php 경로*/');
$android = strpos($_SERVER['HTTP_USER_AGENT'], "Android");
if($android) {
$query=$_POST['query']; // 안드로이드에서 넘어올 query 문
$stmt = $PDO->query($query);
$stmt->execute();
if ($stmt->rowCount() > 0) {
$data = array();
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
array_push($data,
$row);
}
header('Content-Type: application/json; charset=utf8');
$json = json_encode(array("/*Json의 이름 되지만 지정하지 않을 수 있다.*/" => $data), JSON_PRETTY_PRINT + JSON_UNESCAPED_UNICODE);
echo $json;
}
}
?>
이렇게 php를 작성하여 Json으로 파싱하여준다.(자바에서 쿼리문을 받아오기 때문에 여러 테이블을 참조할 수 있게 제작)
이번에는 안드로이드에서 DB의 내용을 표현할 recyclerview를 만들것이다. activity의 xml이다.
mainactivity.xml
<?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:layout_margin="15dp"
android:padding="10dp">
<android.support.v7.widget.RecyclerView
android:id="@+id/fieldRecycle"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_margin="5dp"
android:layout_weight="6"
android:padding="5dp" />
</LinearLayout>
item_list.xml
<?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">
//받아올 필드가 2개라면 2개 선언!
<TextView
android:id="@+id/textView_field"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:padding="5dp" />
</LinearLayout>
그리고 아래는 main activity.java이다.
import를 시켜야할 라이브러리들이다.
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.widget.Button;
import android.app.ProgressDialog;
import android.os.AsyncTask;
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;
import android.util.Log;
아래는 메인 엑티비티이다.
public class MainActivity extends AppCompatActivity {
public static String IP_ADDRESS = "/*Json으로 파싱해줄 php가 있는 web 경로*/";
private static String TAG = "Json";
private RecyclerView subjectRecycle;
private ArrayList<PersonalData> mArrayList;
private UsersAdapter mAdapter;
private String mJsonString;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 리사이클러리스트를 통하여 여러 줄로 db 표현
fieldRecycle = (RecyclerView) findViewById(R.id.fieldRecycle);
fieldRecycle.setLayoutManager(new LinearLayoutManager(this));
mArrayList = new ArrayList<>();
mAdapter = new UsersAdapter(this, mArrayList);
fieldRecycle.setAdapter(mAdapter);
mArrayList.clear();
mAdapter.notifyDataSetChanged();
GetData task = new GetData();
task.execute( IP_ADDRESS, "");
}
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();
Log.d(TAG, "response - " + result);
if (result == null){
}
else {
mJsonString = result;
showResult();
}
}
@Override
protected String doInBackground(String... params) {
String serverURL = params[0];
String postParameters = "/* 쿼리문 작성 */";
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, "GetData : Error ", e);
errorString = e.toString();
return null;
}
}
}
private void showResult(){
String TAG_JSON="/*Json의 이름 ""로 생략 가능*/";
String TAG_field = "/*필드를 받아 올 변수*/";
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 field = item.getString(TAG_field);
PersonalData personalData = new PersonalData();
personalData.setMember_subject(subject)
mArrayList.add(personalData);
mAdapter.notifyDataSetChanged();
}
} catch (JSONException e) {
Log.d(TAG, "showResult : ", e);
}
}
userAdaptor class 이다.
package com.example.ondroid;
import android.app.Activity;
import android.support.annotation.NonNull;
import android.support.v7.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 subject;
public CustomViewHolder(View view) {
super(view);
this.field = (TextView) view.findViewById(R.id.textView_field);
}
}
@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.field.setText(mList.get(position).getMember_field());
}
@Override
public int getItemCount() {
return (null != mList ? mList.size() : 0);
}
}
personalData class 이다.
package com.example.ondroid;
public class PersonalData {
private String member_field;
public String getMember_field() {
return member_field;
}
public void setMember_field(String member_field) {
this.member_fieldt = member_field;
}
}
'Java > 안드로이드' 카테고리의 다른 글
안드로이드 타이틀,상태바 없애기 (0) | 2019.09.12 |
---|---|
안드로이드 레이아웃 색상 자바에서 지정 (0) | 2019.09.12 |
안드로이드 runOnUiThread (0) | 2019.09.12 |
안드로이드 Handler 의 Memory Leak (0) | 2019.09.12 |
안드로이드 activity Life Cycle (0) | 2019.09.12 |