IoTMakers는 IoTMakers 플랫폼에 저장된 다양한 정보(디바이스, 태그스트림, 이벤트, 공개디바이스)를 활용할 수 있는 IoT 애플리케이션 개발을 위해 두 가지 방식을 지원합니다.
애플리케이션 개발을 위한 IoTMakers 플랫폼의 주요 지원 기능
앱 등록 절차
포탈 메뉴 상단의 IoT 개발 탭 내 앱 등록 메뉴에서 아래와 같이 [App 등록] 버튼을 클릭합니다.
기본정보 및 상세정보를 입력 후, 저장 버튼을 클릭합니다.
기본정보 입력
상세정보 입력
등록된 앱의 App ID와 App Secret를 확인한다.
Android Studio를 통해서 Android 프로젝트를 생성
Android Studio 프로젝트의 최 상단(app 모듈)에서 우 클릭 후 Open Module Setting을 선택합니다.
화면 상단의 + 버튼을 클릭한다.
Import Gradle Project 를 선택 후 Next를 클릭합니다.
압축 푼 SDK를 찾아 선택하고 Finish를 클릭합니다.
그 다음 Modules 중 app의 Dependencies 를 선택 후 + (Add Dependency) 버튼을 클릭한 후 Module Dependency를 선택한다.
Add Module Dependency 창이 뜨면 iotmakers_sdk_android 를 선택하고 OK를 누릅니다
OK 버튼을 클릭하여 SDK 기본설정을 마친다.
IoTMakers 포탈에 배포된 SDK는 Android4.0 기반으로 만들어진 것이므로, 최신 Android 플랫폼 버전 (Android 9.0, API level 29)에서 정상적으로 동작시키기 위해서 다음과 같은 추가작업을 수행해야 합니다.
build.gradle (Module: iotmakers_sdk_android) 스크립트 수정
buildToolsVersion21.1.2" 삭제
compile을
implementation으로 변경
AndroidManifest.xml 파일 수정
<application> 태그 안에 다음 태그를 추가
<application ...>
<uses-library android:name="org.apache.http.legacy" android:required="false" />
</application>
<application> 부분에 android:usesCleartextTraffic=true
로 설정
<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/AppTheme"
android:usesCleartextTraffic="true">
iotmakers_sdk_android 라이브러리에 포함된 서버 주소로는 접속이 안되는 문제가 발생하여, 새로운 서버 주소로 변경해야 합니다.
모든 http://iotmakers.olleh.com
를 http://iotmakers.kt.com
로 수정
//Open API 변경
public static final String OPEN_API_AUTH_HOST_ADDRESS = "http://iotmakers.kt.com";
public static final String OPEN_API_HOST_ADDRESS = "http://iotmakers.kt.com/api/v1"; //API-GW host
public static final String OPEN_API_CORE_HOST = "http://iotmakers.kt.com/coreapi/v1"; //API-GW event host
public static final String OPEN_API_PUSH_HOST = "http://iotmakers.kt.com/pushapi/v1"; //API-GW push host
이하 모든 IoTMakers 연동 Android 얩 예제 프로젝트에서는 IoTMaker 서버와 Android 앱이 인터넷 통신을 위해서 AndroidManifest.xml 파일에 다음 권한을 추가해야 합니다.
<manifest> 태크 안에 다음 android.permission.INTERNET 권한을 추가
<manifest ...>
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
로그인에 필요한 APP ID / Secret 은 아래와 같이 앱 등록 시 기본정보 메뉴에서 확인하시면 됩니다.
플랫폼 로그인 API는 네트워크를 사용하는데, 네트워크를 사용하는 코드는 Android 3.0 이후부터 UI 스레드와 분리된 스레드에서 동작해야 합니다.
public class LoginActivity extends AppCompatActivity {
// 다음 상수정의 부분을 여러분의 정보로 변경하여야 합니다.
private static final String APP_ID = "APP ID";
private static final String SECRET = "APP SECRET";
private static final String USER_ID = "사용자 ID";
private static final String PASSWORD = "비밀번호";
String accessToken;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Thread loginThread = new LoginThread();
loginThread.start();
}
/*
* 네트워크 관련 코드는 Main UI Thread와는 별도의 Thread로 수행되어야 합니다.
*/
private class LoginThread extends Thread {
public void run() {
GigaIotOAuth gigaIotOAuth = new GigaIotOAuth(APP_ID, SECRET);
GiGaIotOAuthResponse authResponse = gigaIotOAuth.loginWithPassword(USER_ID, PASSWORD);
accessToken = authResponse.getAccessToken();
}
}
}
위 방식에서는 LoginThread가 UI 스레드가 아니기 때문에 LoginThread에서 UI를 조작할 수가 없습니다.
private class LoginThread extends Thread {
public void run() {
GigaIotOAuth gigaIotOAuth = new GigaIotOAuth(APP_ID, SECRET);
GiGaIotOAuthResponse authResponse = gigaIotOAuth.loginWithPassword(USER_ID, PASSWORD);
accessToken = authResponse.getAccessToken();
// 아래 코드는 오류를 야기시킴
Toast.makeText(MainActivity.this, R.string.login_success, Toast.LENGTH_SHORT).show();
}
}
AysncTask 란?
LoginActivity.java
public class LoginActivity extends AppCompatActivity implements View.OnClickListener {
private EditText mEtId, mEtPw, mEtAppId, mEtSec;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
mEtId = findViewById(R.id.et_login_id);
mEtPw = findViewById(R.id.et_login_pw);
mEtAppId = findViewById(R.id.et_app_id);
mEtSec = findViewById(R.id.et_app_secret);
ImageView ivLogin = (ImageView) findViewById(R.id.iv_login_bt);
ivLogin.setOnClickListener(this);
}
// Login 버튼 클릭 시 호출됨
public void onClick(View v) {
switch(v.getId()){
case R.id.iv_login_bt:
String id = mEtId.getText().toString();
String pw = mEtPw.getText().toString();
String app_id = mEtAppId.getText().toString();
String secret = mEtSec.getText().toString();
if(TextUtils.isEmpty(id)){
Toast.makeText(LoginActivity.this, R.string.login_id_empty, Toast.LENGTH_SHORT).show();
return;
} else if(TextUtils.isEmpty(pw)){
Toast.makeText(LoginActivity.this, R.string.login_pw_empty, Toast.LENGTH_SHORT).show();
return;
} else if(TextUtils.isEmpty(app_id)){
Toast.makeText(LoginActivity.this, R.string.login_app_id_empty, Toast.LENGTH_SHORT).show();
return;
} else if(TextUtils.isEmpty(secret)){
Toast.makeText(LoginActivity.this, R.string.login_secret_empty, Toast.LENGTH_SHORT).show();
return;
}
// LoginTask 클래스의 doInBackground() 메소드 호출
new LoginTask().execute();
break;
}
}
private class LoginTask extends AsyncTask<Void, Void, GiGaIotOAuthResponse> {
ProgressDialog progressDialog;
String id;
@Override
protected void onPreExecute() {
progressDialog = ProgressDialog.show(LoginActivity.this, "", getResources().getString(R.string.common_wait), true, false);
}
@Override
protected GiGaIotOAuthResponse doInBackground(Void... params) {
id = mEtId.getText().toString();
String pw = mEtPw.getText().toString();
String app_id = mEtAppId.getText().toString();
String secret = mEtSec.getText().toString();
//테스트용
GigaIotOAuth gigaIotOAuth = new GigaIotOAuth(app_id, secret);
GiGaIotOAuthResponse response = gigaIotOAuth.loginWithPassword(id, pw);
return response;
}
@Override
protected void onPostExecute(GiGaIotOAuthResponse result) {
if(progressDialog != null && progressDialog.isShowing()){
progressDialog.dismiss();
progressDialog = null;
}
if(result != null && result.getResponseCode().equals(ApiConstants.CODE_OK)){
Toast.makeText(LoginActivity.this, getResources().getString(R.string.login_success), Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(LoginActivity.this, getResources().getString(R.string.login_fail) + result.getMessage(), Toast.LENGTH_SHORT).show();
}
}
}
}
전체 프로젝트 코드
DeviceApiResponse
Method
Method | Description |
---|---|
public String getResponseCode () | 응답에 대한 코드를 문자열로 반환합니다 |
public String getMessage () | 응답에 대한 메시지를 문자열로 반환합니다. |
public int getTotal () | 응답에 대한 데이터가 목록일 경우 데이터의 총 개수를 반환합니다. |
public int getPage () | 응답에 대한 데이터가 목록일 경우 요청한 페이지 번호를 반환합니다. |
public int getRowNum () | 응답에 대한 데이터가 목록일 경우 페이지 별 데이터의 개수를 반환합니다. |
public ArrayList |
디바이스 목록을 가져 올 수 있다. 목록은 ArrayList에 Device 객체로 반환된다. |
Device
Attributes
Attribute | Description |
---|---|
String atcFileSeq | 디바이스 이미지 일련번호 |
String cretDt | 디바이스 생성일시 |
String devModelNm | 디바이스 모델 명 |
String devModelSeq | 디바이스 모델 일련번호 |
String devNm | 디바이스 명 |
String gwCnctId | 게이트웨이 연결 아이디 |
String protID | 프로토콜 아이디 |
String protNm | 프로토콜 명 |
String spotDevId | 디바이스 아이디 |
String spotDevSeq | 디바이스 일련번호 |
String svcTgtSeq | 서비스 대상 일련번호 |
List |
태그스트림 리스트 |
DeviceListActivity.java
public class DeviceListActivity extends AppCompatActivity implements AdapterView.OnItemClickListener{
private final int ROW_CNT = 10;
private int mPageNum = 1;
private ListView mListView;
ArrayList<Device> mDevices;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_device_list);
mListView = findViewById(R.id.lv_device_list);
mListView.setOnItemClickListener(this);
new GetDevListTask().execute(); // GetDevListTask의 doInBackground() 메소드 수행
}
/**
* 디바이스 목록 중 하나가 선택되었을 때 호출되는 메소드
* @param parent 디바이스 목록을 표시하는 리스트뷰 객체
* @param view 선택된 항목 뷰 객체
* @param position 디바이스 목록 중 선택된 항목 위치
* @param id
*/
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (mDevices != null) {
Gson gson = new Gson();
String strDevice = gson.toJson(mDevices.get(position)); // 리스트뷰에서 선택된 디바이스 객체 정보를 JSON 문자열로 변환
Intent intent = new Intent(DeviceListActivity.this, DeviceActivity.class);
intent.putExtra(DeviceActivity.EXTRA_DEVICE, strDevice); // JSON 문자열로 변환된 디바이스 객체 정보를 DeviceActivity에 Extras를 통해 전달
startActivity(intent);
}
}
/*
* DeviceListActivity UI 스레드와는 별도의 스레드로 IoTMaker와 네트워크 통신 수행
*/
private class GetDevListTask extends AsyncTask<Void, Void, DeviceApiResponse> {
@Override
protected DeviceApiResponse doInBackground(Void... voids) {
// Access Token을 통해 DeviceApi 객체 획득
DeviceApi deviceApi = new DeviceApi(ApplicationPreference.getInstance().getPrefAccessToken());
// 디바이스 목록 조회 요청
DeviceApiResponse response = deviceApi.getDeviceList(mPageNum, ROW_CNT);
return response;
}
/**
* doInBackground 메소드가 수행된 직후에 수행되는 메소드로서 doInBackground 메소드의 리턴 값이 result 파라미터 값으로 전달됨
* @param result: Device 목록 요청에 대한 응답 정보를 포함한 DeviceApiResponse 객체
*/
@Override
protected void onPostExecute(DeviceApiResponse result) {
// 전체 디바이스 객체 목록을 ArrayList 객체인 mDevices 멤버변수에 저장
mDevices = result.getDevices();
ArrayList<String> device_names = new ArrayList<String>();
for (Device d: mDevices) {
device_names.add(d.getDevNm());
}
// ArrayAdpater 객체 생성 및 설정
ArrayAdapter dAdapter = new ArrayAdapter(DeviceListActivity.this,
android.R.layout.simple_list_item_1, device_names.toArray());
// 리스트뷰에 어뎁터 객체 연결
mListView.setAdapter(dAdapter);
}
}
}
DeviceActivity.java
디바이스 목록 중 하나의 디바이스가 선택되었을 때, 해당 디바이스에 대한 정보를 표시해 주는 액티비티 클래스
public class DeviceActivity extends AppCompatActivity implements AdapterView.OnItemClickListener{
String TAG="DeviceActivity";
public static final String EXTRA_DEVICE = "device";
private Device mDevice;
private ArrayList<TagStrm> mTagStrms;
private ListView mListView;
Handler mHandler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_device);
mListView = findViewById(R.id.lv_tagstrm_list);
mListView.setOnItemClickListener(this);
String strDevice = getIntent().getStringExtra(EXTRA_DEVICE);
Gson gson = new Gson();
mDevice = gson.fromJson(strDevice, Device.class);
TextView tw_device = findViewById(R.id.tv_device_info);
tw_device.setText("디바이스 이미지 일련번호: "+ mDevice.getAtcFileSeq() +"\n"+
"디바이스 생성일시: "+ mDevice.getCretDt() +"\n"+
"디바이스 모델 명: "+ mDevice.getDevModelNm() +"\n"+
"디바이스 모델 일련번호: "+ mDevice.getDevModelSeq() +"\n"+
"디바이스 명: "+ mDevice.getDevNm() +"\n"+
"게이트웨이 연결 아이디: "+ mDevice.getGwCnctId() +"\n"+
"프로토콜 아이디: "+ mDevice.getProtID() +"\n"+
"프로토콜 명: " + mDevice.getProtNm() + "\n"+
"디바이스 아이디: " + mDevice.getSpotDevId() + "\n"+
"디바이스 일련번호: " + mDevice.getSpotDevSeq() + "\n"+
"서비스 대상 일련번호: " + mDevice.getSvcTgtSeq() + "\n"
);
// ... 생략
}
//... 생략
}
TagStrmApiResponse
Method
Method | Description |
---|---|
public String getResponseCode () | 응답에 대한 코드를 반환합니다. |
public String getMessage () | 응답에 대한 메시지를 반환합니다 |
public ArrayList |
디바이스에 등록된 태그스트림 목록을 가져 올 수 있다. 태그스트림 목록 조회 시 반환되며, ArrayList에 TagStrm 객체로 반환된다 |
public ArrayList |
디바이스에 등록된 태그스트림에서 발생한 수집데이터 이력을 가져 올 수 있다. 태그스트림 데이터 이력 조회 시 반환되며, ArrayList에 Log 객체로 반환된다. |
TagStrm
태그스트림 정보 클래스, 디바이스에 등록된 태그스트림 조회 시 태그스트림에 대한 정보를 확인할 수 있다.
Attributes
Attribute | Description |
---|---|
String tagStrmSeq | 태그스트림일련번호 |
String tagStrmId | 태그스트림ID |
String tagStrmUnitVal | 태그스트림단위값 |
String tagStrmPrpsTypeCd | 제어코드 0000010:수집 0000020:제어 |
String tagStrmPrpsTypeCdNm | |
String tagStrmValTypeCd | |
String tagStrmValTypeCdNm | 숫자형여부 0000010:숫자 0000020:문자 |
String indcOdrg | 표시순서 |
String amdrId | |
String amdDt |
Log
태그스트림 수집데이터 정보 클래스, 디바이스에 등록된 태그스트림 수집 이력 조회 시 수집데이터에 대한 정보를 확인할 수 있다.
Attributes
Attribute | Description |
---|---|
String occDt | 발생 일시 |
String spotDevSeq | 현장장치 일련번호 |
String svcTgtSeq | 서비스대상 일련번호 |
HashMap<String, Object> attributes | 수집 데이터 HashMap |
DeviceActivity.java
public class DeviceActivity extends AppCompatActivity implements AdapterView.OnItemClickListener{
String TAG="DeviceActivity";
public static final String EXTRA_DEVICE = "device";
private Device mDevice;
private ArrayList<TagStrm> mTagStrms;
private ListView mListView;
Handler mHandler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_device);
mListView = findViewById(R.id.lv_tagstrm_list);
mListView.setOnItemClickListener(this);
String strDevice = getIntent().getStringExtra(EXTRA_DEVICE);
Gson gson = new Gson();
mDevice = gson.fromJson(strDevice, Device.class);
// ... 생략
// 태그스트림 목록을 읽어오는 AsyncTask 수행
new GetTagStrmListTask().execute();
}
// ... 생략
/**
* TagStrmApi를 통해 태그스트림 목록을 읽어와서 리스트뷰에 제어 및 수집용으로 구분하여
* 태그스트림을 표시한다.
*/
private class GetTagStrmListTask extends AsyncTask<Void, Void, TagStrmApiResponse> {
@Override
protected TagStrmApiResponse doInBackground(Void... params) {
TagStrmApi tagStrmApi = new TagStrmApi(ApplicationPreference.getInstance().getPrefAccessToken());
TagStrmApiResponse response = tagStrmApi.getTagStrmList(mDevice.getSpotDevId());
return response;
}
@Override
protected void onPostExecute(TagStrmApiResponse result) {
mTagStrms = result.getTagStrms();
ArrayList<String> tagStrm_names = new ArrayList<String>();
for (TagStrm tag: mTagStrms) {
String type ="UnKnown";
if (tag.getTagStrmPrpsTypeCd().equals("0000010"))
type ="수집";
else if (tag.getTagStrmPrpsTypeCd().equals("0000020"))
type = "제어";
tagStrm_names.add("[" + type +"] "+ tag.getTagStrmId());
}
// ArrayAdpater 객체 생성 및 설정
ArrayAdapter dAdapter = new ArrayAdapter(DeviceActivity.this,
android.R.layout.simple_list_item_1, tagStrm_names.toArray());
// 리스트뷰에 어뎁터 객체 연결
mListView.setAdapter(dAdapter);
}
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (mTagStrms != null) {
TagStrm tagStrm = mTagStrms.get(position);
Gson gson = new Gson();
String strTag = gson.toJson(tagStrm);
String strDevice = gson.toJson(mDevice);
if (tagStrm.getTagStrmPrpsTypeCd().equals(TagStrmApi.TAGSTRM_DATA)) {
Intent intent = new Intent(DeviceActivity.this, TagStrmLogActivity.class);
intent.putExtra(DeviceActivity.EXTRA_DEVICE, strDevice);
intent.putExtra(TagStrmLogActivity.EXTRA_TAGSTRM, strTag);
startActivity(intent);
} else if (tagStrm.getTagStrmPrpsTypeCd().equals(TagStrmApi.TAGSTRM_CTRL)) {
createSendCtrlMsgDialog(position);
}
}
}
}
TagStrmLogActivity.java
public class TagStrmLogActivity extends AppCompatActivity {
public static final String EXTRA_TAGSTRM = "tagstrm";
private TagStrm mTagStrm;
private Device mDevice;
private String period;
private String count;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tag_strm_log);
Gson gson = new Gson();
// JSON 문자열 형태로 TagStrmLogActivity로 전달된 TagStrm 객체를 받아옴
String strTag = getIntent().getStringExtra(EXTRA_TAGSTRM);
mTagStrm = gson.fromJson(strTag, TagStrm.class);
// JSON 문자열 형태로 TagStrmLogActivity로 전달된 Device 객체를 받아옴
String strDevice = getIntent().getStringExtra(DeviceActivity.EXTRA_DEVICE);
mDevice = gson.fromJson(strDevice, Device.class);
// 화면 상단에 조회할 태그스트림 ID를 표시함
TextView textView = findViewById(R.id.tv_tagstrm);
String tag_id = mTagStrm.getTagStrmId();
textView.setText("태그 스트림 [" +tag_id + "] 조회");
// 조회 버튼이 클릭되었을 때 호출될 이벤트 리스너 정의
Button btn_log = findViewById(R.id.btn_log);
btn_log.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 두개의 텍스트뷰로부터 기간(period)과 개수(count)정보를 읽어옴
TextView tv = findViewById(R.id.et_log_period);
period = tv.getText().toString();
tv = findViewById(R.id.et_log_count);
count = tv.getText().toString();
// 미입력시 오류 처리
if(TextUtils.isEmpty(period)){
Toast.makeText(TagStrmLogActivity.this, R.string.period_empty, Toast.LENGTH_SHORT).show();
return;
} else if(TextUtils.isEmpty(count)){
Toast.makeText(TagStrmLogActivity.this, R.string.count_empty, Toast.LENGTH_SHORT).show();
return;
}
// TagStrmApi를 통해 TagStrmLog를 읽어오는 AsyncTask 수행
new GetLogPoolingTask().execute();
}
});
}
/**
* TagStrmApi를 통해 TagStrmLog를 읽어와서, 현재 조회할 태그스트림 id와 일치하는 로그에 대해서만
* 로그 값과 로그가 측정된 시간정보를 하나의 문자열로 만들고, 이들을 누적시킨 결과를 텍스트 뷰에 출력한다.
*
*/
private class GetLogPoolingTask extends AsyncTask<Void, Void, TagStrmApiResponse> {
@Override
protected TagStrmApiResponse doInBackground(Void... params) {
TagStrmApi tagStrmApi = new TagStrmApi(ApplicationPreference.getInstance().getPrefAccessToken());
TagStrmApiResponse response = tagStrmApi.getTagStrmLog(mDevice.getSpotDevId(),period, count );
// mDevice.setTagStrmList(response.getTagStrms());
return response;
}
@Override
protected void onPostExecute(TagStrmApiResponse result) {
// ArrayList<Object> log_str = new ArrayList<Object>();
if (result.getResponseCode().equals(ApiConstants.CODE_OK)) {
ArrayList<Log> logs = result.getLogs();
StringBuffer result_str = new StringBuffer();
for(Log log : logs){
Object tagValue = log.getAttributes().get(mTagStrm.getTagStrmId());
if (log.getAttributes().get(mTagStrm.getTagStrmId()) != null) { // 태그스트림 id와 일치하는 태그스트림 로그에 대해서.
// result_str 문자열에 값과 시간정보를 나타내는 문자열을 추가
result_str.append(tagValue.toString()+ " [" + log.getOccDt() + "] \n");
}
}
TextView tv_result_str = findViewById(R.id.tv_log_result);
tv_result_str.setText(result_str);
}
}
}
}
private void createSendCtrlMsgDialog(final int position)
public class DeviceActivity extends AppCompatActivity implements AdapterView.OnItemClickListener{
// ... 생략
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (mTagStrms != null) {
// ... 생략
} else if (tagStrm.getTagStrmPrpsTypeCd().equals(TagStrmApi.TAGSTRM_CTRL)) {
// 태그스트림 목록에서 선택된 태그스트림이 제어 형식인 경우, 제어명령 전송을 위한 다이얼로그 생성
createSendCtrlMsgDialog(position);
}
}
}
private void createSendCtrlMsgDialog(final int position){
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View dilogView = inflater.inflate(R.layout.dialog_device_ctrl, null);
final EditText etCtrlMsg = (EditText) dilogView.findViewById(R.id.et_device_ctrl);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("제어요청 보내기")
.setView(dilogView)
.setPositiveButton("보내기", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
final String ctrlMsg = etCtrlMsg.getText().toString();
//TODO : 제어요청 API 호출
new Thread(new Runnable() {
@Override
public void run() {
TagStrmApi tagStrmApi = new TagStrmApi(ApplicationPreference.getInstance().getPrefAccessToken());
final TagStrmApiResponse response = tagStrmApi.sendCtrlMsg(
mDevice.getSvcTgtSeq(), mDevice.getSpotDevSeq(), mDevice.getSpotDevId(), mDevice.getGwCnctId(),
mTagStrms.get(position).getTagStrmId(),
mTagStrms.get(position).getTagStrmValTypeCd(),
ApplicationPreference.getInstance().getPrefAccountId(), ctrlMsg);
if (response.getResponseCode().equals(ApiConstants.CODE_OK)) {
mHandler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(DeviceActivity.this, "제어 요청이 성공하였습니다.", Toast.LENGTH_SHORT).show();
}
});
} else if (response.getResponseCode().equals(ApiConstants.CODE_NG)) {
mHandler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(DeviceActivity.this, "제어 요청이 실패하였습니다.\n[" + response.getMessage() + "]", Toast.LENGTH_SHORT).show();
}
});
}
}
}).start();
}
})
.setNegativeButton("취소", null);
AlertDialog dialog = builder.create();
dialog.show();
}
전체 프로젝트 코드
이를 최신 플랫폼 및 안드로이드 스튜디오에서 빌드될 수 있도록 만든 버전을 아래 주소에서 다운로드할 수 있으니, 다운로드 후에 테스트 해 보세요.