Commit 21f807f5 by Lee Jaebin

#36104 機器連携(SPP通信処理)対応

parent 55aeeca4
......@@ -112,10 +112,6 @@
<option name="m_ignoreInvisibleFields" value="true" />
<option name="m_ignoreStaticMethods" value="true" />
</inspection_tool>
<inspection_tool class="LoggerInitializedWithForeignClass" enabled="false" level="WARNING" enabled_by_default="false">
<option name="loggerClassName" value="org.apache.log4j.Logger,org.slf4j.LoggerFactory,org.apache.commons.logging.LogFactory,java.util.logging.Logger" />
<option name="loggerFactoryMethodName" value="getLogger,getLogger,getLog,getLogger" />
</inspection_tool>
<inspection_tool class="MagicConstant" enabled="true" level="ERROR" enabled_by_default="true" />
<inspection_tool class="MagicNumber" enabled="true" level="INFO" enabled_by_default="true">
<option name="ignoreInitialCapacity" value="true" />
......@@ -138,6 +134,9 @@
<option name="updateNames">
<value />
</option>
<option name="ignoredClasses">
<value />
</option>
</inspection_tool>
<inspection_tool class="MismatchedStringBuilderQueryUpdate" enabled="true" level="ERROR" enabled_by_default="true" />
<inspection_tool class="MissingOverrideAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
......@@ -260,7 +259,7 @@
<option name="REPORT_REDUNDANT_INITIALIZER" value="true" />
</inspection_tool>
<inspection_tool class="UseOfPropertiesAsHashtable" enabled="true" level="ERROR" enabled_by_default="true" />
<inspection_tool class="VariableNotUsedInsideIf" enabled="true" level="ERROR" enabled_by_default="true" />
<inspection_tool class="VariableNotUsedInsideIf" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="unused" enabled="true" level="TODO" enabled_by_default="true">
<option name="LOCAL_VARIABLE" value="true" />
<option name="FIELD" value="true" />
......
package jp.agentec.abook.abv.bl.acms.client.json;
import java.util.ArrayList;
import java.util.List;
import jp.agentec.abook.abv.bl.acms.client.AcmsClient;
import jp.agentec.abook.abv.bl.common.exception.AcmsException;
import jp.agentec.abook.abv.bl.common.exception.JSONValidationException;
import jp.agentec.abook.abv.bl.common.util.JsonUtil;
import jp.agentec.abook.abv.bl.dto.ContentDto;
import jp.agentec.abook.abv.bl.dto.SppDeviceDto;
import org.json.adf.JSONArray;
import org.json.adf.JSONObject;
......@@ -24,10 +26,21 @@ public class ContentVersionsJSON extends AcmsCommonJSON {
public static final String ContentNameKana = "contentNameKana";
public static final String ContentType = "contentType";
public static final String FetchDate = "fetchDate";
// SPP通信の端末情報リスト
public static final String SppDeviceInfoList = "sppDeviceInfoList";
public static final String SppDeviceId = "sppDeviceId";
public static final String SppDeviceName = "sppDeviceName";
public static final String DataStartIndex = "dataStartIndex";
public static final String DataEndIndex = "dataEndIndex";
public ArrayList<ContentDto> contentVersions;
public String fetchDate;
// SPP通信機器のDTOリスト
public List<SppDeviceDto> sppDeviceDtoList;
public static final String ResourcePatternType = "resourcePatternType"; // 文言リソースパターン
public int resourcePatternType; // 文言リソースパターン変数
......@@ -44,6 +57,26 @@ public class ContentVersionsJSON extends AcmsCommonJSON {
if (json.has(FetchDate)) {
fetchDate = json.getString(FetchDate);
}
// SppDeviceInfoListキーが存在する場合、sppDeviceDtoListにセットする
if (json.has(SppDeviceInfoList)) {
sppDeviceDtoList = new ArrayList<SppDeviceDto>();
JSONArray sppDeviceInfoArray = json.getJSONArray(SppDeviceInfoList);
for (int j = 0; j < sppDeviceInfoArray.length(); j++) {
JSONObject sppDeviceJson = sppDeviceInfoArray.getJSONObject(j);
SppDeviceDto sppDeviceDto = new SppDeviceDto();
// SPP通信機器ID
sppDeviceDto.sppDeviceId = getInt(sppDeviceJson, SppDeviceId);
// SPP通信機器名
sppDeviceDto.sppDeviceName = getString(sppDeviceJson, SppDeviceName);
// SPP通信機器から取得対象の開始文字列
sppDeviceDto.dataStartIndex = getInt(sppDeviceJson, DataStartIndex);
// SPP通信機器から取得対象の終了文字列
sppDeviceDto.dataEndIndex = getInt(sppDeviceJson, DataEndIndex);
sppDeviceDtoList.add(sppDeviceDto);
}
}
if (json.has(ContentList)) {
JSONArray jarr = json.getJSONArray(ContentList);
......
......@@ -171,8 +171,11 @@ public class Constant {
// 連携機器の区分
public interface DeviceType {
int thermomete = 1; // 中心温度計
int centerThermomete = 1; // 中心温度計
int sensor = 2; // 置くだけセンサー
int barcode = 3; // バーコード
int radiationThermomete = 4; // 放射温度計
int sppBluetoothMachine = 5; // SPP通信機器
int nfc = 6; // nfc機器
}
}
......@@ -185,10 +185,10 @@ public class JsonUtil {
else if (retType.equals(String.class)) {
return (T) obj.toString();
}
else if ((retType.equals(long.class) || retType.equals(Long.class)) && StringUtil.isNumber(obj.toString())) {
else if ((retType.equals(long.class) || retType.equals(Long.class)) && StringUtil.isLongNumber(obj.toString())) {
return (T)(Long)Long.parseLong(obj.toString());
}
else if ((retType.equals(int.class) || retType.equals(Integer.class)) && StringUtil.isNumber(obj.toString())) {
else if ((retType.equals(int.class) || retType.equals(Integer.class)) && StringUtil.isLongNumber(obj.toString())) {
return (T)(Integer)Integer.parseInt(obj.toString());
}
else if ((retType.equals(double.class) || retType.equals(Double.class)) && StringUtil.isReal(obj.toString())) {
......
......@@ -35,6 +35,7 @@ import jp.agentec.abook.abv.bl.data.tables.TEnquete;
import jp.agentec.abook.abv.bl.data.tables.TMarkingSetting;
import jp.agentec.abook.abv.bl.data.tables.TOperation;
import jp.agentec.abook.abv.bl.data.tables.TPushMessage;
import jp.agentec.abook.abv.bl.data.tables.TSppDevice;
import jp.agentec.abook.abv.bl.data.tables.TTask;
import jp.agentec.abook.abv.bl.data.tables.TTaskReport;
import jp.agentec.abook.abv.bl.data.tables.TTaskReportItems;
......@@ -95,6 +96,8 @@ public class ABVDataOpenHelper {
iTableScripts.add(new TTaskReportItems());
iTableScripts.add(new TPushMessage());
// SPP通信端末管理テーブルをスクリプトに追加
iTableScripts.add(new TSppDevice());
return iTableScripts;
}
......
......@@ -3,5 +3,6 @@ package jp.agentec.abook.abv.bl.data;
// バージョンが上がるごとに+10すること
public class DatabaseVersions {
public static final int Ver1_0_0 = 1;
public static final int Ver1_0_2 = 11; // SATO HACCP 1.0.2
}
package jp.agentec.abook.abv.bl.data.dao;
import java.util.List;
import jp.agentec.abook.abv.bl.common.db.Cursor;
import jp.agentec.abook.abv.bl.dto.SppDeviceDto;
/**
* SPP通信の端末情報を管理する
*/
public class SppDeviceDao extends AbstractDao {
private static final String TAG = "SppDeviceDao";
@Override
protected SppDeviceDto convert(Cursor cursor) {
SppDeviceDto dto = new SppDeviceDto();
int column = cursor.getColumnIndex("spp_device_id");
if (column != -1) {
dto.sppDeviceId = cursor.getInt(column);
}
column = cursor.getColumnIndex("spp_device_name");
if (column != -1) {
dto.sppDeviceName = cursor.getString(column);
}
column = cursor.getColumnIndex("data_start_index");
if (column != -1) {
dto.dataStartIndex = cursor.getInt(column);
}
column = cursor.getColumnIndex("data_end_index");
if (column != -1) {
dto.dataEndIndex = cursor.getInt(column);
}
column = cursor.getColumnIndex("pairing_device_name");
if (column != -1) {
dto.pairingDeviceName = cursor.getString(column);
}
column = cursor.getColumnIndex("pairing_device_address");
if (column != -1) {
dto.pairingDeviceAddress = cursor.getString(column);
}
return dto;
}
/**
* 登録処理
* @param dto
*/
public void insert(SppDeviceDto dto) {
insert("insert into t_spp_device "
+ "(spp_device_id, "
+ "spp_device_name, "
+ "data_start_index, "
+ "data_end_index, "
+ "pairing_device_name, "
+ "pairing_device_address) "
+ "values "
+ "(?,?,?,?,?,?)",
dto.getInsertValues());
}
/**
* SPP通信端末を全て取得
* @return
*/
public List<SppDeviceDto> getAllSppDevice() {
return rawQueryGetDtoList("SELECT * FROM t_spp_device ORDER BY spp_device_id DESC", null, SppDeviceDto.class);
}
/**
* SPP通信端末をIDで検索
* @param sppDeviceId
* @return
*/
public SppDeviceDto getSppDeviceById(Integer sppDeviceId) {
return rawQueryGetDto("SELECT * FROM t_spp_device WHERE spp_device_id = ?", new String[] { "" + sppDeviceId }, SppDeviceDto.class);
}
/**
* SPP通信端末IDを全て取得
* @return
*/
public List<Integer> getSppDeviceIdList() {
return rawQueryGetIntegerList("SELECT spp_device_id FROM t_spp_device ORDER BY spp_device_id DESC", null);
}
/**
* SPP通信端末でペアリング済みデータ取得
* @return
*/
public List<SppDeviceDto> getPairingDeviceList() {
return rawQueryGetDtoList("SELECT * FROM t_spp_device WHERE pairing_device_name is NOT NULL AND pairing_device_address is NOT NULL order by spp_device_id DESC", null, SppDeviceDto.class);
}
/**
* SPP通信端末の更新処理
* @param dto
* @return
*/
public boolean updateSppDevice(SppDeviceDto dto) {
long count = update("UPDATE t_spp_device SET spp_device_name=?, data_start_index=?, data_end_index=?, pairing_device_name=?, pairing_device_address=? WHERE spp_device_id=?", dto.getUpdateValues());
return count > 0;
}
/**
* ペアリングの端末アドレスがユニーク前提
* ペアリング情報をアドレスで取得
* @param deviceAddress
* @return
*/
public SppDeviceDto getPairingDeviceByAddress(String deviceAddress) {
StringBuffer sql = new StringBuffer();
sql.append(" SELECT DISTINCT * ");
sql.append(" FROM t_spp_device");
sql.append(" WHERE pairing_device_address = ?");
return rawQueryGetDto(sql.toString(), new String[] { deviceAddress }, SppDeviceDto.class);
}
/**
* ペアリング情報をクリアする
* @param deviceAddress
*/
public void clearPairingDevice(String deviceAddress) {
SppDeviceDto sppDeviceDto = getPairingDeviceByAddress(deviceAddress);
// ペアリング情報を空にして更新
sppDeviceDto.pairingDeviceName = null;
sppDeviceDto.pairingDeviceAddress = null;
updateSppDevice(sppDeviceDto);
}
/**
* SPP端末IDでDB情報を削除
* @param sppDeviceId
*/
public void deleteById(Integer sppDeviceId) {
delete("t_spp_device", "spp_device_id=?", new String[] { "" + sppDeviceId });
}
}
package jp.agentec.abook.abv.bl.data.tables;
import java.util.ArrayList;
import java.util.List;
import jp.agentec.abook.abv.bl.common.db.SQLiteDatabase;
import jp.agentec.abook.abv.bl.data.DatabaseVersions;
/**
* CMS側から取得したSPP通信端末を管理するテーブル
*/
public class TSppDevice extends SQLiteTableScript {
public TSppDevice() {
super();
}
@Override
public List<String> getCreateScript(int version) {
List<String> ddl = new ArrayList<String>();
StringBuffer sql = new StringBuffer();
sql.append(" CREATE TABLE t_spp_device ( ");
sql.append(" spp_device_id INTEGER NOT NULL");
sql.append(" , spp_device_name VARCHAR(256) NOT NULL");
sql.append(" , data_start_index INTEGER NOT NULL ");
sql.append(" , data_end_index INTEGER NOT NULL ");
sql.append(" , pairing_device_name VARCHAR(256) ");
sql.append(" , pairing_device_address VARCHAR(256) ");
sql.append(" , PRIMARY KEY (spp_device_id) ");
sql.append(" ) ");
ddl.add(sql.toString());
return ddl;
}
/**
* マイグレーション処理
* @param oldVersion
* @param newVersion
* @return
*/
@Override
public List<String> getUpgradeScript(int oldVersion, int newVersion) {
List<String> ddl = new ArrayList<String>();
if (oldVersion < DatabaseVersions.Ver1_0_2) {
ddl.addAll(getCreateScript(newVersion));
}
return ddl;
}
@Override
public List<String> getMigrationScript(SQLiteDatabase databaseConnection, int oldVersion, int newVersion, Object[] params) {
return null;
}
}
......@@ -19,8 +19,10 @@ import jp.agentec.abook.abv.bl.data.ABVDataCache;
import jp.agentec.abook.abv.bl.data.dao.AbstractDao;
import jp.agentec.abook.abv.bl.data.dao.AcmsDao;
import jp.agentec.abook.abv.bl.data.dao.ContentDao;
import jp.agentec.abook.abv.bl.data.dao.SppDeviceDao;
import jp.agentec.abook.abv.bl.dto.ContentDto;
import jp.agentec.abook.abv.bl.dto.EnqueteDto;
import jp.agentec.abook.abv.bl.dto.SppDeviceDto;
import jp.agentec.abook.abv.bl.logic.AbstractLogic;
import jp.agentec.abook.abv.bl.logic.CategoryLogic;
import jp.agentec.abook.abv.bl.logic.ContentLogic;
......@@ -50,6 +52,8 @@ import jp.agentec.adf.util.DateTimeUtil;
private ContentLogic contentLogic = AbstractLogic.getLogic(ContentLogic.class);
private OperationLogic operationLogic = AbstractLogic.getLogic(OperationLogic.class);
private ContentDao contentDao = AbstractDao.getDao(ContentDao.class);
private SppDeviceDao sppDeviceDao = AbstractDao.getDao(SppDeviceDao.class);
private ABVDataCache cache = ABVDataCache.getInstance();
private ContentDownloader contentDownloader = ContentDownloader.getInstance();
......@@ -287,6 +291,35 @@ import jp.agentec.adf.util.DateTimeUtil;
String fetchDate = json.fetchDate;
ABVEnvironment.getInstance().tempContentVersionLastFetchDate = fetchDate;
// sppDeviceDtoを登録
List<SppDeviceDto> sppDeviceDtoList = json.sppDeviceDtoList;
if (CollectionUtil.isNotEmpty(sppDeviceDtoList)) {
// ローカルに保存されてるIDリストを取得(登録・更新の判定のため)
List<Integer> localSppDeviceIdList = sppDeviceDao.getSppDeviceIdList();
for (SppDeviceDto sppDeviceDto : sppDeviceDtoList) {
if (CollectionUtil.isNotEmpty(localSppDeviceIdList) && localSppDeviceIdList.contains(sppDeviceDto.sppDeviceId)) {
SppDeviceDto localSppDevice = sppDeviceDao.getSppDeviceById(sppDeviceDto.sppDeviceId);
// ペアリング情報だけローカルから取得して、更新する
sppDeviceDto.pairingDeviceName = localSppDevice.pairingDeviceName;
sppDeviceDto.pairingDeviceAddress = localSppDevice.pairingDeviceAddress;
sppDeviceDao.updateSppDevice(sppDeviceDto);
// 削除のため、更新したら該当するIDを削除する
localSppDeviceIdList.remove(localSppDeviceIdList.indexOf(sppDeviceDto.sppDeviceId));
} else {
// 取得したSPP通信端末のデータベースへ登録
sppDeviceDao.insert(sppDeviceDto);
}
}
// ローカル情報削除(サーバーと端末データの差分)
if (CollectionUtil.isNotEmpty(localSppDeviceIdList)) {
for (Integer deleteSppDeviceId : localSppDeviceIdList) {
sppDeviceDao.deleteById(deleteSppDeviceId);
}
}
}
List<ContentDto> serverContents = json.contentVersions;
// DTO Info:contentId, metaVersion, resourceVersion, contentNameKana, readerShareFlg
......
package jp.agentec.abook.abv.bl.dto;
/**
* bluetoothペアリング情報を扱うDto
* デバイス名、デバイスアドレス
*/
public class BluetoothPairingDeviceInfoDto {
/** デバイス名 */
public String deviceName;
/** デバイスアドレス*/
public String deviceAddress;
/** デバイスタイプ*/
public Integer deviceType;
}
package jp.agentec.abook.abv.bl.dto;
/**
* SPP通信の端末情報DTO
*/
public class SppDeviceDto extends AbstractDto {
// SPP通信端末ID
public Integer sppDeviceId;
// SPP通信端末名
public String sppDeviceName;
// 取得したいデータの開始時点
public Integer dataStartIndex;
// 取得したいデータの終了時点
public Integer dataEndIndex;
// ペアリング端末名
public String pairingDeviceName;
// ペアリング端末アドレス
public String pairingDeviceAddress;
@Override
public Object[] getInsertValues() {
return new Object[] { sppDeviceId, sppDeviceName, dataStartIndex, dataEndIndex, pairingDeviceName, pairingDeviceAddress };
}
@Override
public Object[] getUpdateValues() {
return new Object[] { sppDeviceName, dataStartIndex, dataEndIndex, pairingDeviceName, pairingDeviceAddress, sppDeviceId };
}
@Override
public String[] getKeyValues() {
return new String[] { "" + sppDeviceId };
}
}
......@@ -537,7 +537,7 @@ public class StringUtil {
}
}
public static boolean isNumber(String s) {
public static boolean isLongNumber(String s) {
try {
Long.parseLong(s);
return true;
......@@ -546,6 +546,13 @@ public class StringUtil {
}
}
public static boolean isNumber(String num) {
String regex = "^\\-?[0-9]*\\.?[0-9]+$";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(num);
return m.find();
}
public static boolean isReal(String s) {
try {
Double.parseDouble(s);
......
......@@ -21,6 +21,7 @@
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.NFC" />
<!-- GCM -->
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
......@@ -34,6 +35,9 @@
<!-- BLE -->
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
<!-- NFC -->
<uses-feature android:name="android.hardware.nfc" android:required="true"/>
<permission
android:name="${applicationId}.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
......@@ -224,9 +228,13 @@
<activity android:name="jp.agentec.abook.abv.ui.viewer.activity.CheckOZDViewActivity" android:configChanges="orientation|screenSize"/>
<!-- ABookCheck1.0.0 Sato -->
<activity android:name="jp.agentec.abook.abv.ui.home.activity.PairingSettingActivity"
android:theme="@style/AppTheme"/>
<activity android:name="jp.agentec.abook.abv.ui.home.activity.BlePairingSettingActivity"
android:theme="@style/AppTheme"
android:configChanges="keyboardHidden|orientation|screenSize"/>
<activity android:name="jp.agentec.abook.abv.ui.home.activity.BarCodeReaderActivity"
android:theme="@style/AppTheme" android:configChanges="keyboardHidden|orientation|screenSize"/>
android:theme="@style/AppTheme"
android:configChanges="keyboardHidden|orientation|screenSize"/>
<activity android:name="jp.agentec.abook.abv.ui.home.activity.SppBluetoothPairingSettingActivity"
android:theme="@style/AppTheme"/>
</application>
</manifest>
\ No newline at end of file
......@@ -1399,23 +1399,38 @@
<!-- ABookCheck Sato 1.0.0 -->
<string name="set_title_pairing">ペアリング</string>
<string name="set_pairing_central_thermometer">中心温度計</string>
<string name="center_thermometer">中心温度計</string>
<string name="pairing_search_scan">スキャン</string>
<string name="pairing_search_scaning">スキャン中..</string>
<string name="pairing_search_stop">中止</string>
<string name="pairing_save_thermometer">登録された温度計</string>
<string name="pairing_other_thermometer">その他温度計</string>
<string name="pairing_other_thermometer_searching">その他温度計(検索中..)</string>
<string name="ble_connecting">接続中..</string>
<string name="msg_no_device_info">登録された中心温度計情報がありません。\n設定画面のペアリングの中心温度計から登録できます。</string>
<string name="ble_connecting">接続中...</string>
<string name="title_okudake_sensor">おくだけセンサー</string>
<string name="msg_ble_connect_error">登録した中心温度計と接続することができません。中心温度計の電源を確認した後、再度お試しください。(%s)</string>
<string name="msg_ble_connect_success">中心温度計と接続になりました。中心温度計を操作してください。</string>
<string name="msg_scan_bluetooth_no_allow">BlueToothの利用を「許可」しないと、中心温度計のスキャンができません。</string>
<string name="msg_thermometer_connect_bluetooth_no_allow">BlueToothの利用を「許可」しないと、中心温度計と接続できません。</string>
<string name="msg_okudake_connect_bluetooth_no_allow">BlueToothの利用を「許可」しないと、おくだけセンサーと接続できません。</string>
<string name="msg_ble_connect_success">%1$sと接続になりました。%1$sを操作してください。</string>
<string name="msg_scan_bluetooth_no_allow">BlueToothの利用を「許可」しないと、%1$sのスキャンができません。</string>
<string name="msg_connect_bluetooth_no_allow">BlueToothの利用を「許可」しないと、%1$sと接続できません。</string>
<string name="msg_location_device_no_allow">端末の設定から位置情報をONにしてください。</string>
<string name="bluetooth_is_not_supported">Bluetooth機能が利用できない端末です。</string>
<string name="barcode">コードリーダー</string>
<!-- ABookCheck Sato 1.0.2 -->
<string name="chino_machine">CHINO機器</string>
<string name="spp_machine">SPP通信機器</string>
<string name="radiation_thermometer">放射温度計</string>
<string name="pairing_save_machine">登録された%s</string>
<string name="pairing_other_machine">その他%s</string>
<string name="pairing_other_machine_searching">その他%s(検索中...)</string>
<string name="msg_bluetooth_connect_error">登録した%1$sと接続することができません。%1$sの電源を確認した後、再度お試しください。</string>
<string name="msg_bluetooth_receive_data_error">%1$sのデータ取得に失敗しました。</string>
<string name="msg_pairing_device_no_info">登録された%s情報がありません。\n設定画面のペアリング設定から登録できます。</string>
<string name="msg_not_found_parameter">パラメータが存在しません。</string>
<string name="msg_fraud_parameter">パラメータに数値以外の文字列が含まれています。</string>
<string name="msg_okudake_fraud_parameter">おくだけセンサーのパラメータに数値以外の文字列が含まれています。</string>
<string name="nfc_communication">NFC通信</string>
<string name="msg_hold_nfc_device">NFC機器をかざしてください。</string>
<string name="msg_nfc_value_error">NFC通信でエラーが発生しました。(%s)</string>
<string name="msg_no_support_nfc">NFC機能が利用できない端末です。</string>
<string name="msg_no_nfc_setting">端末の設定からNFCを有効にする必要があります。\n端末の設定画面へ遷移しますか?</string>
<string name="select_spp_device_title">機器選択</string>
</resources>
......@@ -1407,23 +1407,36 @@
<!-- ABookCheck Sato 1.0.0 -->
<string name="set_title_pairing">패어링</string>
<string name="set_pairing_central_thermometer">중심 온도계</string>
<string name="center_thermometer">중심 온도계</string>
<string name="pairing_search_scan">스캔</string>
<string name="pairing_search_scaning">스캔중..</string>
<string name="pairing_search_stop">중지</string>
<string name="pairing_save_thermometer">등록된 온도계</string>
<string name="pairing_other_thermometer">그 밖에 온도계</string>
<string name="pairing_other_thermometer_searching">그 밖에 온도계(검색중..)</string>
<string name="ble_connecting">접속 시도 중..</string>
<string name="msg_no_device_info">등록된 중심 온도계 정보가 없습니다.\n 설정 화면의 페어링의 중심 온도계에서 등록 가능합니다.</string>
<string name="ble_connecting">접속 시도 중...</string>
<string name="title_okudake_sensor">오쿠다케 센서</string>
<string name="msg_ble_connect_error">등록한 중심 온도계와 연결 할 수 없습니다. 중심 온도계의 전원을 확인후 다시 시도해 주시기 바랍니다.(%s)</string>
<string name="msg_ble_connect_success">중심 온도계와 연결되었습니다. 중심 온도계를 조작 해 주세요.</string>
<string name="msg_scan_bluetooth_no_allow">블루투스 사용를 [허용] 하지 않으면, 중심 온도계 스캔이 불가능 합니다. </string>
<string name="msg_thermometer_connect_bluetooth_no_allow">블루투스 사용를 [허용] 하지 않으면, 중심 온도계와 연결이 불가능 합니다.</string>
<string name="msg_okudake_connect_bluetooth_no_allow">블루투스 사용를 [허용] 하지 않으면, 오쿠다케 센서와 연결이 불가능 합니다.</string>
<string name="msg_ble_connect_success">%1$s와 연결되었습니다. %1$s를 조작 해 주세요.</string>
<string name="msg_scan_bluetooth_no_allow">블루투스 사용를 [허용] 하지 않으면, %1$s 스캔이 불가능 합니다. </string>
<string name="msg_connect_bluetooth_no_allow">블루투스 사용를 [허용] 하지 않으면, %1$s와 연결이 불가능 합니다.</string>
<string name="msg_location_device_no_allow">단말기의 설정에서 위치정보를 ON으로 설정해 주세요.</string>
<string name="bluetooth_is_not_supported">블루투스는 지원되지 않습니다.</string>
<string name="barcode">코드 리더</string>
<string name="msg_okudake_fraud_parameter">오쿠다케 센서의 파라미터에 숫자가 아닌 문자열이 포합되어 있습니다.</string>
<!-- ABookCheck Sato 1.0.2 -->
<string name="chino_machine">CHINO機器</string>
<string name="spp_machine">SPP通信機器</string>
<string name="radiation_thermometer">放射温度計</string>
<string name="pairing_save_machine">등록된 %s</string>
<string name="pairing_other_machine">그 밖에 %s</string>
<string name="pairing_other_machine_searching">그 밖에 %s(검색중...)</string>
<string name="msg_bluetooth_connect_error">登録した%1$sと接続することができません。%1$sの電源を確認した後、再度お試しください。</string>
<string name="msg_bluetooth_receive_data_error">%1$sのデータ取得に失敗しました。</string>
<string name="msg_pairing_device_no_info">登録された%s情報がありません。\n設定画面のペアリング設定から登録できます。</string>
<string name="msg_not_found_parameter">파라미터가 존재하지 않습니다.</string>
<string name="msg_fraud_parameter">파라미터에 숫자가 아닌 문자열이 포합되어 있습니다.</string>
<string name="msg_okudake_fraud_parameter">おくだけセンサーのパラメータに数値以外の文字列が含まれています。</string>
<string name="nfc_communication">NFC通信</string>
<string name="msg_hold_nfc_device">NFC機器をかざしてください。</string>
<string name="msg_nfc_value_error">NFC通信でエラーが発生しました。(%s)</string>
<string name="msg_no_support_nfc">NFC機能が利用できない端末です。</string>
<string name="msg_no_nfc_setting">端末の設定からNFCを有効にする必要があります。\n端末の設定画面へ遷移しますか?</string>
<string name="select_spp_device_title">機器選択</string>
</resources>
\ No newline at end of file
......@@ -1405,24 +1405,37 @@
<!-- ABookCheck Sato 1.0.0 -->
<string name="set_title_pairing">Pairing</string>
<string name="set_pairing_central_thermometer">Central thermometer</string>
<string name="center_thermometer">Central thermometer</string>
<string name="pairing_search_scan">Scan</string>
<string name="pairing_search_scaning">Scaning..</string>
<string name="pairing_search_scaning">Scaning...</string>
<string name="pairing_search_stop">Stop</string>
<string name="pairing_save_thermometer">Saved thermometer</string>
<string name="pairing_other_thermometer">Other thermometer</string>
<string name="pairing_other_thermometer_searching">Other thermometer(Searching..)</string>
<string name="ble_connecting">Connection..</string>
<string name="msg_no_device_info">There is no registered central thermometer information. \n You can register in the center thermometer of the pairing of setting screen.</string>
<string name="ble_connecting">Connection...</string>
<string name="title_okudake_sensor">OKUDAKE SENSOR</string>
<string name="msg_ble_connect_error">You can not connect to the registered center thermometer. Check the power supply of the central thermometer and try again.(%s)</string>
<string name="msg_ble_connect_success">Connected with the center thermometer. Please control the central thermometer.</string>
<string name="msg_scan_bluetooth_no_allow">If Bluetooth is not allow, the center thermometer scan is disabled.</string>
<string name="msg_thermometer_connect_bluetooth_no_allow">If Bluetooth is not allow, the center thermometer connect is disabled.</string>
<string name="msg_okudake_connect_bluetooth_no_allow">If Bluetooth is not allow, the center okudake sensor connect is disabled.</string>
<string name="msg_ble_connect_success">Connected with %1$s. Please control %1$s.</string>
<string name="msg_scan_bluetooth_no_allow">If Bluetooth is not allow, %1$s scan is disabled.</string>
<string name="msg_connect_bluetooth_no_allow">If Bluetooth is not allow, %1$s connect is disabled.</string>
<string name="msg_location_device_no_allow">Please set the location information to ON in the device setting.</string>
<string name="bluetooth_is_not_supported">Bluetooth is not supported.</string>
<string name="barcode">Code Reader</string>
<string name="msg_okudake_fraud_parameter">The okudake sensor parameter contains a non-numeric string.</string>
<!-- ABookCheck Sato 1.0.2 -->
<string name="chino_machine">CHINO機器</string>
<string name="spp_machine">SPP通信機器</string>
<string name="radiation_thermometer">放射温度計</string>
<string name="pairing_save_machine">Saved %s</string>
<string name="pairing_other_machine">Other %s</string>
<string name="pairing_other_machine_searching">Other %s(Searching...)</string>
<string name="msg_bluetooth_connect_error">登録した%1$sと接続することができません。%1$sの電源を確認した後、再度お試しください。</string>
<string name="msg_bluetooth_receive_data_error">%1$sのデータ取得に失敗しました。</string>
<string name="msg_pairing_device_no_info">登録された%s情報がありません。\n設定画面のペアリング設定から登録できます。</string>
<string name="msg_not_found_parameter">パラメータが存在しません。</string>
<string name="msg_fraud_parameter">The parameter contains a non-numeric string.</string>
<string name="msg_okudake_fraud_parameter">おくだけセンサーのパラメータに数値以外の文字列が含まれています。</string>
<string name="nfc_communication">NFC通信</string>
<string name="msg_hold_nfc_device">NFC機器をかざしてください。</string>
<string name="msg_nfc_value_error">NFC通信でエラーが発生しました。(%s)</string>
<string name="msg_no_support_nfc">NFC機能が利用できない端末です。</string>
<string name="msg_no_nfc_setting">端末の設定からNFCを有効にする必要があります。\n端末の設定画面へ遷移しますか?</string>
<string name="select_spp_device_title">機器選択</string>
</resources>
\ No newline at end of file
......@@ -13,6 +13,7 @@
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
......
......@@ -2,7 +2,7 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:orientation="horizontal"
......@@ -10,7 +10,7 @@
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_height="50dp"
android:orientation="vertical"
android:gravity="left|center_vertical"
android:layout_weight="1">
......@@ -18,7 +18,7 @@
<TextView
android:id="@+id/bl_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_height="match_parent"
android:ellipsize="end"
android:maxLines="1"
android:maxWidth="250dp"
......@@ -29,11 +29,22 @@
</LinearLayout>
<TextView
android:id="@+id/sub_title"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="right|center_vertical"
android:ellipsize="end"
android:maxLines="1"
android:text="SubTitle"
android:visibility="visible" />
<Button
android:id="@+id/bl_deleteBtn"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="right|center_vertical"
android:layout_marginTop="2dp"
android:text="@string/delete" />
android:text="@string/delete"
android:visibility="gone" />
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/operation_bg"
android:minWidth="500dp"
android:minHeight="300dp"
android:orientation="vertical">
<RelativeLayout
android:id="@+id/toolbar_layout"
style="@style/OperationSearchToolBar"
android:layout_width="match_parent"
android:layout_height="50dp">
<TextView
android:id="@+id/title"
style="@style/DialogToolBarTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="@string/select_spp_device_title"
android:textColor="@color/edt_text"
android:textSize="@dimen/opeartion_title_text_size" />
<Button
android:id="@+id/closeBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:background="@drawable/ic_operation_close"
android:contentDescription="@string/cont_desc" />
</RelativeLayout>
<ListView
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/item_spp_device_select"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/spp_device_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:minHeight="20dp"
android:padding="10dp"
android:text="@string/dummy_str"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/text_select" />
<ImageView
android:id="@+id/nextLevel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_gravity="center"
android:src="@drawable/ic_navigation_next_item"
android:visibility="visible" />
</LinearLayout>
<View
android:layout_width="fill_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray" />
</LinearLayout>
\ No newline at end of file
......@@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="jp.agentec.abook.abv.ui.home.activity.PairingSettingActivity">
tools:context="jp.agentec.abook.abv.ui.home.activity.BlePairingSettingActivity">
<!--android:background="@drawable/setting_bg"-->
<!--android:layout_height="0dp"-->
<!--android:background="@drawable/setting_bg"-->
......
......@@ -60,8 +60,12 @@
</PreferenceCategory>
<PreferenceCategory android:title="@string/set_title_pairing" android:key="set_pairing">
<PreferenceScreen
android:key="setPairing"
android:title="@string/set_pairing_central_thermometer" >
android:key="setChinoPairing"
android:title="@string/chino_machine" >
</PreferenceScreen>
<PreferenceScreen
android:key="setSppPairing"
android:title="@string/spp_machine" >
</PreferenceScreen>
</PreferenceCategory>
</PreferenceScreen>
\ No newline at end of file
......@@ -18,8 +18,10 @@ import java.nio.ByteOrder;
import java.util.List;
import java.util.UUID;
import jp.agentec.abook.abv.bl.common.Constant.DeviceType;
import jp.agentec.abook.abv.bl.common.log.Logger;
import jp.agentec.abook.abv.launcher.android.R;
import jp.agentec.adf.util.StringUtil;
import static android.bluetooth.BluetoothDevice.TRANSPORT_LE;
import static org.chromium.base.ThreadUtils.runOnUiThread;
......@@ -33,22 +35,21 @@ public class BleManagerUtil {
// 定数(Bluetooth LE Gatt UUID)
// Private Service
private static final UUID UUID_SERVICE_PRIVATE = UUID.fromString("05fd8c58-9d23-11e7-abc4-cec278b6b50a");
private static final UUID UUID_CHARACTERISTIC_PRIVATE1 = UUID.fromString("05fd8f5a-9d23-11e7-abc4-cec278b6b50a");
private static final UUID UUID_CHARACTERISTIC_PRIVATE2 = UUID.fromString("05fd8f5a-9d23-11e7-abc4-cec278b6b50a");
private UUID UUID_SERVICE_PRIVATE;
private UUID UUID_CHARACTERISTIC_PRIVATE;
// for Notification
private static final UUID UUID_NOTIFY = UUID.fromString("05fd8f5a-9d23-11e7-abc4-cec278b6b50a");
private static final UUID UUID_NOTIRY_DESCRIPTOR = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");
// battery
private static final UUID UUID_BATTERY_LEVEL = UUID.fromString("00002A19-0000-1000-8000-00805f9b34fb");
private UUID UUID_NOTIFY;
// メンバー変数
public BluetoothAdapter mBluetoothAdapter; // BluetoothAdapter : Bluetooth処理で必要
public String mDeviceAddress = ""; // デバイスアドレス
public String mDeviceName = ""; // ディバイス名
public BluetoothGatt mBluetoothGatt = null; // Gattサービスの検索、キャラスタリスティックの読み書き
public BluetoothGatt mBluetoothGatt = null; // Gattサービスの検索、キャラスタリスティックの読み書き
private int mBleConnectDeviceType;
public BleManagerUtil(Context context, BleManagerUtilListener listener) {
this.context = context;
this.listener = listener;
}
// BluetoothGattコールバック
private final BluetoothGattCallback mGattcallback = new BluetoothGattCallback() {
......@@ -56,19 +57,12 @@ public class BleManagerUtil {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState ) {
super.onConnectionStateChange(gatt, status, newState);
// if( BluetoothGatt.GATT_SUCCESS != status ) {
// runOnUiThread( new Runnable() {
// public void run() {
// listener.onGetDeviceInfoFailed();
// }
// });
// return;
// }
final int fStatus = status;
// デバイスと接続されていない場合のメッセージコード:133, 62
// デバイスと接続が切れた場合のメッセージコード:19
// デバイスと接続されていない場合のメッセージコード:133, 62
// デバイスと接続が切れた場合のメッセージコード:19
if (status == 133 || status == 62) { // 接続失敗
runOnUiThread( new Runnable() {
@Override
public void run() {
Logger.e("onConnectionStateChange status = " + fStatus);
listener.onConnectionError(fStatus);
......@@ -82,6 +76,7 @@ public class BleManagerUtil {
if (!mBluetoothGatt.discoverServices()) { // サービス検索
runOnUiThread( new Runnable() { // 接続失敗
@Override
public void run() {
listener.onGetDeviceInfoFailed(fStatus);
Logger.e("onConnectionStateChange2 status = " + fStatus);
......@@ -89,6 +84,7 @@ public class BleManagerUtil {
});
}
runOnUiThread( new Runnable() {
@Override
public void run() {
// 接続成功
listener.onConnectionState();
......@@ -98,9 +94,6 @@ public class BleManagerUtil {
}
if( BluetoothProfile.STATE_DISCONNECTED == newState ) { // 切断完了(接続可能範囲から外れて切断された)
// 接続可能範囲に入ったら自動接続することが必要場合、mBluetoothGatt.connect()を呼び出す。
// mBluetoothGatt.connect();
// 切断が発生する場合、Bluetoothと接続を切断する。
disconnect();
return;
......@@ -117,7 +110,7 @@ public class BleManagerUtil {
// 発見されたサービスのループ
for( BluetoothGattService service : gatt.getServices() ) {
// サービスごとに個別の処理
if( ( null == service ) || ( null == service.getUuid() ) ) {
if((service == null) || (service.getUuid() == null)) {
continue;
}
......@@ -131,13 +124,8 @@ public class BleManagerUtil {
// プライベートサービス
if( UUID_SERVICE_PRIVATE.equals( service.getUuid() ) ) {
// 最初の読み取り
readCharacteristic(UUID_SERVICE_PRIVATE, UUID_CHARACTERISTIC_PRIVATE1);
readCharacteristic(UUID_SERVICE_PRIVATE, UUID_CHARACTERISTIC_PRIVATE);
runOnUiThread( new Runnable() {
public void run() {
// 渡すデータがある場合
}
});
continue;
}
}
......@@ -149,10 +137,11 @@ public class BleManagerUtil {
if( BluetoothGatt.GATT_SUCCESS != status ) {
return;
}
if( UUID_CHARACTERISTIC_PRIVATE1.equals( characteristic.getUuid() ) ) {
if( UUID_CHARACTERISTIC_PRIVATE.equals(characteristic.getUuid())) {
final String strTemperature = byteToString(characteristic.getValue());
runOnUiThread( new Runnable() {
@Override
public void run() {
// 芯温計の温度を渡す。
// 端末と接続時に呼ばれるのでコメント処理
......@@ -161,7 +150,7 @@ public class BleManagerUtil {
});
// 通知設定
setCharacteristicNotification(UUID_SERVICE_PRIVATE, UUID_NOTIFY, true);
setCharacteristicNotification(UUID_SERVICE_PRIVATE, UUID_CHARACTERISTIC_PRIVATE, true);
return;
}
}
......@@ -169,7 +158,7 @@ public class BleManagerUtil {
// キャラクタリスティック変更が通知されたときの処理
@Override
public void onCharacteristicChanged( BluetoothGatt gatt, BluetoothGattCharacteristic characteristic ) {
if( UUID_NOTIFY.equals( characteristic.getUuid() ) ) {
if( UUID_CHARACTERISTIC_PRIVATE.equals( characteristic.getUuid() ) ) {
final String strTemperature = byteToString(characteristic.getValue());
runOnUiThread( new Runnable() {
......@@ -188,9 +177,12 @@ public class BleManagerUtil {
}
};
public BleManagerUtil(Context context, BleManagerUtilListener listener) {
this.context = context;
this.listener = listener;
/**
* 接続してるデバイスタイプを取得
* @return
*/
public int getBluetoothDeviceType() {
return mBleConnectDeviceType;
}
/**
......@@ -206,18 +198,25 @@ public class BleManagerUtil {
void onConnectionError(int status); // ディバイス接続エラー
}
// 接続
public void connect() {
if( mDeviceAddress.equals( "" ) ) { // DeviceAddressが空の場合は処理しない
/**
* 接続
* @param connectTargetDeviceType bluetoothDeviceType 接続するデバイスタイプ
* @param deviceAddress デバイスアドレス
*/
public void connect(int connectTargetDeviceType, String deviceAddress) {
// デバイスタイプセット
mBleConnectDeviceType = connectTargetDeviceType;
setUUID();
if(StringUtil.isNullOrEmpty(deviceAddress)) { // deviceAddressが空の場合は処理しない
return;
}
if( null != mBluetoothGatt ) { // mBluetoothGattがnullでないなら接続済みか、接続中。
if(mBluetoothGatt != null) { // mBluetoothGattがnullでないなら接続済みか、接続中。
return;
}
// mBluetoothGattのサービスと接続
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice( mDeviceAddress );
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice( deviceAddress );
// GATT BLEを利用する時Androidのバージョン「23」をチェックしてGATTと接続する。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
......@@ -225,12 +224,11 @@ public class BleManagerUtil {
} else {
mBluetoothGatt = device.connectGatt( context, false, mGattcallback );
}
}
// 切断
public void disconnect() {
if( null == mBluetoothGatt ) {
if( mBluetoothGatt == null ) {
return;
}
......@@ -245,6 +243,7 @@ public class BleManagerUtil {
mBluetoothGatt = null;
runOnUiThread( new Runnable() {
@Override
public void run() {
// 切断トーストメッセージを表示する。
listener.onDisConnectionState();
......@@ -275,7 +274,7 @@ public class BleManagerUtil {
BluetoothGattCharacteristic blechar = service.getCharacteristic( uuid_characteristic );
mBluetoothGatt.setCharacteristicNotification( blechar, enable );
BluetoothGattDescriptor descriptor = blechar.getDescriptor(UUID_NOTIRY_DESCRIPTOR);
BluetoothGattDescriptor descriptor = blechar.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));
descriptor.setValue( BluetoothGattDescriptor.ENABLE_INDICATION_VALUE );
mBluetoothGatt.writeDescriptor(descriptor);
}
......@@ -292,10 +291,27 @@ public class BleManagerUtil {
public void startDeviceInfo() {
// Bluetoothアダプタの取得
BluetoothManager bluetoothManager = (BluetoothManager) context.getSystemService( Context.BLUETOOTH_SERVICE );
mBluetoothAdapter = bluetoothManager.getAdapter();
if( null == mBluetoothAdapter ) { // Android端末がBluetoothをサポートしていない
Toast.makeText( context, R.string.bluetooth_is_not_supported, Toast.LENGTH_SHORT ).show();
return;
if (bluetoothManager != null) {
mBluetoothAdapter = bluetoothManager.getAdapter();
if( mBluetoothAdapter == null ) { // Android端末がBluetoothをサポートしていない
Toast.makeText( context, R.string.bluetooth_is_not_supported, Toast.LENGTH_SHORT ).show();
return;
}
} else {
Logger.e(TAG, "bluetoothManager is null");
}
}
// UUIDセット
private void setUUID() {
if (mBleConnectDeviceType == DeviceType.centerThermomete) {
// 中心温度計のUUIDセット
UUID_SERVICE_PRIVATE = UUID.fromString("05fd8c58-9d23-11e7-abc4-cec278b6b50a");
UUID_CHARACTERISTIC_PRIVATE = UUID.fromString("05fd8f5a-9d23-11e7-abc4-cec278b6b50a");
} else if (mBleConnectDeviceType == DeviceType.radiationThermomete) {
// 放射温度計のUUIDセット
UUID_SERVICE_PRIVATE = UUID.fromString("462026f6-cfe1-11e7-abc4-cec278b6b50a");
UUID_CHARACTERISTIC_PRIVATE = UUID.fromString("46202b74-cfe1-11e7-abc4-cec278b6b50a");
}
}
}
package jp.agentec.abook.abv.cl.util;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import java.io.IOException;
import java.util.UUID;
import jp.agentec.abook.abv.bl.common.log.Logger;
/**
* SPP通信のbluetoothの接続スレッド
*/
public class SppBluetoothConnectThread extends Thread {
protected String TAG = "SppBluetoothConnectThread";
// "00001101-0000-1000-8000-00805f9b34fb" = SPP (シリアルポートプロファイル) の UUID.
public static final UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
private BluetoothSocket mSocket;
private bluetoothConnectThreadListener mListener;
private BluetoothDevice mBluetoothDevice;
public interface bluetoothConnectThreadListener {
void onConnect(BluetoothSocket socket); // 接続リスナ
void onFail();
}
public SppBluetoothConnectThread(BluetoothDevice device, bluetoothConnectThreadListener listener) {
mListener = listener;
mBluetoothDevice = device;
try {
mSocket = device.createRfcommSocketToServiceRecord(SPP_UUID);
} catch (IOException e) {
Logger.e(TAG, e);
}
}
@Override
public void run() {
if (mSocket == null) {
Logger.e(TAG, "socket is null");
return;
}
try {
mSocket.connect();
} catch (IOException e) {
Logger.e(TAG, e);
try {
if (mSocket == null) {
return;
}
mSocket.close();
} catch (IOException e1) {
Logger.e(TAG, e);
}
mListener.onFail();
return;
}
mListener.onConnect(mSocket);
Logger.i(TAG, "Bluetooth connecting.");
}
public boolean isConnecting() {
return mSocket.isConnected();
}
/**
* ソケットを初期化する
*/
public void finish() {
if (mSocket == null) {
return;
}
try {
mSocket.close();
} catch (IOException e) {
Logger.e(TAG, e);
}
mSocket = null;
}
public String getConnectedAddress() {
if (mBluetoothDevice == null) {
return null;
}
return mBluetoothDevice.getAddress();
}
}
\ No newline at end of file
package jp.agentec.abook.abv.cl.util;
import android.bluetooth.BluetoothSocket;
import java.io.IOException;
import java.io.InputStream;
import jp.agentec.abook.abv.bl.common.log.Logger;
import jp.agentec.abook.abv.bl.dto.SppDeviceDto;
/**
* 大和機器のbluetooth通信でデータを受け取るスレッド
*/
public class YamatoBluetoothReceiveTask extends Thread {
public static final String TAG = "YamatoBluetoothReceiveTask";
private InputStream mInputStream;
private BluetoothSocket mSocket;
private SppDeviceDto mSppDeviceDto;
private static final int STX = 2;
private static final int ETX = 3;
private BluetoothReceiveTaskListener mListener;
public interface BluetoothReceiveTaskListener {
void onGetData(String result); // 値取得時のリスナ
void onFail(boolean dataFormatErrorFlg); // 失敗リスナ
}
public YamatoBluetoothReceiveTask(BluetoothSocket socket, SppDeviceDto sppDeviceDto, BluetoothReceiveTaskListener listener) {
mSocket = null;
mInputStream = null;
mSppDeviceDto = sppDeviceDto;
mListener = listener;
if (socket == null) {
Logger.e(TAG, "parameter socket is null.");
mListener.onFail(false);
return;
}
try {
mSocket = socket;
mInputStream = socket.getInputStream();
} catch (IOException e) {
Logger.e(TAG, e);
mListener.onFail(false);
return;
}
}
@Override
public void run() {
Logger.i(TAG, "bluetoothReciveTask run");
byte[] buffer = new byte[1024];
int readSize = 0;
while (mInputStream != null) {
Logger.i(TAG, "start read mInputStream.");
if (mSocket == null) {
Logger.e(TAG, "mSocket is null.");
break;
}
try {
readSize = mInputStream.read(buffer);
String str = new String(buffer, 0, readSize);
Logger.i(TAG, "getData : " + str);
if (str.indexOf(new Character((char) STX).toString()) != -1 && str.indexOf(new Character((char) ETX).toString()) != -1) {
String dataStr = str.substring(str.indexOf(new Character((char) STX).toString()) + 1, str.indexOf(new Character((char) ETX).toString()));
Logger.i(TAG, "convert data : " + dataStr);
String result = dataStr.substring(mSppDeviceDto.dataStartIndex - 1, mSppDeviceDto.dataEndIndex - 1).replaceAll(" ", "");
mListener.onGetData(result);
}
Thread.sleep(500);
} catch (IndexOutOfBoundsException e) {
Logger.e(TAG, e);
mListener.onFail(true);
break;
} catch (Exception e) {
Logger.e(TAG, e);
mListener.onFail(false);
break;
}
}
Logger.i(TAG, "exit read task.");
}
/**
* ソケットを初期化処理
*/
public void finish() {
if (mSocket == null) {
return;
}
try {
mSocket.close();
mSocket = null;
} catch (IOException e) {
Logger.e(TAG, e);
}
}
}
\ No newline at end of file
......@@ -2,8 +2,10 @@ package jp.agentec.abook.abv.launcher.android;
import java.util.ArrayList;
import jp.agentec.abook.abv.bl.common.Constant.DeviceType;
import jp.agentec.abook.abv.bl.common.Constant.ReportType;
import jp.agentec.abook.abv.bl.common.log.Logger;
import jp.agentec.abook.abv.bl.dto.BluetoothPairingDeviceInfoDto;
import jp.agentec.abook.abv.cl.util.PreferenceUtil;
import jp.agentec.abook.abv.ui.common.appinfo.AppDefType;
import jp.agentec.abook.abv.ui.common.appinfo.AppDefType.DefPrefKey;
......@@ -111,6 +113,10 @@ public class ABVUIDataCache {
}
}
/**
* フィルターのタイプIDの値セット
* @param operationReportTypes
*/
public void setOperationReportTypes(ArrayList<Integer> operationReportTypes) {
this.mReportTypes = operationReportTypes;
String val = null;
......@@ -126,6 +132,10 @@ public class ABVUIDataCache {
PreferenceUtil.putUserPref(context, UserPrefKey.OPERATION_REPORT_TYPES, val);
}
/**
* フィルターID情報リスト取得
* @return フィルター用のタイプIDリスト
*/
public ArrayList<Integer> getOperationReportTypes() {
String operationReportTypesStr = PreferenceUtil.getUserPref(context, UserPrefKey.OPERATION_REPORT_TYPES, null);
......@@ -147,4 +157,111 @@ public class ABVUIDataCache {
return mReportTypes;
}
/**
* アプリ内で保存されてるbluetoothのペアリング情報の
* BluetoothPairingDeviceInfoDtoで返す。
*
* 情報が存在しない場合はnullで返す。
*
* @param bluetoothDeviceType 取得するbluetoothのデバイスタイプ
* @return BluetoothPairingDeviceInfoDto ペアリング情報
*/
public BluetoothPairingDeviceInfoDto getPairingBluetoothDeviceInfo(int bluetoothDeviceType) {
BluetoothPairingDeviceInfoDto dto = new BluetoothPairingDeviceInfoDto();
String deviceName = null;
String deviceAddress = null;
if (bluetoothDeviceType == DeviceType.centerThermomete) {
// 中心温度計
deviceName = PreferenceUtil.getUserPref(context, UserPrefKey.BLE_DEVICE_CENTER_TEMPERATURE_NAME, "");
deviceAddress = PreferenceUtil.getUserPref(context, UserPrefKey.BLE_DEVICE_CENTER_TEMPERATURE_ADDRESS, "");
} else if (bluetoothDeviceType == DeviceType.radiationThermomete) {
// 放射温度計
deviceName = PreferenceUtil.getUserPref(context, UserPrefKey.BLE_DEVICE_RADIATION_TEMPERATURE_NAME, "");
deviceAddress = PreferenceUtil.getUserPref(context, UserPrefKey.BLE_DEVICE_RADIATION_TEMPERATURE_ADDRESS, "");
}
// deviceNameとdeviceAddressがセットなので、どっちかの値が存在しないとnullで返す。
if (StringUtil.isNullOrEmpty(deviceName) || StringUtil.isNullOrEmpty(deviceAddress)) {
return null;
}
dto.deviceName = deviceName;
dto.deviceAddress = deviceAddress;
dto.deviceType = bluetoothDeviceType;
return dto;
}
/**
* 引数のデバイスタイプでローカルに保存されてるbluetoothのデバイスアドレス取得
* @param bluetoothDeviceType
* @return
*/
public String getPairingBluetoothDeviceAddress(int bluetoothDeviceType) {
String deviceAddressKey = null;
if (bluetoothDeviceType == DeviceType.centerThermomete) {
deviceAddressKey = UserPrefKey.BLE_DEVICE_CENTER_TEMPERATURE_ADDRESS;
} else if (bluetoothDeviceType == DeviceType.radiationThermomete) {
deviceAddressKey = UserPrefKey.BLE_DEVICE_RADIATION_TEMPERATURE_ADDRESS;
}
if (deviceAddressKey == null) {
// 引数のデバイスタイプが定義した以外の値が入った場合
return null;
}
return PreferenceUtil.getUserPref(context, deviceAddressKey, "");
}
/**
* 引数であるデバイスタイプリストに対するアプリ内で保存されてる
* bluetoothのペアリング情報リストを返す。
* @param deviceTypeList
* @return List<BluetoothPairingDeviceInfoDto> ペアリング情報リスト
*/
public List<BluetoothPairingDeviceInfoDto> getPairingBluetoothDeviceInfoList(List<Integer> deviceTypeList) {
List<BluetoothPairingDeviceInfoDto> bluetoothPairingDeviceInfoDtoList = new ArrayList<BluetoothPairingDeviceInfoDto>();
for (Integer deviceType : deviceTypeList) {
// 引数のデバイスタイプのリスト全部を1つずつデータ取得
BluetoothPairingDeviceInfoDto dto = getPairingBluetoothDeviceInfo(deviceType);
if (dto != null) {
// dtoがnullではない場合のみリストに追加
bluetoothPairingDeviceInfoDtoList.add(dto);
}
}
return bluetoothPairingDeviceInfoDtoList;
}
/**
* ペアリング情報をローカルに保存する
* deviceType毎に保存するキーが異なる
* @param pairingDeviceInfoDto
*/
public void setPairingBluetoothDeviceInfo(BluetoothPairingDeviceInfoDto pairingDeviceInfoDto) {
if (pairingDeviceInfoDto.deviceType.equals(DeviceType.centerThermomete)) {
// 中心温度計
PreferenceUtil.putUserPref(context, UserPrefKey.BLE_DEVICE_CENTER_TEMPERATURE_NAME, pairingDeviceInfoDto.deviceName);
PreferenceUtil.putUserPref(context, UserPrefKey.BLE_DEVICE_CENTER_TEMPERATURE_ADDRESS, pairingDeviceInfoDto.deviceAddress);
} else if (pairingDeviceInfoDto.deviceType.equals(DeviceType.radiationThermomete)) {
// 放射温度計
PreferenceUtil.putUserPref(context, UserPrefKey.BLE_DEVICE_RADIATION_TEMPERATURE_NAME, pairingDeviceInfoDto.deviceName);
PreferenceUtil.putUserPref(context, UserPrefKey.BLE_DEVICE_RADIATION_TEMPERATURE_ADDRESS, pairingDeviceInfoDto.deviceAddress);
}
}
/**
* 引数であるデバイスタイプの
* ペアリング情報を削除する
* @param deviceType
*/
public void removePairingBluetoothDeviceInfo(int deviceType) {
if (deviceType == DeviceType.centerThermomete) {
// 中心温度計
PreferenceUtil.removeUserPref(context, UserPrefKey.BLE_DEVICE_CENTER_TEMPERATURE_NAME);
PreferenceUtil.removeUserPref(context, UserPrefKey.BLE_DEVICE_CENTER_TEMPERATURE_ADDRESS);
} else if (deviceType == DeviceType.radiationThermomete) {
// 放射温度計
PreferenceUtil.removeUserPref(context, UserPrefKey.BLE_DEVICE_RADIATION_TEMPERATURE_NAME);
PreferenceUtil.removeUserPref(context, UserPrefKey.BLE_DEVICE_RADIATION_TEMPERATURE_ADDRESS);
}
}
}
package jp.agentec.abook.abv.ui.common.activity;
import android.app.Activity;
import android.app.PendingIntent;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
......@@ -9,10 +12,12 @@ import android.content.res.AssetFileDescriptor;
import android.location.LocationManager;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.nfc.NdefMessage;
import android.nfc.NfcAdapter;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcelable;
import android.provider.Settings;
import android.widget.Toast;
import com.nttdocomo.android.sdaiflib.BeaconData;
import com.nttdocomo.android.sdaiflib.BeaconReceiverBase;
......@@ -22,22 +27,31 @@ import com.nttdocomo.android.sdaiflib.Define;
import org.json.adf.JSONObject;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import jp.agentec.abook.abv.bl.common.Constant;
import jp.agentec.abook.abv.bl.common.CommonExecutor;
import jp.agentec.abook.abv.bl.common.Constant.ABookPermissionType;
import jp.agentec.abook.abv.bl.common.constant.ABookKeys;
import jp.agentec.abook.abv.bl.common.Constant.DeviceType;
import jp.agentec.abook.abv.bl.common.log.Logger;
import jp.agentec.abook.abv.bl.data.dao.AbstractDao;
import jp.agentec.abook.abv.bl.data.dao.SppDeviceDao;
import jp.agentec.abook.abv.bl.dto.SppDeviceDto;
import jp.agentec.abook.abv.cl.util.BleManagerUtil;
import jp.agentec.abook.abv.cl.util.SppBluetoothConnectThread;
import jp.agentec.abook.abv.cl.util.YamatoBluetoothReceiveTask;
import jp.agentec.abook.abv.launcher.android.R;
import jp.agentec.abook.abv.ui.common.appinfo.AppDefType;
import jp.agentec.abook.abv.ui.common.dialog.ABookAlertDialog;
import jp.agentec.abook.abv.ui.common.util.ABVToastUtil;
import jp.agentec.abook.abv.ui.common.util.AlertDialogUtil;
import jp.agentec.abook.abv.ui.home.activity.BarCodeReaderActivity;
import jp.agentec.abook.abv.ui.home.helper.ABookPermissionHelper;
import jp.agentec.adf.util.NumericUtil;
import jp.agentec.adf.util.StringUtil;
public class ABVCheckContentViewActivity extends ABVContentViewActivity {
......@@ -62,12 +76,13 @@ public class ABVCheckContentViewActivity extends ABVContentViewActivity {
private static final int OKUDAKE_SERVICE_ID_HUMIDITY = 2;
// 定数
public static final int REQUEST_CODE_ENABLEBLUETOOTH_TEMPERATURE = 2001; // Bluetooth機能の有効化要求時の識別コード
public static final int REQUEST_CODE_ENABLEBLUETOOTH_OKUDAKE = 2002; // Bluetooth機能の有効化要求時の識別コード
public final static int REQUEST_CODE_BARCODE_READER = 2003; // バーコードリーダの職別コード
private static final int REQUEST_CODE_ENABLEBLUETOOTH_CENTER_TEMPERATURE = 2001; // Bluetooth機能の有効化要求時の識別コード(中心温度計)
private static final int REQUEST_CODE_ENABLEBLUETOOTH_OKUDAKE = 2002; // Bluetooth機能の有効化要求時の識別コード
private static final int REQUEST_CODE_BARCODE_READER = 2003; // バーコードリーダの職別コード
private static final int REQUEST_CODE_ENABLEBLUETOOTH_RADIATION_TEMPERATURE = 2004; // Bluetooth機能の有効化要求時の識別コード(放射温度計)
private static final int REQUEST_CODE_ENABLEBLUETOOTH_SPP_MACHINE = 2005; // Bluetooth機能の有効化要求時の識別コード(SPP通信機器)
// メンバー変数
public String mDeviceAddress = ""; // デバイスアドレス
private BleManagerUtil bleManagerUtil; // Bluetoothの接続
// 機器連携のコマンドの設問ID
......@@ -82,11 +97,32 @@ public class ABVCheckContentViewActivity extends ABVContentViewActivity {
//置くだけセンサースキャンするデバイス情報タイプ(1:温度、2:湿度)
private int mScaningServiceId;
//デバイスタイプ(1:中心温度計、2:置くだけセンサー、3:バーコード)
// デバイスタイプ
private int mDeviceType;
// メディアプレイヤー
private MediaPlayer mMediaPlayer;
// bluetoothアダプタ
private BluetoothAdapter mBluetoothAdapter;
// 接続を切った時、エラーが発生するので、ダイアログ表示しないようにフラグに保持
private boolean mDisConnectSppBluetoothFlg;
// 大和機器専用、bluetoothで値取得タスク
private YamatoBluetoothReceiveTask mYamatoReceiveTask;
// SPPbluetooth接続スレッド
private SppBluetoothConnectThread mSppBluetoothConnectThread;
// NFCアダプタを扱うための変数
private NfcAdapter mNfcAdapter;
// SPP通信端末のデータベース管理クラス
private SppDeviceDao mSppDeviceDao = AbstractDao.getDao(SppDeviceDao.class);
// SPP通信機器のデバイスID(t_spp_device)
private Integer mSppDeviceId;
/**
* Beaconスキャン結果受信Receiver.
*/
......@@ -169,45 +205,97 @@ public class ABVCheckContentViewActivity extends ABVContentViewActivity {
/** 中心温度計デバイス関連 開始 **/
bleManagerUtil = new BleManagerUtil(this, new BleManagerUtil.BleManagerUtilListener() {
@Override
public void onConnectionError(int status) { //中心温度計接続エラー
public void onConnectionError(int status) { //bluetooth接続エラー
Logger.e(TAG, "onConnectionError");
errorAfterAbookCheckAip(String.format(getString(R.string.msg_ble_connect_error), String.valueOf(status)));
bleThermometerDisconnect();
// bluetoothのデバイスタイプ(中心温度計・放射温度計)
int bluetoothDeviceType = bleManagerUtil.getBluetoothDeviceType();
// タイプによってメッセージ内容をセット
if (bluetoothDeviceType == DeviceType.centerThermomete) {
errorAfterAbookCheckAip(String.format(getString(R.string.msg_bluetooth_connect_error), getString(R.string.center_thermometer)));
} else if (bluetoothDeviceType == DeviceType.radiationThermomete) {
errorAfterAbookCheckAip(String.format(getString(R.string.msg_bluetooth_connect_error), getString(R.string.radiation_thermometer)));
}
bleManagerDisconnect();
}
@Override
public void onConnectionState() { // 中心温度計接続成功
public void onConnectionState() { // bluetooth接続成功
Logger.d(TAG, "onConnectionState");
//ダイアログが非表示になっても、何回呼ばれることがあるので、ダイアログのnullチェックする。
if (mWaitingDialog != null) {
mWaitingDialog.setMessage(getString(R.string.msg_ble_connect_success));
String message = null;
// bluetoothのデバイスタイプ(中心温度計・放射温度計)
int bluetoothDeviceType = bleManagerUtil.getBluetoothDeviceType();
// タイプによってメッセージ内容をセット
if (bluetoothDeviceType == DeviceType.centerThermomete) {
message = String.format(getString(R.string.msg_ble_connect_success), getString(R.string.center_thermometer));
} else if (bluetoothDeviceType == DeviceType.radiationThermomete) {
message = String.format(getString(R.string.msg_ble_connect_success), getString(R.string.radiation_thermometer));
}
if (StringUtil.isNullOrEmpty(message)) {
// 接続するデバイスが存在しないと見做し、接続を切る
bleManagerDisconnect();
} else {
mWaitingDialog.setMessage(message);
}
}
}
@Override
public void onDisConnectionState() { // 中心温度計接続切断
public void onDisConnectionState() { // bluetooth接続切断
Logger.d(TAG, "onDisConnectionState");
setThermometerData("");
// setThermometerData("");
dismissWaitngDialog();
}
@Override
public void onGetDeviceInfo(String strTemp) { // 中心温度計からデータ取得成功
public void onGetDeviceInfo(String strTemp) { // bluetooth機器からデータ取得成功
Logger.d(TAG, "onGetDeviceInfo temperature [%s]", strTemp);
setThermometerData(strTemp);
bleThermometerDisconnect();
bleManagerDisconnect();
}
@Override
public void onGetDeviceInfoFailed(int status) { // 中心温度計からデータ取得エラー
public void onGetDeviceInfoFailed(int status) { // bluetooth機器からデータ取得エラー
Logger.e(TAG, "onGetDeviceInfoFailed");
errorAfterAbookCheckAip(String.format(getString(R.string.msg_ble_connect_error), String.valueOf(status)));
// bluetoothのデバイスタイプ(中心温度計・放射温度計)
int bluetoothDeviceType = bleManagerUtil.getBluetoothDeviceType();
String errorMessage = null;
// タイプによってメッセージ内容をセット
if (bluetoothDeviceType == DeviceType.centerThermomete) {
errorMessage = String.format(getString(R.string.msg_bluetooth_connect_error), getString(R.string.center_thermometer));
} else if (bluetoothDeviceType == DeviceType.radiationThermomete) {
errorMessage = String.format(getString(R.string.msg_bluetooth_connect_error), getString(R.string.radiation_thermometer));
}
if (StringUtil.isNullOrEmpty(errorMessage)) {
errorAfterAbookCheckAip(errorMessage);
}
// bluetooth通信を切断
bleManagerDisconnect();
// ダイアログを閉じる
dismissWaitngDialog();
bleThermometerDisconnect();
}
});
bleManagerUtil.startDeviceInfo();
/** 中心温度計デバイス関連 終了 **/
// アダプタのインスタンスを取得
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
// bluetoothAdapterがない場合、デバイスがbluetooth機能がない??
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
// エラー: Bluetooth なし.
}
}
@Override
protected void onResume() {
super.onResume();
}
@Override
......@@ -228,22 +316,110 @@ public class ABVCheckContentViewActivity extends ABVContentViewActivity {
@Override
public void onPause() {
super.onPause();
if (mNfcAdapter != null) {
// Activityがバックグラウンドになったときは、受け取らない
mNfcAdapter.disableForegroundDispatch(this);
}
}
/**
* onNewIntentよりonPauseメソッドが先に呼ばれて、
* onPause処理でnfc検知を受け取らない処理が入っているため、
* nfc検知処理を受け取らない処理を入れなくてもいい
*
* @param intent
*/
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
String action = intent.getAction();
// nfcのみ対応、それ以外は無視
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)
|| NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)
|| NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
String data = readFromIntent(intent);
if (data != null) {
String[] dataLineSplit = data.split("\r\n");
String[] lastLineData = dataLineSplit[dataLineSplit.length - 1].split(",");
// "date, concentration, temperature"
String result = lastLineData[1].replaceAll(" ", "");
if (StringUtil.isNumber(result)) {
// 数値の場合、正常と見做し設問に値セット
setNfcData(result);
} else {
// 数値以外の場合、エラーと見做す
Logger.e(TAG, "nfc data is error : " + result);
errorAfterAbookCheckAip(String.format(getString(R.string.msg_nfc_value_error), result));
}
} else {
// 取得したデータがない場合、エラー表示
errorAfterAbookCheckAip(String.format(getString(R.string.msg_bluetooth_receive_data_error), getString(R.string.nfc_communication)));
}
dismissWaitngDialog();
}
}
/**
* インテントからデータを読み込み、データを取得
* @param intent
* @return 変換したデータ
*/
private String readFromIntent(Intent intent) {
String action = intent.getAction();
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)
|| NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)
|| NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
NdefMessage[] msgs = null;
if (rawMsgs != null) {
msgs = new NdefMessage[rawMsgs.length];
for (int i = 0; i < rawMsgs.length; i++) {
msgs[i] = (NdefMessage) rawMsgs[i];
}
return parseNdfMessageString(msgs);
}
}
return null;
}
/**
* Ndfメッセージを文字列に変換
* @param msgs
* @return 変換したデータ
*/
private String parseNdfMessageString(NdefMessage[] msgs) {
if (msgs == null || msgs.length == 0) return null;
String text = "";
byte[] payload = msgs[0].getRecords()[0].getPayload();
String textEncoding = ((payload[0] & 128) == 0) ? "UTF-8" : "UTF-16"; // Get the Text Encoding
int languageCodeLength = payload[0] & 0063; // Get the Language Code, e.g. "en"
// String languageCode = new String(payload, 1, languageCodeLength, "US-ASCII");
try {
// Get the Text
text = new String(payload, languageCodeLength + 1, payload.length - languageCodeLength - 1, textEncoding);
} catch (UnsupportedEncodingException e) {
Logger.e("UnsupportedEncoding", e.toString());
}
return text;
}
@Override
protected void onActivityResult( int requestCode, int resultCode, Intent data ) {
switch(requestCode) {
case REQUEST_CODE_ENABLEBLUETOOTH_TEMPERATURE: // 中心温度計Bluetooth有効化要求
case REQUEST_CODE_ENABLEBLUETOOTH_CENTER_TEMPERATURE: // 中心温度計Bluetooth有効化要求
if( Activity.RESULT_CANCELED == resultCode ) { // 有効にされなかった
errorAfterAbookCheckAip(getString(R.string.msg_thermometer_connect_bluetooth_no_allow));
errorAfterAbookCheckAip(String.format(getString(R.string.msg_connect_bluetooth_no_allow), getString(R.string.center_thermometer)));
return;
} else {
setThermometerDeviceInfo();
setCenterThermometerDeviceInfo();
}
break;
case REQUEST_CODE_ENABLEBLUETOOTH_OKUDAKE: // 置くだけセンサーBluetooth有効化要求
if( Activity.RESULT_CANCELED == resultCode ) { // 有効にされなかった
errorAfterAbookCheckAip(getString(R.string.msg_okudake_connect_bluetooth_no_allow));
errorAfterAbookCheckAip(String.format(getString(R.string.msg_connect_bluetooth_no_allow), getString(R.string.title_okudake_sensor)));
return;
} else {
startOkudakeBeaconScan();
......@@ -255,6 +431,22 @@ public class ABVCheckContentViewActivity extends ABVContentViewActivity {
successAfterAbookCheckAip(value);
}
break;
case REQUEST_CODE_ENABLEBLUETOOTH_RADIATION_TEMPERATURE: // 放射温度計
if( Activity.RESULT_CANCELED == resultCode ) { // 有効にされなかった
errorAfterAbookCheckAip(String.format(getString(R.string.msg_connect_bluetooth_no_allow), getString(R.string.radiation_thermometer)));
return;
} else {
setRadiationThermometerDeviceInfo();
}
break;
case REQUEST_CODE_ENABLEBLUETOOTH_SPP_MACHINE: // SPP通信機器
if( Activity.RESULT_CANCELED == resultCode ) { // 有効にされなかった
errorAfterAbookCheckAip(String.format(getString(R.string.msg_connect_bluetooth_no_allow), getString(R.string.spp_machine)));
return;
} else {
setSppBluetoothDeviceInfo();
}
break;
}
super.onActivityResult( requestCode, resultCode, data );
}
......@@ -263,30 +455,48 @@ public class ABVCheckContentViewActivity extends ABVContentViewActivity {
* ABVContentViewActivityからの呼ばれるメッソドで各種デバイスとの連携
* @param abookCheckParam HTML側からのパラメーター情報
*/
@Override
protected void getDeviceInfo(Map<String, String> abookCheckParam) {
if (abookCheckParam.containsKey(ABookKeys.TASK_DEVICE_TYPE)) {
mDeviceType = Integer.valueOf(abookCheckParam.get(ABookKeys.TASK_DEVICE_TYPE)); // ディバイスのタイプ取得
mQid = abookCheckParam.get(ABookKeys.TASK_QUESTION_ID); // 設問ID取得
// 1:中心温度計 2:置くだけセンサー 3:バーコード
if (mDeviceType == Constant.DeviceType.thermomete) { // 中心温度計
setThermometerDeviceInfo();
// 1:中心温度計 2:置くだけセンサー 3:バーコード 4:放射温度計 5: SPP通信機器 6: NFC通信
if (mDeviceType == DeviceType.centerThermomete) { // 中心温度計
setCenterThermometerDeviceInfo();
} else if (mDeviceType == Constant.DeviceType.sensor) { // 置くだけセンサー
} else if (mDeviceType == DeviceType.sensor) { // 置くだけセンサー
String param1 = abookCheckParam.get(ABookKeys.TASK_DEVICE_TYPE_PARAM1);
String param2 = abookCheckParam.get(ABookKeys.TASK_DEVICE_TYPE_PARAM2);
if (StringUtil.isNullOrEmpty(param1) || StringUtil.isNullOrEmpty(param2)) {
// パラメータが存在しない場合
errorAfterAbookCheckAip(getString(R.string.msg_not_found_parameter));
return;
}
try {
mScaningDeviceId = Integer.valueOf(abookCheckParam.get(ABookKeys.TASK_DEVICE_TYPE_PARAM1)); // デバイスID取得
mScaningServiceId = Integer.valueOf(abookCheckParam.get(ABookKeys.TASK_DEVICE_TYPE_PARAM2)); // ServiceId ID取得
mScaningDeviceId = Integer.valueOf(param1); // デバイスID取得
mScaningServiceId = Integer.valueOf(param2); // ServiceId ID取得
} catch (NumberFormatException e) {
Logger.e("param is not Int", e);
errorAfterAbookCheckAip(getString(R.string.msg_okudake_fraud_parameter));
errorAfterAbookCheckAip(getString(R.string.msg_fraud_parameter));
return;
}
startOkudakeBeaconScan();
} else if (mDeviceType == Constant.DeviceType.barcode) { // バーコード
} else if (mDeviceType == DeviceType.barcode) { // バーコード
setBarcodeDeviceInfo();
} else if (mDeviceType == DeviceType.radiationThermomete) { // 放射温度計
setRadiationThermometerDeviceInfo();
} else if (mDeviceType == DeviceType.sppBluetoothMachine) { // SPP通信機器
String param1 = abookCheckParam.get(ABookKeys.TASK_DEVICE_TYPE_PARAM1);
// スキームから取得したパラメータをメンバー変数のmSppDeviceIdにセット(setSppBluetoothDeviceInfoで使用)
mSppDeviceId = Integer.valueOf(param1);
setSppBluetoothDeviceInfo();
} else if (mDeviceType == DeviceType.nfc) {
setNfcDeviceInfo();
} else {
Logger.e("外部デバイスタイプ不正 deviceType = " + mDeviceType);
}
......@@ -296,6 +506,18 @@ public class ABVCheckContentViewActivity extends ABVContentViewActivity {
}
/**
* HTML側にNFC機器からのデータを転送する
* @param strTemp
*/
public void setNfcData(final String strTemp) {
Logger.i("setNfcData");
JSONObject nfcDataJson = new JSONObject();
nfcDataJson.put(ABookKeys.TASK_QUESTION_ID, mQid);
nfcDataJson.put("value", strTemp);
afterABookCheckApi(mCmd, "", 0, "", nfcDataJson.toString());
}
/**
* 置くだけセンサースキャン開始
*/
private void startOkudakeBeaconScan() {
......@@ -309,7 +531,7 @@ public class ABVCheckContentViewActivity extends ABVContentViewActivity {
//端末側の位置情報許可チェック
if (gpsEnabled || secureLocationGpsEnabled) {
ABookPermissionHelper helper = new ABookPermissionHelper(this, Constant.ABookPermissionType.AccessFineLocation, null);
ABookPermissionHelper helper = new ABookPermissionHelper(this, ABookPermissionType.AccessFineLocation, null);
//アプリ側の位置情報許可チェック(置くだけセンサーとLinkingアプリの通信できないため)
if (helper.checkMultiPermissions(true)) {
......@@ -352,12 +574,28 @@ public class ABVCheckContentViewActivity extends ABVContentViewActivity {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (mDeviceType) {
case Constant.DeviceType.thermomete:
bleThermometerDisconnect(); // 中心温度計接続切断
case DeviceType.centerThermomete:
case DeviceType.radiationThermomete:
bleManagerDisconnect(); // 中心温度計接続切断
break;
case Constant.DeviceType.sensor:
case DeviceType.sensor:
stopOkudakeBeaconScan(); // 置くだけセンサースキャン中止
break;
case DeviceType.sppBluetoothMachine:
disConnectSppBluetooth();
// 接続を切るのに5秒ぐらい必要なので、プログレスバーを表示して5秒後に閉じる
showProgressPopup(getString(R.string.msg_common_processing));
handler.postDelayed( new Runnable() {
@Override
public void run() {
closeProgressPopup();
}
}, 5000 );
break;
case DeviceType.nfc: // nfc
// Activityがバックグラウンドになったときは、受け取らない
mNfcAdapter.disableForegroundDispatch(ABVCheckContentViewActivity.this);
break;
}
successAfterAbookCheckAip("");
mWaitingDialog = null;
......@@ -378,19 +616,201 @@ public class ABVCheckContentViewActivity extends ABVContentViewActivity {
/**
* BLEディバイスの中心温度計の情報取得
*/
private void setThermometerDeviceInfo() {
if (requestBluetoothFeature(REQUEST_CODE_ENABLEBLUETOOTH_TEMPERATURE)) { //端末のBluetooth設定を確認
String deviceAddress = getUserPref(AppDefType.UserPrefKey.BLUETOOTH_DEVICE_TEMPERATURE_ADDRESS, "");
if (deviceAddress.length() > 0) { //登録されている中心温度計がある
showWaitingDialog(getString(R.string.set_pairing_central_thermometer), getString(R.string.ble_connecting));
bleManagerUtil.mDeviceAddress = deviceAddress;
// 接続
bleManagerUtil.connect();
} else { //登録されている中心温度計がない
errorAfterAbookCheckAip(getString(R.string.msg_no_device_info));
setThermometerData("");
private void setCenterThermometerDeviceInfo() {
if (requestBluetoothFeature(REQUEST_CODE_ENABLEBLUETOOTH_CENTER_TEMPERATURE)) { //端末のBluetooth設定を確認
String deviceAddress = getABVUIDataCache().getPairingBluetoothDeviceAddress(DeviceType.centerThermomete);
if (StringUtil.isNullOrEmpty(deviceAddress)) {
// 登録されている中心温度計がない場合
errorAfterAbookCheckAip(String.format(getString(R.string.msg_pairing_device_no_info), getString(R.string.center_thermometer)));
return; // 以下の処理にかからないようにreturnする
}
// 登録されている中心温度計がある
showWaitingDialog(getString(R.string.center_thermometer), getString(R.string.ble_connecting));
// 接続
bleManagerUtil.connect(DeviceType.centerThermomete, deviceAddress);
}
}
/**
* BLEディバイスの放射温度計の情報取得
*/
private void setRadiationThermometerDeviceInfo() {
if (requestBluetoothFeature(REQUEST_CODE_ENABLEBLUETOOTH_RADIATION_TEMPERATURE)) { //端末のBluetooth設定を確認
String deviceAddress = getABVUIDataCache().getPairingBluetoothDeviceAddress(DeviceType.radiationThermomete);
if (StringUtil.isNullOrEmpty(deviceAddress)) {
// 登録されている放射温度計がない場合
errorAfterAbookCheckAip(String.format(getString(R.string.msg_pairing_device_no_info), getString(R.string.radiation_thermometer)));
return; // 以下の処理にかからないようにreturnする
}
// 登録されている放射温度計がある
showWaitingDialog(getString(R.string.radiation_thermometer), getString(R.string.ble_connecting));
// 接続
bleManagerUtil.connect(DeviceType.radiationThermomete, deviceAddress);
}
}
/**
* SPP機器の通信情報をセット
*/
private void setSppBluetoothDeviceInfo() {
if (requestBluetoothFeature(REQUEST_CODE_ENABLEBLUETOOTH_SPP_MACHINE)) { //端末のBluetooth設定を確認
final SppDeviceDto sppDeviceDto = mSppDeviceDao.getSppDeviceById(mSppDeviceId);
if (sppDeviceDto == null || StringUtil.isNullOrEmpty(sppDeviceDto.pairingDeviceAddress)) {
// 登録されているSPP通信機器がない場合
errorAfterAbookCheckAip(String.format(getString(R.string.msg_pairing_device_no_info), getString(R.string.spp_machine)));
return; // 以下の処理にかからないようにreturnする
}
// 登録されているSPP通信機器がある時、接続する
showWaitingDialog(getString(R.string.spp_machine), getString(R.string.ble_connecting));
final BluetoothDevice bluetoothDevice = mBluetoothAdapter.getRemoteDevice(sppDeviceDto.pairingDeviceAddress);
if (bluetoothDevice != null) {
// 既に接続している場合、端末アドレスが一致すれば、接続済みと見做す。
if (mSppBluetoothConnectThread != null && mSppBluetoothConnectThread.getConnectedAddress().equals(bluetoothDevice.getAddress())) {
// 接続完了後、処理
if (mWaitingDialog != null) {
handler.post(new Runnable() {
@Override
public void run() {
mWaitingDialog.setMessage(String.format(getString(R.string.msg_ble_connect_success), sppDeviceDto.sppDeviceName));
}
});
}
} else { // 初回のbluetooth接続・bluetooth対象アドレスが異なる場合、新規で接続するようにする。
// 初回ではない場合はbluetoothを一度接続を切る。
if (mSppBluetoothConnectThread != null) {
Logger.i("------------------------------1");
disConnectSppBluetooth();
handler.postDelayed(new Runnable() {
@Override
public void run() {
setSppBluetoothThread(bluetoothDevice, sppDeviceDto);
}
}, 5000);
} else {
setSppBluetoothThread(bluetoothDevice, sppDeviceDto);
}
}
}
}
}
private void setSppBluetoothThread(final BluetoothDevice bluetoothDevice, final SppDeviceDto sppDeviceDto) {
// 接続が切れた時、tureにセットするため、接続起動時falseに初期化する。
mDisConnectSppBluetoothFlg = false;
// 接続
CommonExecutor.execute(new Runnable() {
@Override
public void run() {
mSppBluetoothConnectThread = new SppBluetoothConnectThread(bluetoothDevice, new SppBluetoothConnectThread.bluetoothConnectThreadListener() {
@Override
public void onConnect(BluetoothSocket socket) {
// 接続完了後、処理
if (mWaitingDialog != null) {
handler.post(new Runnable() {
@Override
public void run() {
mWaitingDialog.setMessage(String.format(getString(R.string.msg_ble_connect_success), sppDeviceDto.sppDeviceName));
}
});
}
mYamatoReceiveTask = new YamatoBluetoothReceiveTask(socket, sppDeviceDto, new YamatoBluetoothReceiveTask.BluetoothReceiveTaskListener() {
@Override
public void onGetData(String result) {
Logger.i(TAG, "result : " + result);
// ダイアログが表示されてる場合だけ、設問に値をセットする
if (mWaitingDialog != null && mWaitingDialog.isShowing()) {
setSppBluetoothMachineData(result);
}
}
@Override
public void onFail(boolean dataFormatErrorFlg) {
Logger.e(TAG, "receiveTaskThread fail");
connectErrorSppDevice(sppDeviceDto.sppDeviceName, dataFormatErrorFlg);
}
});
mYamatoReceiveTask.start();
}
@Override
public void onFail() {
Logger.e(TAG, "ConnectThread fail");
connectErrorSppDevice(sppDeviceDto.sppDeviceName, false);
}
});
// bluetooth接続スレッド処理開始
mSppBluetoothConnectThread.start();
}
});
}
/**
* NFCデータ受信できるようにセット
*/
private void setNfcDeviceInfo() {
if (mNfcAdapter == null) {
// デバイスがNFCをサポートしてないと見做す。
errorAfterAbookCheckAip(String.format(getString(R.string.msg_no_support_nfc)));
return; // 以下の処理にかからないようにreturnする
}
// 端末のNFC設定が無効の場合
if (!mNfcAdapter.isEnabled()) {
// NFC設定画面へ遷移確認ダイアログ表示
showNfcSettingDialog();
return;
}
// NFCがかざされたときの設定
Intent intent = new Intent(this, this.getClass());
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
// ほかのアプリを開かないようにする
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, 0);
// nfcアダプタのフォアグラウンドディスパッチを有効(onNewIntentメソッドからnfc検知を行う)
mNfcAdapter.enableForegroundDispatch(this, pendingIntent, null, null);
showWaitingDialog(getString(R.string.nfc_communication), getString(R.string.msg_hold_nfc_device));
}
/**
* 端末のNFC設定確認
*/
private void showNfcSettingDialog() {
ABookAlertDialog alertDialog = AlertDialogUtil.createAlertDialog(this, "NFC");
alertDialog.setMessage(getString(R.string.msg_no_nfc_setting));
alertDialog.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int whichButton) {
startActivity(new Intent(Settings.ACTION_NFC_SETTINGS));
}
});
alertDialog.setNegativeButton(R.string.cancel, null);
alertDialog.show();
}
/**
* SPP通信エラー処理
* @param deviceName
*/
private void connectErrorSppDevice(String deviceName, boolean dataFormatErrorFlg) {
if (!mDisConnectSppBluetoothFlg) {
if (dataFormatErrorFlg) {
// データ取得時のエラーはbluetoothを切断しない
errorAfterAbookCheckAip(String.format(getString(R.string.msg_bluetooth_receive_data_error), deviceName));
} else {
disConnectSppBluetooth();
errorAfterAbookCheckAip(String.format(getString(R.string.msg_bluetooth_connect_error), deviceName));
}
if (mWaitingDialog != null && mWaitingDialog.isShowing()) {
mWaitingDialog.dismiss();
}
}
}
......@@ -410,7 +830,7 @@ public class ABVCheckContentViewActivity extends ABVContentViewActivity {
}
/**
* HTML側に中心温度計からのデータを転送する
* HTML側に温度計からのデータを転送する
* @param strTemp デバイスから受信された値
*/
private void setThermometerData(String strTemp) {
......@@ -426,19 +846,35 @@ public class ABVCheckContentViewActivity extends ABVContentViewActivity {
Logger.v(TAG, "thermometer JSON [%s]", thermometerDataJson.toString());
}
/**
* HTML側にSPP機器からのデータを転送する
* @param strData デバイスから受信された値
*/
public void setSppBluetoothMachineData(final String strData) {
Logger.v(TAG, "SppBluetoothMachine [%s]", strData);
JSONObject sppBluetoothMachineDataJson = new JSONObject();
sppBluetoothMachineDataJson.put(ABookKeys.TASK_QUESTION_ID, mQid);
sppBluetoothMachineDataJson.put("value", strData);
afterABookCheckApi(mCmd, "", 0, "", sppBluetoothMachineDataJson.toString());
// 閉じる
dismissWaitngDialog();
}
/**
* 中心温度計の接続を切る
*/
protected void bleThermometerDisconnect() {
protected void bleManagerDisconnect() {
bleManagerUtil.disconnect();
}
/**
* デバイスのバーコードの情報取得
* デバイスのバーコードの情報取得
*/
private void setBarcodeDeviceInfo() {
//カメラパーミッションチェック
ABookPermissionHelper helper = new ABookPermissionHelper(ABVCheckContentViewActivity.this, Constant.ABookPermissionType.Camera, null);
ABookPermissionHelper helper = new ABookPermissionHelper(ABVCheckContentViewActivity.this, ABookPermissionType.Camera, null);
if (!helper.checkMultiPermissions(true)) {
Logger.w(TAG,"startCameraIntent Camera Permission false");
return;
......@@ -537,4 +973,30 @@ public class ABVCheckContentViewActivity extends ABVContentViewActivity {
// mediaPlayerを初期化
mMediaPlayer = null;
}
// SPP通信のタスクが存在すれば接続を切るにする
private void disConnectSppBluetooth() {
mDisConnectSppBluetoothFlg = true;
if (mYamatoReceiveTask != null) {
mYamatoReceiveTask.finish();
mYamatoReceiveTask = null;
}
if (mSppBluetoothConnectThread != null) {
mSppBluetoothConnectThread.finish();
mSppBluetoothConnectThread = null;
}
}
@Override
protected void onStop() {
super.onStop();
// SPP通信の接続を切る
disConnectSppBluetooth();
// ダイアログを閉じる
if (mWaitingDialog != null && mWaitingDialog.isShowing()) {
mWaitingDialog.dismiss();
}
}
}
......@@ -57,8 +57,13 @@ public interface AppDefType {
String RESOURCE_PATTERN_TYPE = "resourcePatternType"; // 文言リソースパターン
String BLUETOOTH_DEVICE_TEMPERATURE_NAME = "bleDeviceTemperatureName"; // 温度計機器の名
String BLUETOOTH_DEVICE_TEMPERATURE_ADDRESS = "bleDeviceTemperatureAddress"; // 温度計機器のアドレス
// 中心温度計
String BLE_DEVICE_CENTER_TEMPERATURE_NAME = "bleDeviceCenterTemperatureName"; // 中心温度計機器の名
String BLE_DEVICE_CENTER_TEMPERATURE_ADDRESS = "bleDeviceCenterTemperatureAddress"; // 中心温度計機器のアドレス
// 放射温度計
String BLE_DEVICE_RADIATION_TEMPERATURE_NAME = "bleDeviceRadiationTemperatureName"; // 放射温度計機器の名
String BLE_DEVICE_RADIATION_TEMPERATURE_ADDRESS = "bleDeviceRadiationTemperatureAddress"; // 放射温度計機器のアドレス
String MASTER_DATA_FETCH_DATE = "masterDataFetchDate"; // マスタデータのFetchDate
}
......
......@@ -15,6 +15,7 @@ import java.io.InputStream;
import jp.agentec.abook.abv.bl.common.ABVEnvironment;
import jp.agentec.abook.abv.bl.common.log.Logger;
import jp.agentec.abook.abv.bl.download.ContentFileExtractor;
import jp.agentec.abook.abv.launcher.android.ABVApplication;
import jp.agentec.abook.abv.launcher.android.R;
import jp.agentec.adf.util.FileUtil;
......@@ -61,6 +62,8 @@ public class ABookSettingActivity extends PreferenceActivity {
@Override
protected void onResume() {
super.onResume();
// アプリがpauseかどうかの判定を最上位クラスABVActivityで処理が行っていて、設定画面だけ親クラスを参照してないためセットする
((ABVApplication) getApplication()).getABVUIDataCache().visibleActivityName = getClass().getName();
}
@Override
......@@ -68,6 +71,7 @@ public class ABookSettingActivity extends PreferenceActivity {
super.onPause();
}
// ホーム画面へ戻る処理
private void backToHome() {
Intent intent = new Intent(getApplicationContext(), OperationListActivity.class);
......@@ -76,6 +80,10 @@ public class ABookSettingActivity extends PreferenceActivity {
finish();
}
/**
* スマートフォンか判定
* @return
*/
private boolean isNormalSize() {
return (getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_NORMAL;
}
......
......@@ -35,7 +35,6 @@ import jp.agentec.abook.abv.bl.acms.type.AcmsApis;
import jp.agentec.abook.abv.bl.common.ABVEnvironment;
import jp.agentec.abook.abv.bl.common.CommonExecutor;
import jp.agentec.abook.abv.bl.common.Constant;
import jp.agentec.abook.abv.bl.common.constant.ABookKeys;
import jp.agentec.abook.abv.bl.common.log.Logger;
import jp.agentec.abook.abv.bl.data.ABVDataCache;
import jp.agentec.abook.abv.bl.dto.MemberInfoDto;
......@@ -49,19 +48,14 @@ import jp.agentec.abook.abv.launcher.android.OnAppDownloadReceiver;
import jp.agentec.abook.abv.launcher.android.R;
import jp.agentec.abook.abv.ui.common.appinfo.AppDefType;
import jp.agentec.abook.abv.ui.common.appinfo.AppDefType.UserPrefKey;
import jp.agentec.abook.abv.ui.common.appinfo.options.Options;
import jp.agentec.abook.abv.ui.common.dialog.ABookAlertDialog;
import jp.agentec.abook.abv.ui.common.helper.ProgressDialogHelper;
import jp.agentec.abook.abv.ui.common.util.ABVToastUtil;
import jp.agentec.abook.abv.ui.common.util.AlertDialogUtil;
import jp.agentec.abook.abv.ui.common.util.PatternStringUtil;
import jp.agentec.abook.abv.ui.home.helper.ABookPermissionHelper;
import jp.agentec.adf.util.DateTimeFormat;
import jp.agentec.adf.util.DateTimeUtil;
import static jp.agentec.abook.abv.cl.util.PreferenceUtil.getUserPref;
import static jp.agentec.abook.abv.cl.util.PreferenceUtil.putUserPref;
public class ABookSettingFragment extends PreferenceFragment {
private static final String TAG = "ABookSettingActivity";
......@@ -90,8 +84,9 @@ public class ABookSettingFragment extends PreferenceFragment {
protected AlertDialog alertDialog = null;
private SharedPreferences pref;
// 機器連携
private static final String SET_PAIRING = "setPairing";
// 機器連携(ペアリング)
private static final String SET_CHINO_PAIRING = "setChinoPairing"; // CHINO機器
private static final String SET_SPP_PAIRING = "setSppPairing"; // SPP通信機器
@Override
public void onCreate(Bundle savedInstanceState) {
......@@ -475,16 +470,34 @@ public class ABookSettingFragment extends PreferenceFragment {
// 機器連携のペアリング設定
private void setPairingSetting() {
PreferenceGroup devicePairing = (PreferenceGroup) findPreference(SET_PAIRING);
// CHINO機器
PreferenceGroup chinoDevicePairing = (PreferenceGroup) findPreference(SET_CHINO_PAIRING);
chinoDevicePairing.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
try {
// ペアリング設定画面(BLE通信)
Intent intent = new Intent();
intent.setClass(getActivity(), BlePairingSettingActivity.class);
startActivity(intent);
} catch (Exception e) {
Logger.e(TAG, e);
}
return true;
}
});
// SPP通信機器
PreferenceGroup sppDevicePairing = (PreferenceGroup) findPreference(SET_SPP_PAIRING);
devicePairing.setOnPreferenceClickListener(new OnPreferenceClickListener() {
sppDevicePairing.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
try {
// ペアリング設定画面
// ペアリング設定画面(SPP通信)
Intent intent = new Intent();
intent.setClass(getActivity(), PairingSettingActivity.class);
intent.putExtra("beforeView", SET_PAIRING);
intent.setClass(getActivity(), SppBluetoothPairingSettingActivity.class);
startActivity(intent);
} catch (Exception e) {
Logger.e(TAG, e);
......
......@@ -6,7 +6,8 @@ import android.bluetooth.BluetoothDevice;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanResult;
import android.content.DialogInterface;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.location.LocationManager;
import android.os.Build;
......@@ -21,47 +22,42 @@ import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import jp.agentec.abook.abv.bl.common.Constant;
import jp.agentec.abook.abv.bl.common.Constant.DeviceType;
import jp.agentec.abook.abv.bl.common.log.Logger;
import jp.agentec.abook.abv.bl.dto.BluetoothPairingDeviceInfoDto;
import jp.agentec.abook.abv.cl.util.BleManagerUtil;
import jp.agentec.abook.abv.cl.util.PreferenceUtil;
import jp.agentec.abook.abv.launcher.android.R;
import jp.agentec.abook.abv.ui.common.activity.ABVUIActivity;
import jp.agentec.abook.abv.ui.common.appinfo.AppDefType;
import jp.agentec.abook.abv.ui.common.dialog.ABookAlertDialog;
import jp.agentec.abook.abv.ui.common.util.ABVToastUtil;
import jp.agentec.abook.abv.ui.common.util.AlertDialogUtil;
import jp.agentec.abook.abv.ui.home.adapter.BleListAdapter;
import jp.agentec.abook.abv.ui.home.adapter.BleListRowData;
import jp.agentec.abook.abv.ui.home.adapter.common.SectionHeaderData;
import jp.agentec.abook.abv.ui.home.helper.ABookPermissionHelper;
import jp.agentec.adf.util.CollectionUtil;
public class PairingSettingActivity extends ABVUIActivity {
private static final String TAG = "PairingSettingActivity";
public class BlePairingSettingActivity extends ABVUIActivity {
private static final String TAG = "BlePairingSettingActivity";
// 定数
private static final int REQUEST_ENABLEBLUETOOTH = 1; // Bluetooth機能の有効化要求時の識別コード
private static final long SCAN_PERIOD = 20000; // スキャン時間。単位はミリ秒。
public static final String EXTRAS_DEVICE_NAME = "DEVICE_NAME";
public static final String EXTRAS_DEVICE_ADDRESS = "DEVICE_ADDRESS";
public static final String DEVICE_CONNECTED = "DEVICE_CONNECTED"; // ディバイスと接続可否
public static final String DEVICE_LIST = "DEVIVE_LIST"; // リストビュー
private static final String CENTER_THERMOMETE_DEVICE_NAME = "MF500"; // 中心温度計のデバイス名
private static final String RADIATION_THERMOMETE_DEVICE_NAME = "IR-TB"; // 放射温度計のデバイス名
// メンバー変数
private Handler mHandler; // UIスレッド操作ハンドラ : 「一定時間後にスキャンをやめる処理」で必要
private boolean mScanning = false; // スキャン中かどうかのフラグ
private boolean mScanning = false; // スキャン中かどうかのフラグ
private Button mButton_Scan;
private Button mButton_Stop;
private String mBeforeView; // 以前画面の情報
private BleManagerUtil bleManagerUtil;
private BleListAdapter mBleListAdapter; // Adapter
private int selectedDeviceListPostion;
private List<BluetoothDevice> mScanDeviceInfoList;
private List<BluetoothDevice> mScanDeviceInfoList = new ArrayList<BluetoothDevice>();
private String mSavedDeviceAddress; //登録した端末アドレス
private boolean mConnecting; //デバイス接続中
private List<String> mSavedDeviceAddressList = new ArrayList<String>(); //登録した端末アドレス
// デバイススキャンコールバック
private ScanCallback mLeScanCallback = new ScanCallback() {
......@@ -73,19 +69,21 @@ public class PairingSettingActivity extends ABVUIActivity {
@Override
public void run() {
BluetoothDevice device = result.getDevice();
Logger.d("mLeScanCallback device.getName() = " + device.getName());
Logger.d("mScanCallback device.getName() = " + device.getName());
// 識別商品名に絞る
if(device.getName() != null && device.getName().startsWith("MF500")) {
if (!device.getAddress().equals(mSavedDeviceAddress)) { //登録されたデバイスの場合、スキャン情報から除外する。
if (mScanDeviceInfoList == null || mScanDeviceInfoList.size() == 0) {
mScanDeviceInfoList.add(device);
} else {
for (BluetoothDevice savedDevice : mScanDeviceInfoList) {
if (!savedDevice.getAddress().equals(device.getAddress())) {
mScanDeviceInfoList.add(device);
}
if(device.getName() != null && (device.getName().startsWith(CENTER_THERMOMETE_DEVICE_NAME) || device.getName().startsWith(RADIATION_THERMOMETE_DEVICE_NAME))) {
if (!mSavedDeviceAddressList.contains(device.getAddress())) { //登録されたデバイスの場合、スキャン情報から除外する。
boolean isAdd = true;
for (BluetoothDevice savedDevice : mScanDeviceInfoList) {
if (savedDevice.getAddress().equals(device.getAddress())) {
// スキャンされたデバイス情報リストから一つでも一致する場合、既にスキャンされたと見做し追加しない。
isAdd = false;
}
}
if (isAdd) {
mScanDeviceInfoList.add(device);
}
reloadListView();
}
Logger.d("device.getName() = " + device.getName() + "device.getAddress() = " + device.getAddress() );
......@@ -108,25 +106,30 @@ public class PairingSettingActivity extends ABVUIActivity {
setContentView(R.layout.pairing_setting);
TextView deviceTitle = (TextView) findViewById(R.id.device_toolbar_title);
deviceTitle.setText(R.string.set_pairing_central_thermometer);
deviceTitle.setText(getString(R.string.chino_machine));
// 戻り値の初期化
setResult( Activity.RESULT_CANCELED );
// 画像数の取得
Intent intent = getIntent();
mBeforeView = intent.getStringExtra("beforeView"); // 以前画面を確認する。以前画面によって接続するやり方が違う。
List<SectionHeaderData> sectionList = getSectionListInfo();
List<List<BleListRowData>> rowList = getRowListInfo();
mBleListAdapter = new BleListAdapter( this, sectionList, rowList, new BleListAdapter.BleListAdapterListener() { // ビューアダプターの初期化
@Override
public void onDeleteConnectInfo() { // 登録されたデバイス情報削除
if (mConnecting) { //接続中
return;
public void onDeleteConnectInfo(BleListRowData rowData) { // 登録されたデバイス情報削除
Logger.i(rowData.deviceAddress);
Integer deviceType = null;
if (rowData.title.startsWith(CENTER_THERMOMETE_DEVICE_NAME)) {
deviceType = DeviceType.centerThermomete;
} else if (rowData.title.startsWith(RADIATION_THERMOMETE_DEVICE_NAME)) {
deviceType = DeviceType.radiationThermomete;
}
removeBleConnectInfoUserPref();
if (deviceType != null) {
// 機器連携の情報をローカルに削除する。
getABVUIDataCache().removePairingBluetoothDeviceInfo(deviceType);
}
// 保存済みのアドレスを管理するメンバー変数も削除
mSavedDeviceAddressList.remove(rowData.deviceAddress);
reloadListView();
//スキャン実行中ではない場合はスキャン実行
if (!mScanning) {
......@@ -135,10 +138,12 @@ public class PairingSettingActivity extends ABVUIActivity {
}
});
// Bluetoothと接続処理する
bleManagerUtil = new BleManagerUtil(this, null);
bleManagerUtil.startDeviceInfo();
// bleManagerUtil.mBluetoothAdapter.startDiscovery();
ListView listView = (ListView) findViewById(R.id.devicelist); // リストビューの取得
listView.setAdapter(mBleListAdapter); // リストビューにビューアダプターをセット
......@@ -148,7 +153,10 @@ public class PairingSettingActivity extends ABVUIActivity {
long id) {
Logger.d(TAG, "position = " + position);
BleListRowData bleListRowData = (BleListRowData)parent.getItemAtPosition(position);
localSaveDeviceInfo(bleListRowData);
// 既に保存されてる場合は何もしない
if (!bleListRowData.isSaved) {
localSaveDeviceInfo(bleListRowData);
}
}
});
......@@ -169,7 +177,6 @@ public class PairingSettingActivity extends ABVUIActivity {
// UIスレッド操作ハンドラの作成(「一定時間後にスキャンをやめる処理」で使用する)
mHandler = new Handler();
this.mScanDeviceInfoList = new ArrayList<BluetoothDevice>();
}
// 初回表示時、および、ポーズからの復帰時
......@@ -210,14 +217,19 @@ public class PairingSettingActivity extends ABVUIActivity {
if (!requestBluetoothFeature()) return;
LocationManager lm = (LocationManager) this.getSystemService(this.LOCATION_SERVICE);
final boolean gpsEnabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
boolean gpsEnabled = false;
if (lm != null) {
gpsEnabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
} else {
Logger.w(TAG, "LocationManager is null");
}
// GPSの状態を取得(getSystemtServiceからのGPS ON/OFF取得が取れない場合があるため、secureで取得したgpsも判定するため)
final boolean secureLocationGpsEnabled = android.provider.Settings.Secure.getString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED).contains("gps");
//端末側の位置情報許可チェック
if (!(gpsEnabled || secureLocationGpsEnabled)) {
showSimpleAlertDialog(R.string.set_pairing_central_thermometer, R.string.msg_location_device_no_allow);
showSimpleAlertDialog(R.string.chino_machine, R.string.msg_location_device_no_allow);
return;
}
......@@ -225,21 +237,22 @@ public class PairingSettingActivity extends ABVUIActivity {
//アプリ側の位置情報許可チェック(置くだけセンサーとLinkingアプリの通信できないため)
if (!helper.checkMultiPermissions(true)) return;
//デバイス接続中にはスキャンさせない
if (mConnecting) {
return;
}
// BluetoothLeScannerの取得
// ※Runnableオブジェクト内でも使用できるようfinalオブジェクトとする。
BluetoothLeScanner scanner = null;
BluetoothLeScanner scanner = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
scanner = bleManagerUtil.mBluetoothAdapter.getBluetoothLeScanner();
}
if(scanner == null) {
if (scanner == null) {
return;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
scanner.startScan(mLeScanCallback);
}
// スキャン開始(一定時間後にスキャン停止する)
mHandler.postDelayed( new Runnable() {
@Override
......@@ -250,9 +263,7 @@ public class PairingSettingActivity extends ABVUIActivity {
}, SCAN_PERIOD );
mScanning = true;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
scanner.startScan(mLeScanCallback);
}
mButton_Scan.setText(getString(R.string.pairing_search_stop));
reloadListView();
Logger.d(TAG, "start scan !!");
......@@ -282,13 +293,30 @@ public class PairingSettingActivity extends ABVUIActivity {
}
private void localSaveDeviceInfo(BleListRowData bleListRowData) {
String savedDeviceAddress = getUserPref(AppDefType.UserPrefKey.BLUETOOTH_DEVICE_TEMPERATURE_ADDRESS, "");
if (!savedDeviceAddress.equals(bleListRowData.deviceAddress)) { //保存している
mSavedDeviceAddress = bleListRowData.deviceAddress;
setUserPref(bleListRowData.title, mSavedDeviceAddress);
int removeIndex = -1;
// アドレスが保存されてる場合無視
if (!mSavedDeviceAddressList.contains(bleListRowData.deviceAddress)) {
mSavedDeviceAddressList.add(bleListRowData.deviceAddress);
BluetoothPairingDeviceInfoDto pairingDeviceInfo = new BluetoothPairingDeviceInfoDto();
if (bleListRowData.title.startsWith(CENTER_THERMOMETE_DEVICE_NAME)) {
// デバイス名がMF500から始まると中心温度計と見做す。
pairingDeviceInfo.deviceType = DeviceType.centerThermomete;
} else if (bleListRowData.title.startsWith(RADIATION_THERMOMETE_DEVICE_NAME)) {
// デバイス名がIR-TBから始まると放射温度計と見做す。
pairingDeviceInfo.deviceType = DeviceType.radiationThermomete;
}
// 上記のdeviceTypeがセットされた場合のみ、ローカルのxmlに保存する
if (pairingDeviceInfo.deviceType != null) {
pairingDeviceInfo.deviceName = bleListRowData.title;
pairingDeviceInfo.deviceAddress = bleListRowData.deviceAddress;
// 機器連携の情報をローカルに保存する。
getABVUIDataCache().setPairingBluetoothDeviceInfo(pairingDeviceInfo);
}
// スキャンされた情報から保存されたのでdeviceは削除
for (BluetoothDevice savedScanDevice : mScanDeviceInfoList) {
if (savedScanDevice.getAddress().equals(mSavedDeviceAddress)) {
if (savedScanDevice.getAddress().equals(bleListRowData.deviceAddress)) {
mScanDeviceInfoList.remove(savedScanDevice);
break;
}
......@@ -304,42 +332,26 @@ public class PairingSettingActivity extends ABVUIActivity {
finish();
}
// 機器連携の情報をローカルに保存する。
public void setUserPref(String deviceName, String deviceAddress) {
putUserPref(AppDefType.UserPrefKey.BLUETOOTH_DEVICE_TEMPERATURE_NAME, deviceName);
putUserPref(AppDefType.UserPrefKey.BLUETOOTH_DEVICE_TEMPERATURE_ADDRESS, deviceAddress);
}
/**
* 機器連携の情報をローカルに削除する。
*/
private void removeBleConnectInfoUserPref() {
PreferenceUtil.removeUserPref(this, AppDefType.UserPrefKey.BLUETOOTH_DEVICE_TEMPERATURE_NAME);
PreferenceUtil.removeUserPref(this, AppDefType.UserPrefKey.BLUETOOTH_DEVICE_TEMPERATURE_ADDRESS);
mSavedDeviceAddress = null;
}
// アラート表示処理
private void showConfirmAlert(final int dialogTitle, String dialogMessage) {
ABookAlertDialog alert = AlertDialogUtil.createAlertDialog(this, dialogTitle);
alert.setMessage(dialogMessage);
alert.setButton(DialogInterface.BUTTON_POSITIVE, getResources().getString(R.string.confirm), (DialogInterface.OnClickListener) null);
showAlertDialog(alert);
}
/**
* ListViewのSectionデータを作成する。
* @return Rowデータリスト
*/
private List<SectionHeaderData> getSectionListInfo() {
List<SectionHeaderData> sectionList = new ArrayList<SectionHeaderData>();
if (getUserPref(AppDefType.UserPrefKey.BLUETOOTH_DEVICE_TEMPERATURE_NAME, "").length() > 0) {
sectionList.add(new SectionHeaderData(getString(R.string.pairing_save_thermometer)));
}
if (mScanning) {
sectionList.add(new SectionHeaderData(getString(R.string.pairing_other_thermometer_searching)));
} else {
sectionList.add(new SectionHeaderData(getString(R.string.pairing_other_thermometer)));
List<SectionHeaderData> sectionList = new ArrayList<>();
List<BluetoothPairingDeviceInfoDto> bluetoothPairingInfoDtoList = getABVUIDataCache().getPairingBluetoothDeviceInfoList(Arrays.asList(DeviceType.centerThermomete, DeviceType.radiationThermomete));
if (CollectionUtil.isNotEmpty(bluetoothPairingInfoDtoList)) {
for (BluetoothPairingDeviceInfoDto bluetoothPairingDeviceInfoDto : bluetoothPairingInfoDtoList) {
// ペアリング情報が既に保存されてる場合はヘッダー情報を各機器毎に追加する
if (bluetoothPairingDeviceInfoDto.deviceType.equals(DeviceType.centerThermomete)) {
sectionList.add(new SectionHeaderData(String.format(getString(R.string.pairing_save_machine), getString(R.string.center_thermometer))));
} else if (bluetoothPairingDeviceInfoDto.deviceType.equals(DeviceType.radiationThermomete)) {
sectionList.add(new SectionHeaderData(String.format(getString(R.string.pairing_save_machine), getString(R.string.radiation_thermometer))));
}
}
}
// その他のヘッダー情報追加
sectionList.add(new SectionHeaderData(String.format(getString(mScanning ? R.string.pairing_other_machine_searching : R.string.pairing_other_machine), getString(R.string.chino_machine))));
return sectionList;
}
......@@ -350,18 +362,24 @@ public class PairingSettingActivity extends ABVUIActivity {
*/
private List<List<BleListRowData>> getRowListInfo() {
List<List<BleListRowData>> rowList = new ArrayList<List<BleListRowData>>();
if (getUserPref(AppDefType.UserPrefKey.BLUETOOTH_DEVICE_TEMPERATURE_NAME, "").length() > 0) {
List<BleListRowData> rowDataList = new ArrayList<BleListRowData>();
String deviceName = getUserPref(AppDefType.UserPrefKey.BLUETOOTH_DEVICE_TEMPERATURE_NAME, "");
String deviceAddress = getUserPref(AppDefType.UserPrefKey.BLUETOOTH_DEVICE_TEMPERATURE_ADDRESS, "");
BleListRowData rowData = new BleListRowData(deviceName, deviceAddress, true);
rowDataList.add(rowData);
rowList.add(rowDataList);
this.mSavedDeviceAddress = deviceAddress;
// 引数で指定したタイプリストのペアリング情報を取得
List<BluetoothPairingDeviceInfoDto> bluetoothPairingInfoDtoList = getABVUIDataCache().getPairingBluetoothDeviceInfoList(Arrays.asList(DeviceType.centerThermomete, DeviceType.radiationThermomete));
if (CollectionUtil.isNotEmpty(bluetoothPairingInfoDtoList)) {
for (BluetoothPairingDeviceInfoDto bluetoothPairingDeviceInfoDto : bluetoothPairingInfoDtoList) {
List<BleListRowData> rowDataList = new ArrayList<BleListRowData>();
BleListRowData rowData = new BleListRowData(bluetoothPairingDeviceInfoDto.deviceName, bluetoothPairingDeviceInfoDto.deviceAddress, true);
rowDataList.add(rowData);
rowList.add(rowDataList);
// 保存された情報であれば、メンバー変数で管理するため、listに追加、既に存在する場合は何もしない
if (!mSavedDeviceAddressList.contains(bluetoothPairingDeviceInfoDto.deviceAddress)) {
mSavedDeviceAddressList.add(bluetoothPairingDeviceInfoDto.deviceAddress);
}
}
}
if (mScanDeviceInfoList == null || mScanDeviceInfoList.size() == 0) {
if (mScanDeviceInfoList.size() == 0) {
List<BleListRowData> scanRowDataList = new ArrayList<BleListRowData>();
BleListRowData scanRowData = new BleListRowData("" , "" );
scanRowDataList.add(scanRowData);
......@@ -369,7 +387,13 @@ public class PairingSettingActivity extends ABVUIActivity {
} else {
List<BleListRowData> scanRowDataList = new ArrayList<BleListRowData>();
for (BluetoothDevice bleDevice : mScanDeviceInfoList) {
BleListRowData scanRowData = new BleListRowData(bleDevice.getName() , bleDevice.getAddress(), false);
String labelDeviceName = "";
if (bleDevice.getName().startsWith(CENTER_THERMOMETE_DEVICE_NAME)) {
labelDeviceName = getString(R.string.center_thermometer);
} else if (bleDevice.getName().startsWith(RADIATION_THERMOMETE_DEVICE_NAME)) {
labelDeviceName = getString(R.string.radiation_thermometer);
}
BleListRowData scanRowData = new BleListRowData(bleDevice.getName(), labelDeviceName, bleDevice.getAddress(), false);
scanRowDataList.add(scanRowData);
}
rowList.add(scanRowDataList);
......
......@@ -9,6 +9,7 @@ import jp.agentec.abook.abv.bl.acms.type.RequirePasswordChangeType;
import jp.agentec.abook.abv.bl.common.ABVEnvironment;
import jp.agentec.abook.abv.bl.common.CommonExecutor;
import jp.agentec.abook.abv.bl.common.Constant;
import jp.agentec.abook.abv.bl.common.Constant.DeviceType;
import jp.agentec.abook.abv.bl.common.Constant.ExceptionDetailMessage;
import jp.agentec.abook.abv.bl.common.exception.ABVException;
import jp.agentec.abook.abv.bl.common.exception.ABVExceptionCode;
......@@ -19,6 +20,7 @@ import jp.agentec.abook.abv.bl.data.dao.AbstractDao;
import jp.agentec.abook.abv.bl.data.dao.AcmsDao;
import jp.agentec.abook.abv.bl.data.dao.MemberInfoDao;
import jp.agentec.abook.abv.bl.download.ContentRefresher;
import jp.agentec.abook.abv.bl.dto.BluetoothPairingDeviceInfoDto;
import jp.agentec.abook.abv.bl.dto.MemberInfoDto;
import jp.agentec.abook.abv.bl.dto.PasswordLockInfoDto;
import jp.agentec.abook.abv.bl.logic.AbstractLogic;
......@@ -30,7 +32,6 @@ import jp.agentec.abook.abv.cl.environment.DeviceInfo;
import jp.agentec.abook.abv.cl.util.PreferenceUtil;
import jp.agentec.abook.abv.launcher.android.R;
import jp.agentec.abook.abv.ui.common.activity.ABVLoginActivity;
import jp.agentec.abook.abv.ui.common.appinfo.AppDefType;
import jp.agentec.abook.abv.ui.common.appinfo.AppDefType.UserPrefKey;
import jp.agentec.abook.abv.ui.common.constant.ErrorCode;
import jp.agentec.abook.abv.ui.common.constant.ErrorMessage;
......@@ -56,6 +57,9 @@ import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
import java.util.Arrays;
import java.util.List;
/**
* @author Minhyuk Seok
* @editor Jang
......@@ -639,20 +643,17 @@ public class LoginActivity extends ABVLoginActivity {
* ユーザ変更時の初期化
*/
private void changeUserInit() {
//中心温度計の情報維持のため、PreferenceUtil初期化前にデータ取得
String deviceName = getUserPref(AppDefType.UserPrefKey.BLUETOOTH_DEVICE_TEMPERATURE_NAME, "");
String deviceAddress = getUserPref(AppDefType.UserPrefKey.BLUETOOTH_DEVICE_TEMPERATURE_ADDRESS, "");
// bluetoothの情報維持のため、PreferenceUtil初期化前にデータ取得(CHINO機器)
List<BluetoothPairingDeviceInfoDto> bluetoothPairingInfoDtoList = getABVUIDataCache().getPairingBluetoothDeviceInfoList(Arrays.asList(DeviceType.centerThermomete, DeviceType.radiationThermomete));
PreferenceUtil.clear(this);
getABVUIDataCache().clear();
PreferenceUtil.clearUserPref(this);
memberInfoDao.deleteMemberInfo();
//PreferenceUtil初期化後、中心温度計の情報保存
if (deviceAddress.length() != 0) {
putUserPref(AppDefType.UserPrefKey.BLUETOOTH_DEVICE_TEMPERATURE_NAME, deviceName);
putUserPref(AppDefType.UserPrefKey.BLUETOOTH_DEVICE_TEMPERATURE_ADDRESS, deviceAddress);
//PreferenceUtil初期化後、ペアリングの情報保存(CHINO機器)
for (BluetoothPairingDeviceInfoDto bluetoothPairingDeviceInfoDto : bluetoothPairingInfoDtoList) {
getABVUIDataCache().setPairingBluetoothDeviceInfo(bluetoothPairingDeviceInfoDto);
}
contentLogic.deleteContentMarkingData();
......
package jp.agentec.abook.abv.ui.home.activity;
import android.app.Activity;
import android.app.Dialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.provider.Settings;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
import jp.agentec.abook.abv.bl.common.Constant;
import jp.agentec.abook.abv.bl.common.Constant.DeviceType;
import jp.agentec.abook.abv.bl.common.log.Logger;
import jp.agentec.abook.abv.bl.data.dao.AbstractDao;
import jp.agentec.abook.abv.bl.data.dao.SppDeviceDao;
import jp.agentec.abook.abv.bl.dto.BluetoothPairingDeviceInfoDto;
import jp.agentec.abook.abv.bl.dto.SppDeviceDto;
import jp.agentec.abook.abv.cl.util.BleManagerUtil;
import jp.agentec.abook.abv.launcher.android.R;
import jp.agentec.abook.abv.ui.common.activity.ABVUIActivity;
import jp.agentec.abook.abv.ui.common.util.ABVToastUtil;
import jp.agentec.abook.abv.ui.home.adapter.BleListAdapter;
import jp.agentec.abook.abv.ui.home.adapter.BleListRowData;
import jp.agentec.abook.abv.ui.home.adapter.SelectSppDeviceAdapter;
import jp.agentec.abook.abv.ui.home.adapter.common.SectionHeaderData;
import jp.agentec.abook.abv.ui.home.helper.ABookPermissionHelper;
import jp.agentec.adf.util.CollectionUtil;
import jp.agentec.adf.util.StringUtil;
public class SppBluetoothPairingSettingActivity extends ABVUIActivity {
private static final String TAG = "SppBluetoothPairingSettingActivity";
// 定数
private static final int REQUEST_ENABLEBLUETOOTH = 1; // Bluetooth機能の有効化要求時の識別コード
private static final long SCAN_PERIOD = 20000; // スキャン時間。単位はミリ秒。
// メンバー変数
private Handler mHandler; // UIスレッド操作ハンドラ : 「一定時間後にスキャンをやめる処理」で必要
private boolean mScanning = false; // スキャン中かどうかのフラグ
private Button mButton_Scan;
private BleListAdapter mBleListAdapter; // Adapter
private List<BluetoothDevice> mScanDeviceInfoList = new ArrayList<BluetoothDevice>();
private BleManagerUtil bleManagerUtil;
private List<String> mSavedDeviceAddressList = new ArrayList<String>(); //登録した端末アドレス
private BroadcastReceiver mBluetoothSearchReceiver;
// SPP通信端末の選択リストダイアログ
private Dialog mSelectSppDeviceListDialog;
// SPP通信端末のDaoクラス
private SppDeviceDao mSppDeviceDao = AbstractDao.getDao(SppDeviceDao.class);
@Override
protected void onCreate(Bundle savedInstanceState) {
Logger.i(TAG, "onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.pairing_setting);
TextView deviceTitle = (TextView) findViewById(R.id.device_toolbar_title);
deviceTitle.setText(getString(R.string.spp_machine));
// 戻り値の初期化
setResult( Activity.RESULT_CANCELED );
List<SectionHeaderData> sectionList = getSectionListInfo();
List<List<BleListRowData>> rowList = getRowListInfo();
mBleListAdapter = new BleListAdapter( this, sectionList, rowList, new BleListAdapter.BleListAdapterListener() { // ビューアダプターの初期化
@Override
public void onDeleteConnectInfo(BleListRowData rowData) { // 登録されたデバイス情報削除
Logger.d(TAG, String.format("[deleteConnectInfo] title : %s, address : %s", rowData.title, rowData.deviceAddress));
// ペアリング情報をクリアする。
mSppDeviceDao.clearPairingDevice(rowData.deviceAddress);
// 保存済みのアドレスを管理するメンバー変数も削除
mSavedDeviceAddressList.remove(rowData.deviceAddress);
reloadListView();
//スキャン実行中ではない場合はスキャン実行
if (!mScanning) {
startScan();
}
}
});
ListView listView = (ListView) findViewById(R.id.devicelist); // リストビューの取得
listView.setAdapter(mBleListAdapter); // リストビューにビューアダプターをセット
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
Logger.d(TAG, "position = " + position);
BleListRowData bleListRowData = (BleListRowData)parent.getItemAtPosition(position);
// 既に保存されてる場合は何もしない
if (!bleListRowData.isSaved) {
localSaveDeviceInfo(bleListRowData);
}
}
});
// Reload Button
mButton_Scan = (Button)findViewById( R.id.btn_reload );
mButton_Scan.setAllCaps(false);
mButton_Scan.setText(getString(R.string.pairing_search_scan));
mButton_Scan.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mScanning) {
stopScan();
} else {
startScan();
}
}
});
// Bluetoothと接続処理する
bleManagerUtil = new BleManagerUtil(this, null);
bleManagerUtil.startDeviceInfo();
bleManagerUtil.mBluetoothAdapter.startDiscovery();
// UIスレッド操作ハンドラの作成(「一定時間後にスキャンをやめる処理」で使用する)
mHandler = new Handler();
}
// 初回表示時、および、ポーズからの復帰時
@Override
protected void onResume() {
super.onResume();
//画面表示時にスキャン実行
startScan();
}
// 別のアクティビティ(か別のアプリ)に移行したことで、バックグラウンドに追いやられた時
@Override
protected void onPause() {
super.onPause();
// スキャンの停止
stopScan();
}
// 機能の有効化ダイアログの操作結果
@Override
protected void onActivityResult( int requestCode, int resultCode, Intent data ) {
switch (requestCode) {
case REQUEST_ENABLEBLUETOOTH: // Bluetooth有効化要求
if( Activity.RESULT_CANCELED == resultCode ) { // 有効にされなかった
ABVToastUtil.showMakeText(getApplicationContext(), getString(R.string.msg_scan_bluetooth_no_allow), Toast.LENGTH_SHORT);
return;
}
break;
}
super.onActivityResult( requestCode, resultCode, data );
}
// スキャンの開始
private void startScan() {
//BlueTooth許可チェック
if (!requestBluetoothFeature()) return;
LocationManager lm = (LocationManager) this.getSystemService(this.LOCATION_SERVICE);
final boolean gpsEnabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
// GPSの状態を取得(getSystemtServiceからのGPS ON/OFF取得が取れない場合があるため、secureで取得したgpsも判定するため)
final boolean secureLocationGpsEnabled = android.provider.Settings.Secure.getString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED).contains("gps");
//端末側の位置情報許可チェック
if (!(gpsEnabled || secureLocationGpsEnabled)) {
showSimpleAlertDialog(R.string.spp_machine, R.string.msg_location_device_no_allow);
return;
}
ABookPermissionHelper helper = new ABookPermissionHelper(this, Constant.ABookPermissionType.AccessFineLocation, null);
//アプリ側の位置情報許可チェック(置くだけセンサーとLinkingアプリの通信できないため)
if (!helper.checkMultiPermissions(true)) return;
//インテントフィルターとBroadcastReceiverの登録
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
filter.addAction(BluetoothDevice.ACTION_FOUND);
mBluetoothSearchReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (BluetoothDevice.ACTION_FOUND.equals(intent.getAction())) {
// 取得したbluetooth情報を取得
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// 識別商品名に絞る
if (device.getName() != null) {
if (!mSavedDeviceAddressList.contains(device.getAddress())) { //登録されたデバイスの場合、スキャン情報から除外する。
boolean isAdd = true;
for (BluetoothDevice savedDevice : mScanDeviceInfoList) {
if (savedDevice.getAddress().equals(device.getAddress())) {
// スキャンされたデバイス情報リストから一つでも一致する場合、既にスキャンされたと見做し追加しない。
isAdd = false;
}
}
if (isAdd) {
mScanDeviceInfoList.add(device);
}
reloadListView();
}
Logger.d("device.getName() = " + device.getName() + "device.getAddress() = " + device.getAddress());
}
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(intent.getAction())) {
Logger.d("-------ACTION_DISCOVERY_FINISHED");
// startDiscoveryのスキャン時間が12秒であるため、再度スタートさせる(20秒のタイマーが別であるため無限には実行しない)
bleManagerUtil.mBluetoothAdapter.startDiscovery();
}
}
};
registerReceiver(mBluetoothSearchReceiver, filter);
// bluetoothAdapterから発見開始行う(結果はブロードキャストで取得 mBluetoothSearchReceiver)
bleManagerUtil.mBluetoothAdapter.startDiscovery();
// スキャン開始(一定時間後にスキャン停止する)
mHandler.postDelayed( new Runnable() {
@Override
public void run() {
stopScan();
Logger.d(TAG, "scan in 20 sec");
}
}, SCAN_PERIOD );
mScanning = true;
mButton_Scan.setText(getString(R.string.pairing_search_stop));
reloadListView();
Logger.d(TAG, "start scan !!");
}
// スキャンの停止
private void stopScan() {
// 一定期間後にスキャン停止するためのHandlerのRunnableの削除
mHandler.removeCallbacksAndMessages( null );
if (mBluetoothSearchReceiver != null) {
unregisterReceiver(mBluetoothSearchReceiver);
mBluetoothSearchReceiver = null;
}
mScanning = false;
mButton_Scan.setText(getString(R.string.pairing_search_scan));
reloadListView();
Logger.d(TAG, "stop scan !!");
}
/**
* SPP通信の端末選択ダイアログ表示処理
* @param rowData bluetooth情報
*/
private void showSelectSppDeviceListDialog(final BleListRowData rowData) {
if (mSelectSppDeviceListDialog == null) {
mSelectSppDeviceListDialog = new Dialog(this);
mSelectSppDeviceListDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
mSelectSppDeviceListDialog.setCanceledOnTouchOutside(false);
mSelectSppDeviceListDialog.setContentView(R.layout.bluetooth_device_select_dialog);
mSelectSppDeviceListDialog.findViewById(R.id.closeBtn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mSelectSppDeviceListDialog.dismiss();
}
});
}
ListView listView = (ListView) mSelectSppDeviceListDialog.findViewById(R.id.listView1);
final List<SppDeviceDto> sppDeviceDtoList = mSppDeviceDao.getAllSppDevice();
listView.setAdapter(new SelectSppDeviceAdapter(this, sppDeviceDtoList));
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mSelectSppDeviceListDialog.dismiss();
// タップしたポジションの端末情報を取得
SppDeviceDto selectedSppDeviceDto = sppDeviceDtoList.get(position);
// 取得したデータのペアリングが既に存在し、ペアリング情報が一致しない場合上書きと見做す。
if (!StringUtil.isNullOrEmpty(selectedSppDeviceDto.pairingDeviceAddress)) {
if (!selectedSppDeviceDto.pairingDeviceAddress.equals(rowData.deviceAddress)) {
mSavedDeviceAddressList.remove(selectedSppDeviceDto.pairingDeviceAddress);
}
}
// ペアリング情報をセットして、更新する
selectedSppDeviceDto.pairingDeviceName = rowData.title;
selectedSppDeviceDto.pairingDeviceAddress = rowData.deviceAddress;
mSppDeviceDao.updateSppDevice(sppDeviceDtoList.get(position));
// スキャンされた情報から保存されたのでdeviceは削除
for (BluetoothDevice savedScanDevice : mScanDeviceInfoList) {
if (savedScanDevice.getAddress().equals(rowData.deviceAddress)) {
mScanDeviceInfoList.remove(savedScanDevice);
break;
}
}
//画面リロード
reloadListView();
}
});
if (mSelectSppDeviceListDialog != null) {
mSelectSppDeviceListDialog.show();
}
}
private void localSaveDeviceInfo(BleListRowData bleListRowData) {
// アドレスが保存されてる場合無視
if (!mSavedDeviceAddressList.contains(bleListRowData.deviceAddress)) {
// 選択ダイアログ表示
showSelectSppDeviceListDialog(bleListRowData);
}
}
// 閉じるボタンの処理
public void onClickCloseView(View v) {
finish();
}
/**
* ListViewのSectionデータを作成する。
* @return Rowデータリスト
*/
private List<SectionHeaderData> getSectionListInfo() {
List<SectionHeaderData> sectionList = new ArrayList<>();
// SPP通信端末の情報を取得
List<SppDeviceDto> sppDeviceDtoList = mSppDeviceDao.getPairingDeviceList();
if (CollectionUtil.isNotEmpty(sppDeviceDtoList)) {
for (SppDeviceDto dto : sppDeviceDtoList) {
sectionList.add(new SectionHeaderData(String.format(getString(R.string.pairing_save_machine), dto.sppDeviceName)));
}
}
// その他のヘッダー情報追加
sectionList.add(new SectionHeaderData(String.format(getString(mScanning ? R.string.pairing_other_machine_searching : R.string.pairing_other_machine), getString(R.string.spp_machine))));
return sectionList;
}
/**
* ListViewのRowデータを作成する。
* @return Rowデータリスト
*/
private List<List<BleListRowData>> getRowListInfo() {
List<List<BleListRowData>> rowList = new ArrayList<List<BleListRowData>>();
// SPP通信機器のペアリングデバイス情報を取得
List<SppDeviceDto> sppDeviceDtoList = mSppDeviceDao.getPairingDeviceList();
if (CollectionUtil.isNotEmpty(sppDeviceDtoList)) {
for (SppDeviceDto dto : sppDeviceDtoList) {
List<BleListRowData> rowDataList = new ArrayList<BleListRowData>();
rowDataList.add(new BleListRowData(dto.pairingDeviceName, dto.pairingDeviceAddress, true));
rowList.add(rowDataList);
// 保存された情報であれば、メンバー変数で管理するため、listに追加、既に存在する場合は何もしない
if (!mSavedDeviceAddressList.contains(dto.pairingDeviceAddress)) {
mSavedDeviceAddressList.add(dto.pairingDeviceAddress);
}
}
}
if (mScanDeviceInfoList.size() == 0) {
List<BleListRowData> scanRowDataList = new ArrayList<BleListRowData>();
BleListRowData scanRowData = new BleListRowData("" , "" );
scanRowDataList.add(scanRowData);
rowList.add(scanRowDataList);
} else {
List<BleListRowData> scanRowDataList = new ArrayList<BleListRowData>();
for (BluetoothDevice bleDevice : mScanDeviceInfoList) {
BleListRowData scanRowData = new BleListRowData(bleDevice.getName(), bleDevice.getAddress(), false);
scanRowDataList.add(scanRowData);
}
rowList.add(scanRowDataList);
}
return rowList;
}
/**
* ListViewをリロードする。
*/
private void reloadListView() {
List<SectionHeaderData> sectionList = getSectionListInfo();
List<List<BleListRowData>> rowList = getRowListInfo();
mBleListAdapter.setItem(sectionList, rowList);
}
// デバイスのBluetooth機能の有効化要求
private boolean requestBluetoothFeature() {
if(bleManagerUtil.mBluetoothAdapter.isEnabled()) {
return true;
}
// デバイスのBluetooth機能が有効になっていないときは、有効化要求(ダイアログ表示)
Intent enableBtIntent = new Intent( BluetoothAdapter.ACTION_REQUEST_ENABLE );
startActivityForResult( enableBtIntent, REQUEST_ENABLEBLUETOOTH );
return false;
}
}
......@@ -12,17 +12,13 @@ import jp.agentec.abook.abv.ui.home.adapter.common.BaseSectionAdapter;
import jp.agentec.abook.abv.ui.home.adapter.common.IndexPath;
import jp.agentec.abook.abv.ui.home.adapter.common.SectionHeaderData;
/**
* Created by kim, changgyun on 2018/11/15.
*/
public class BleListAdapter extends BaseSectionAdapter<SectionHeaderData, BleListRowData> {
private static final String TAG = "BleListAdapter";
protected BleListAdapter.BleListAdapterListener listener;
public interface BleListAdapterListener {
// 登録されたデバイス情報削除
void onDeleteConnectInfo();
// 登録されたデバイス情報削除(bluetooth情報を引数としてセット)
void onDeleteConnectInfo(BleListRowData rowData);
}
public BleListAdapter(Context context, List<SectionHeaderData> sectionList,
......@@ -56,26 +52,34 @@ public class BleListAdapter extends BaseSectionAdapter<SectionHeaderData, BleLis
if (convertView == null) {
convertView = inflater.inflate(R.layout.ble_section_list_row, null);
holder = new ListRowViewHolder();
// bluetoothのデバイス名
holder.bl_title = (TextView) convertView.findViewById(R.id.bl_title);
// 該当通信機器の名(中心温度計・放射温度計)
holder.sub_title = (TextView) convertView.findViewById(R.id.sub_title);
// 削除ボタン
holder.bl_deleteBtn = (Button) convertView.findViewById(R.id.bl_deleteBtn);
convertView.setTag(holder);
} else {
holder = (ListRowViewHolder) convertView.getTag();
}
BleListRowData rowData = rowList.get(indexPath.section).get(indexPath.row);
final BleListRowData rowData = rowList.get(indexPath.section).get(indexPath.row);
holder.bl_title.setText(rowData.title);
//スキャンされた温度計表示時に削除ボタンと接続ステータス非表示
if (!rowData.isSaved) {
holder.bl_deleteBtn.setVisibility(View.INVISIBLE);
} else {
if (rowData.isSaved) {
// 既に保存されてる場合、削除ボタン表示・機器名は非表示
holder.sub_title.setVisibility(View.GONE);
holder.bl_deleteBtn.setVisibility(View.VISIBLE);
holder.bl_deleteBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
listener.onDeleteConnectInfo();
listener.onDeleteConnectInfo(rowData);
}
});
} else {
// スキャンされたbluetooth機器表示時に削除ボタンと接続ステータス非表示
holder.bl_deleteBtn.setVisibility(View.GONE);
holder.sub_title.setVisibility(View.VISIBLE);
holder.sub_title.setText(rowData.subTitle);
}
return convertView;
}
......@@ -87,6 +91,7 @@ public class BleListAdapter extends BaseSectionAdapter<SectionHeaderData, BleLis
static class ListRowViewHolder {
TextView bl_title;
TextView sub_title;
Button bl_deleteBtn;
}
......
......@@ -17,9 +17,9 @@ public class BleListRowData extends SectionRowData {
}
/**
* 中心温度計
* @param title 温度計
* @param deviceAddress デバイスアドレス
* bluetooth情報
* @param title bluetoothデバイス
* @param deviceAddress bluetoothデバイスアドレス
* @param isSaved 登録状態
*/
public BleListRowData(String title, String deviceAddress, boolean isSaved) {
......@@ -27,4 +27,17 @@ public class BleListRowData extends SectionRowData {
this.deviceAddress = deviceAddress;
this.isSaved = isSaved;
}
/**
* bluetooth情報
* @param title bluetoothデバイス名
* @param subTitle 通信機器名(中心温度計・放射温度計)
* @param deviceAddress bluetoothデバイスアドレス
* @param isSaved 登録状態
*/
public BleListRowData(String title, String subTitle, String deviceAddress, boolean isSaved) {
super(title, subTitle);
this.deviceAddress = deviceAddress;
this.isSaved = isSaved;
}
}
package jp.agentec.abook.abv.ui.home.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.List;
import jp.agentec.abook.abv.bl.dto.FixPushMessageDto;
import jp.agentec.abook.abv.bl.dto.SppDeviceDto;
import jp.agentec.abook.abv.launcher.android.R;
/**
* SPP端末選択アダプタ用
*/
public class SelectSppDeviceAdapter extends ArrayAdapter<SppDeviceDto> {
private LayoutInflater mInflater;
private List<SppDeviceDto> mSppDeviceDtoList;
public SelectSppDeviceAdapter(Context context, List<SppDeviceDto> sppDeviceDtoList) {
super(context, 0, sppDeviceDtoList);
mSppDeviceDtoList = sppDeviceDtoList;
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.item_spp_device_select, parent, false);
holder = new ViewHolder();
holder.tvSppDeviceName = (TextView) convertView.findViewById(R.id.spp_device_name);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final SppDeviceDto sppDeviceDto = getItem(position);
if (sppDeviceDto != null) {
holder.tvSppDeviceName.setText(sppDeviceDto.sppDeviceName);
}
return convertView;
}
private static class ViewHolder {
TextView tvSppDeviceName;
}
}
......@@ -40,7 +40,6 @@ import jp.agentec.abook.abv.ui.common.constant.ErrorMessage;
import jp.agentec.abook.abv.ui.common.dialog.ABookAlertDialog;
import jp.agentec.abook.abv.ui.common.util.AlertDialogUtil;
import jp.agentec.abook.abv.ui.common.util.PatternStringUtil;
import jp.agentec.abook.abv.ui.home.helper.ABookCheckWebViewHelper;
import jp.agentec.abook.abv.ui.home.helper.ActivityHandlingHelper;
import jp.agentec.abook.abv.ui.home.helper.ContentViewHelper;
import jp.agentec.adf.util.DateTimeFormat;
......@@ -148,7 +147,7 @@ public class ParentWebViewActivity extends ABVCheckContentViewActivity {
}
progressDialog.setProgress(0);
//中心温度計接続を切る
bleThermometerDisconnect();
bleManagerDisconnect();
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment