├── ic_launcher-web.png
├── libs
└── android-support-v4.jar
├── res
├── drawable-hdpi
│ └── ic_launcher.png
├── drawable-mdpi
│ └── ic_launcher.png
├── drawable-xhdpi
│ └── ic_launcher.png
├── drawable-xxhdpi
│ └── ic_launcher.png
├── values-sw600dp
│ └── dimens.xml
├── values
│ ├── dimens.xml
│ ├── strings.xml
│ ├── styles.xml
│ └── colors.xml
├── values-sw720dp-land
│ └── dimens.xml
├── values-v11
│ └── styles.xml
├── values-v14
│ └── styles.xml
├── menu
│ └── main.xml
├── layout
│ ├── adapter_device_name.xml
│ ├── activity_main.xml
│ ├── fragment_main_dummy.xml
│ ├── activity_device_list.xml
│ └── fragment_settings.xml
├── drawable
│ └── form_button_selector.xml
└── values-ko
│ └── strings.xml
├── README.md
├── src
└── com
│ └── hardcopy
│ └── btchat
│ ├── http
│ ├── HttpListener.java
│ ├── HttpInterface.java
│ ├── HttpAsyncTask.java
│ ├── HttpFileAsyncTask.java
│ └── HttpRequester.java
│ ├── fragments
│ ├── IFragmentListener.java
│ ├── LLSettingsFragment.java
│ ├── FragmentAdapter.java
│ └── ExampleFragment.java
│ ├── utils
│ ├── Constants.java
│ ├── RecycleUtils.java
│ ├── Logs.java
│ ├── AppSettings.java
│ └── Utils.java
│ ├── contents
│ ├── CommandParser.java
│ └── DBHelper.java
│ ├── bluetooth
│ ├── TransactionReceiver.java
│ ├── ConnectionInfo.java
│ ├── TransactionBuilder.java
│ └── BluetoothManager.java
│ ├── service
│ ├── ServiceMonitoring.java
│ └── BTCTemplateService.java
│ ├── DeviceListActivity.java
│ └── MainActivity.java
├── AndroidManifest.xml
└── LICENSE
/ic_launcher-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/godstale/BTChat/HEAD/ic_launcher-web.png
--------------------------------------------------------------------------------
/libs/android-support-v4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/godstale/BTChat/HEAD/libs/android-support-v4.jar
--------------------------------------------------------------------------------
/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/godstale/BTChat/HEAD/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/godstale/BTChat/HEAD/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/godstale/BTChat/HEAD/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/godstale/BTChat/HEAD/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/values-sw600dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 16dp
5 | 16dp
6 |
7 |
8 |
--------------------------------------------------------------------------------
/res/values-sw720dp-land/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 | 128dp
8 |
9 |
10 |
--------------------------------------------------------------------------------
/res/values-v11/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/res/values-v14/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # BTChat
2 | BT chatting between arduino and android. (supports IoT feature)
3 |
4 |
5 | 아두이노와 블루투스로 연결해서 간단한 채팅을 할 수 있도록 작성한 앱입니다. IoT를 위한 HTTP Request 기능도 포함하고 있습니다.
6 |
7 | 좌측상단 블루투스 연결 버튼을 눌러 기기를 검색한 후 페어링을 할 수 있습니다. 페어링이 되면 이후 블루투스로 들어오는 문자열을 화면에 표시해줍니다. 간단한 채팅이나 로그 모니터링 용으로 사용할 수 있습니다.
8 | IoT 지원을 위해 특정 문자열이 들어올 경우 자동으로 HTTP Request를 보낼 수 있도록 작성되었습니다. 아래와 같은 문자열을 인식합니다.
9 |
10 | Whenever BTChat find message like : thingspeak:key=xxx&field1=xxx[*]
11 |
12 | Automatically sends a HTTP Request : http://184.106.153.149/update?key=xxx&field1=xxx
13 |
14 |
--------------------------------------------------------------------------------
/res/menu/main.xml:
--------------------------------------------------------------------------------
1 |
17 |
--------------------------------------------------------------------------------
/res/layout/adapter_device_name.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
--------------------------------------------------------------------------------
/src/com/hardcopy/btchat/http/HttpListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Retro Watch - Open source smart watch project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.hardcopy.btchat.http;
18 |
19 | public interface HttpListener {
20 | // Callback methods
21 | public void OnReceiveHttpResponse(int type, String strResult, int resultCode);
22 | public void OnReceiveFileResponse(int type, String id, String filepath, String url, int resultCode);
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/src/com/hardcopy/btchat/fragments/IFragmentListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Bluetooth Connection Template
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.hardcopy.btchat.fragments;
18 |
19 | public interface IFragmentListener {
20 | public static final int CALLBACK_RUN_IN_BACKGROUND = 1;
21 | public static final int CALLBACK_SEND_MESSAGE = 2;
22 |
23 | public void OnFragmentCallback(int msgType, int arg0, int arg1, String arg2, String arg3, Object arg4);
24 | }
25 |
--------------------------------------------------------------------------------
/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
13 |
14 |
15 |
16 |
22 |
28 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/res/drawable/form_button_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
18 |
19 |
20 | -
21 |
22 |
23 |
24 |
25 |
26 |
27 | -
28 |
29 |
30 |
31 |
32 |
33 |
34 | -
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/src/com/hardcopy/btchat/utils/Constants.java:
--------------------------------------------------------------------------------
1 | package com.hardcopy.btchat.utils;
2 |
3 | public class Constants {
4 |
5 | // Service handler message key
6 | public static final String SERVICE_HANDLER_MSG_KEY_DEVICE_NAME = "device_name";
7 | public static final String SERVICE_HANDLER_MSG_KEY_DEVICE_ADDRESS = "device_address";
8 | public static final String SERVICE_HANDLER_MSG_KEY_TOAST = "toast";
9 |
10 | // Preference
11 | public static final String PREFERENCE_NAME = "btchatPref";
12 | public static final String PREFERENCE_KEY_BG_SERVICE = "BackgroundService";
13 | public static final String PREFERENCE_CONN_INFO_ADDRESS = "device_address";
14 | public static final String PREFERENCE_CONN_INFO_NAME = "device_name";
15 |
16 | // Message types sent from Service to Activity
17 | public static final int MESSAGE_CMD_ERROR_NOT_CONNECTED = -50;
18 |
19 | public static final int MESSAGE_BT_STATE_INITIALIZED = 1;
20 | public static final int MESSAGE_BT_STATE_LISTENING = 2;
21 | public static final int MESSAGE_BT_STATE_CONNECTING = 3;
22 | public static final int MESSAGE_BT_STATE_CONNECTED = 4;
23 | public static final int MESSAGE_BT_STATE_ERROR = 10;
24 |
25 | public static final int MESSAGE_READ_CHAT_DATA = 201;
26 |
27 |
28 |
29 | // Intent request codes
30 | public static final int REQUEST_CONNECT_DEVICE = 1;
31 | public static final int REQUEST_ENABLE_BT = 2;
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/res/layout/fragment_main_dummy.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
15 |
16 |
20 |
21 |
28 |
29 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/src/com/hardcopy/btchat/utils/RecycleUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.hardcopy.btchat.utils;
18 |
19 | import android.view.View;
20 | import android.view.ViewGroup;
21 | import android.widget.AdapterView;
22 | import android.widget.ImageView;
23 |
24 | /**
25 | * @author givenjazz
26 | */
27 |
28 | public class RecycleUtils {
29 |
30 | private RecycleUtils(){};
31 |
32 | public static void recursiveRecycle(View root) {
33 | if (root == null)
34 | return;
35 |
36 | // root.setBackgroundDrawable(null); // Deprecated
37 | if (root instanceof ViewGroup) {
38 | ViewGroup group = (ViewGroup)root;
39 | int count = group.getChildCount();
40 | for (int i = 0; i < count; i++) {
41 | recursiveRecycle(group.getChildAt(i));
42 | }
43 |
44 | if (!(root instanceof AdapterView)) {
45 | group.removeAllViews();
46 | }
47 | }
48 |
49 | if (root instanceof ImageView) {
50 | ((ImageView)root).setImageDrawable(null);
51 | }
52 | root = null;
53 |
54 | return;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/com/hardcopy/btchat/utils/Logs.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Bluetooth Connection Template
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.hardcopy.btchat.utils;
18 |
19 | import android.util.Log;
20 |
21 | public class Logs {
22 |
23 | private static final String TAG = "BTC Template";
24 | public static boolean mIsEnabled = true;
25 |
26 |
27 | public static void v(String msg) {
28 | if(mIsEnabled) {
29 | Log.v(TAG, msg);
30 | }
31 | }
32 |
33 | public static void v(String tag, String msg) {
34 | if(mIsEnabled) {
35 | Log.v(tag, msg);
36 | }
37 | }
38 |
39 | public static void d(String msg) {
40 | if(mIsEnabled) {
41 | Log.d(TAG, msg);
42 | }
43 | }
44 |
45 | public static void d(String tag, String msg) {
46 | if(mIsEnabled) {
47 | Log.d(tag, msg);
48 | }
49 | }
50 |
51 | public static void e(String msg) {
52 | if(mIsEnabled) {
53 | Log.e(TAG, msg);
54 | }
55 | }
56 |
57 | public static void e(String tag, String msg) {
58 | if(mIsEnabled) {
59 | Log.e(tag, msg);
60 | }
61 | }
62 |
63 | public static void i(String msg) {
64 | if(mIsEnabled) {
65 | Log.e(TAG, msg);
66 | }
67 | }
68 |
69 | public static void i(String tag, String msg) {
70 | if(mIsEnabled) {
71 | Log.e(tag, msg);
72 | }
73 | }
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/res/values-ko/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | BT Chat
5 | BT Chat Service
6 |
7 |
8 |
9 | 설정
10 | 백그라운드로 실행
11 | \n앱에서 아래와 같은 형식의 메시지를 받으면 자동으로 지정된 서버로 HTTP request를 보내줍니다.
12 | \n\nFind more at http://www.hardcopyworld.com
13 |
14 |
15 | BT Chat
16 | 설정
17 |
18 | 전송
19 |
20 |
21 | Bluetooth
22 |
23 | 초기화 중...
24 | 대기중.. (우측 상단 아이콘으로 수동 검색)
25 | 연결중...
26 | 연결됨
27 | error
28 |
29 | 블루투스가 꺼져 있습니다. 폰의 Settings 에서 블루투스를 활성화 하세요.
30 | 전송 실패
31 |
32 |
33 | 장치 검색중...
34 | 연결할 장치 선택
35 | 페어링 된 장치가 없습니다.
36 | 검색된 장치가 없습니다.
37 | 페어링 된 장치들
38 | 사용가능한 다른 장치들
39 | 장치 스캔
40 |
41 |
42 | 장치에 연결
43 | Make\ndiscoverable
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
12 |
13 |
14 |
15 |
20 |
21 |
22 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
37 |
38 |
39 |
40 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | BT Chat
5 | BT Chat Service
6 |
7 |
8 | App Settings
9 | Run in background
10 | \nBT Chat automatically sends HTTP GET request to specified server if there is a string like below.
11 | \n\nFind more at http://www.hardcopyworld.com
12 |
13 |
14 | BT Chat
15 | Settings
16 | Send
17 |
18 |
19 | Bluetooth
20 | initializing
21 | waiting.. (select a device manually)
22 | connecting
23 | connected
24 | error
25 | Bluetooth is not enabled. Set the bluetooth on at phone settings.
26 | Transaction failed
27 |
28 |
29 | Scanning for devices...
30 | Select a device to connect
31 | No devices have been paired
32 | No devices found
33 | Paired Devices
34 | Other Available Devices
35 | Scan for devices
36 |
37 |
38 | Connect\na device
39 | Make\ndiscoverable
40 |
41 |
--------------------------------------------------------------------------------
/src/com/hardcopy/btchat/contents/CommandParser.java:
--------------------------------------------------------------------------------
1 | package com.hardcopy.btchat.contents;
2 |
3 | import com.hardcopy.btchat.utils.Logs;
4 |
5 | public class CommandParser {
6 |
7 | public static final int COMMAND_NONE = -1;
8 | public static final int COMMAND_THINGSPEAK = 1;
9 |
10 | private static final String THINGSPEAK_PREFIX = "thingspeak:";
11 | private static final String COMMAND_SUFFIX = "[*]";
12 |
13 | private StringBuilder mReceivedString;
14 | private int mCommand = COMMAND_NONE;
15 | private String mParameters;
16 |
17 | public CommandParser() {
18 | mReceivedString = new StringBuilder();
19 | }
20 |
21 |
22 | public int setString(String message) {
23 | mReceivedString.append(message);
24 | return checkCommand();
25 | }
26 |
27 | public int getCommand() {
28 | return mCommand;
29 | }
30 |
31 | public String getParameterString() {
32 | return mParameters;
33 | }
34 |
35 | public void resetParser() {
36 | mCommand = COMMAND_NONE;
37 | mParameters = null;
38 | }
39 |
40 |
41 |
42 | private int checkCommand() {
43 | int prefixIndex = mReceivedString.lastIndexOf(THINGSPEAK_PREFIX);
44 | if(prefixIndex > -1) {
45 | //Logs.d("# found thingspeak prefix");
46 | // Check if there is suffix string [*]
47 | int suffixIndex = mReceivedString.lastIndexOf(COMMAND_SUFFIX);
48 | if(suffixIndex > -1) {
49 | //Logs.d("# found [*] suffix");
50 | if(prefixIndex + THINGSPEAK_PREFIX.length() <= suffixIndex) {
51 | // cut the parameter string from buffer
52 | mCommand = COMMAND_THINGSPEAK;
53 | mParameters = mReceivedString.substring(prefixIndex + THINGSPEAK_PREFIX.length(), suffixIndex);
54 | mReceivedString = new StringBuilder();
55 | //Logs.d("# parameters = "+mParameters);
56 | return COMMAND_THINGSPEAK;
57 | }
58 | }
59 | } else {
60 |
61 | }
62 |
63 | // Nothing found... Empty buffer if it's too big
64 | if(mReceivedString.length() > 1000) {
65 | mReceivedString = new StringBuilder(mReceivedString.substring(mReceivedString.length() - 200));
66 | }
67 |
68 | mCommand = COMMAND_NONE;
69 |
70 | return COMMAND_NONE;
71 | }
72 |
73 |
74 |
75 |
76 | }
77 |
--------------------------------------------------------------------------------
/res/layout/activity_device_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
21 |
30 |
36 |
45 |
51 |
56 |
--------------------------------------------------------------------------------
/src/com/hardcopy/btchat/http/HttpInterface.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Retro Watch - Open source smart watch project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.hardcopy.btchat.http;
18 |
19 | public interface HttpInterface {
20 |
21 | //---------- HTTP Requester status
22 | public static final int REQUESTER_STATUS_ERROR = -1;
23 | public static final int REQUESTER_STATUS_START = 1;
24 | public static final int REQUESTER_STATUS_BUSY = 2;
25 | public static final int REQUESTER_STATUS_COMPLETE = 3;
26 | public static final int REQUESTER_STATUS_PENDING = 4;
27 |
28 | //---------- HTTP Request message type
29 | public static final int MSG_HTTP_RESULT_FAIL = 0;
30 | public static final int MSG_HTTP_RESULT_OK = 1;
31 |
32 | //---------- HTTP response code
33 | public static final int MSG_HTTP_RESULT_CODE_OK = 0;
34 | public static final int MSG_HTTP_RESULT_CODE_TIMEOUT = 1;
35 | public static final int MSG_HTTP_RESULT_CODE_INVALID_URL = 2;
36 | public static final int MSG_HTTP_RESULT_CODE_INVALID_REQUEST = 3;
37 | public static final int MSG_HTTP_RESULT_CODE_SERVER_NOT_FOUND = 4;
38 | public static final int MSG_HTTP_RESULT_CODE_INTERNAL_SERVER_ERROR = 5;
39 | public static final int MSG_HTTP_RESULT_CODE_ERROR_UNKNOWN = 6;
40 | public static final int MSG_HTTP_RESULT_CODE_ERROR_REQUEST_EXCEPTION = 7;
41 |
42 | //---------- Request type (GET or POST or FILE)
43 | public static final int REQUEST_TYPE_GET = 1;
44 | public static final int REQUEST_TYPE_POST = 2;
45 | public static final int REQUEST_TYPE_FILE = 3;
46 |
47 | public static final String REQUEST_TYPE_GET_STRING = "GET";
48 | public static final String REQUEST_TYPE_POST_STRING = "POST";
49 |
50 | //---------- HTTP Request encoding type
51 | public static final String ENCODING_TYPE_EUC_KR = "euc-kr";
52 | public static final String ENCODING_TYPE_UTF_8 = "utf-8";
53 |
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/res/layout/fragment_settings.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
14 |
15 |
21 |
22 |
23 |
28 |
35 |
41 |
42 |
43 |
44 |
50 |
51 |
52 |
58 |
59 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/src/com/hardcopy/btchat/utils/AppSettings.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Bluetooth Connection Template
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.hardcopy.btchat.utils;
18 |
19 | import android.content.Context;
20 | import android.content.SharedPreferences;
21 |
22 | public class AppSettings {
23 |
24 | // Constants
25 | public static final int SETTINGS_BACKGROUND_SERVICE = 1;
26 |
27 |
28 | private static boolean mIsInitialized = false;
29 | private static Context mContext;
30 |
31 | // Setting values
32 | private static boolean mUseBackgroundService;
33 |
34 |
35 | public static void initializeAppSettings(Context c) {
36 | if(mIsInitialized)
37 | return;
38 |
39 | mContext = c;
40 |
41 | // Load setting values from preference
42 | mUseBackgroundService = loadBgService();
43 |
44 | mIsInitialized = true;
45 | }
46 |
47 | // Remember setting value
48 | public static void setSettingsValue(int type, boolean boolValue, int intValue, String stringValue) {
49 | if(mContext == null)
50 | return;
51 |
52 | SharedPreferences prefs = mContext.getSharedPreferences(Constants.PREFERENCE_NAME, Context.MODE_PRIVATE);
53 | SharedPreferences.Editor editor = prefs.edit();
54 | switch(type) {
55 | case SETTINGS_BACKGROUND_SERVICE:
56 | editor.putBoolean(Constants.PREFERENCE_KEY_BG_SERVICE, boolValue);
57 | editor.commit();
58 | mUseBackgroundService = boolValue;
59 | break;
60 | default:
61 | editor.commit();
62 | break;
63 | }
64 | }
65 |
66 | /**
67 | * Load 'Run in background' setting value from preferences
68 | * @return boolean is true
69 | */
70 | public static boolean loadBgService() {
71 | SharedPreferences prefs = mContext.getSharedPreferences(Constants.PREFERENCE_NAME, Context.MODE_PRIVATE);
72 | boolean isTrue = prefs.getBoolean(Constants.PREFERENCE_KEY_BG_SERVICE, false);
73 | return isTrue;
74 | }
75 |
76 | /**
77 | * Returns 'Run in background' setting value
78 | * @return boolean is true
79 | */
80 | public static boolean getBgService() {
81 | return mUseBackgroundService;
82 | }
83 |
84 | }
85 |
--------------------------------------------------------------------------------
/src/com/hardcopy/btchat/bluetooth/TransactionReceiver.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Bluetooth Connection Template
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.hardcopy.btchat.bluetooth;
18 |
19 | import java.util.ArrayList;
20 |
21 | import android.os.Handler;
22 |
23 | /**
24 | * Parse stream and extract accel data
25 | * @author Administrator
26 | */
27 | public class TransactionReceiver {
28 | private static final String TAG = "TransactionReceiver";
29 |
30 | private static final int PARSE_MODE_ERROR = 0;
31 | private static final int PARSE_MODE_WAIT_START_BYTE = 1;
32 | private static final int PARSE_MODE_WAIT_COMMAND = 2;
33 | private static final int PARSE_MODE_WAIT_DATA = 3;
34 | private static final int PARSE_MODE_WAIT_END_BYTE = 4;
35 | private static final int PARSE_MODE_COMPLETED = 101;
36 |
37 | private Handler mHandler = null;
38 |
39 |
40 |
41 | public TransactionReceiver(Handler h) {
42 | mHandler = h;
43 | reset();
44 | }
45 |
46 |
47 | /**
48 | * Reset transaction receiver.
49 | */
50 | public void reset() {
51 | }
52 |
53 | /**
54 | * Set bytes to parse
55 | * This method automatically calls parseStream()
56 | * @param buffer
57 | * @param count
58 | */
59 | public void setByteArray(byte[] buffer, int count) {
60 | parseStream(buffer, count);
61 | }
62 |
63 | /**
64 | * After parsing bytes received, transaction receiver makes object instance.
65 | * This method returns parsed results
66 | * @return Object parsed object
67 | */
68 | public Object getObject() {
69 | // TODO: return what you want
70 | return null;
71 | }
72 |
73 | /**
74 | * Caching received stream and parse byte array
75 | * @param buffer byte array to parse
76 | * @param count byte array size
77 | */
78 | public void parseStream(byte[] buffer, int count) {
79 | if(buffer != null && buffer.length > 0 && count > 0) {
80 | for(int i=0; i < buffer.length && i < count; i++) {
81 |
82 | // Parse received data
83 | // Protocol description -----------------------------------------------------------
84 | // Describe brief info about protocol
85 |
86 | // TODO: parse buffer
87 |
88 |
89 | } // End of for loop
90 | } // End of if()
91 | } // End of parseStream()
92 |
93 |
94 | }
95 |
--------------------------------------------------------------------------------
/src/com/hardcopy/btchat/fragments/LLSettingsFragment.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Bluetooth Connection Template
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.hardcopy.btchat.fragments;
18 |
19 | import com.hardcopy.btchat.utils.AppSettings;
20 | import com.hardcopy.btchat.R;
21 | import com.hardcopy.btchat.R.id;
22 | import com.hardcopy.btchat.R.layout;
23 |
24 | import android.content.Context;
25 | import android.os.Bundle;
26 | import android.support.v4.app.Fragment;
27 | import android.text.Editable;
28 | import android.text.TextWatcher;
29 | import android.view.LayoutInflater;
30 | import android.view.View;
31 | import android.view.ViewGroup;
32 | import android.widget.CheckBox;
33 | import android.widget.CompoundButton;
34 | import android.widget.CompoundButton.OnCheckedChangeListener;
35 | import android.widget.EditText;
36 | import android.widget.TextView;
37 |
38 | public class LLSettingsFragment extends Fragment {
39 |
40 | private Context mContext = null;
41 | private IFragmentListener mFragmentListener = null;
42 |
43 | private CheckBox mCheckBackground;
44 | private TextView mTextIot;
45 |
46 |
47 | public LLSettingsFragment(Context c, IFragmentListener l) {
48 | mContext = c;
49 | mFragmentListener = l;
50 | }
51 |
52 | @Override
53 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
54 |
55 | AppSettings.initializeAppSettings(mContext);
56 |
57 | View rootView = inflater.inflate(R.layout.fragment_settings, container, false);
58 |
59 | // 'Run in background' setting
60 | mCheckBackground = (CheckBox) rootView.findViewById(R.id.check_background_service);
61 | mCheckBackground.setChecked(AppSettings.getBgService());
62 | mCheckBackground.setOnCheckedChangeListener(new OnCheckedChangeListener() {
63 | @Override
64 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
65 | AppSettings.setSettingsValue(AppSettings.SETTINGS_BACKGROUND_SERVICE, isChecked, 0, null);
66 | mFragmentListener.OnFragmentCallback(IFragmentListener.CALLBACK_RUN_IN_BACKGROUND, 0, 0, null, null,null);
67 | }
68 | });
69 |
70 | mTextIot = (TextView) rootView.findViewById(R.id.text_iot_guide);
71 | mTextIot.append("\n\nthingspeak:key=xxx&field1=xxx[*]\n\n-> HTTP request: http://184.106.153.149/update?key=xxx&field1=xxx");
72 |
73 |
74 | return rootView;
75 | }
76 |
77 |
78 | }
79 |
--------------------------------------------------------------------------------
/src/com/hardcopy/btchat/bluetooth/ConnectionInfo.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Bluetooth Connection Template
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.hardcopy.btchat.bluetooth;
18 |
19 | import com.hardcopy.btchat.utils.Constants;
20 |
21 | import android.content.Context;
22 | import android.content.SharedPreferences;
23 |
24 | /**
25 | * Remember connection informations for future use
26 | */
27 | public class ConnectionInfo {
28 |
29 | // Constants
30 |
31 | // Instance
32 | private static ConnectionInfo mInstance = null;
33 |
34 | private Context mContext;
35 |
36 | // Target device's MAC address
37 | private String mDeviceAddress = null;
38 | // Name of the connected device
39 | private String mDeviceName = null;
40 |
41 |
42 | private ConnectionInfo(Context c) {
43 | mContext = c;
44 |
45 | SharedPreferences prefs = mContext.getSharedPreferences(Constants.PREFERENCE_NAME, Context.MODE_PRIVATE);
46 | mDeviceAddress = prefs.getString(Constants.PREFERENCE_CONN_INFO_ADDRESS, null);
47 | mDeviceName = prefs.getString(Constants.PREFERENCE_CONN_INFO_NAME, null);
48 | }
49 |
50 | /**
51 | * Single pattern
52 | */
53 | public synchronized static ConnectionInfo getInstance(Context c) {
54 | if(mInstance == null) {
55 | if(c != null)
56 | mInstance = new ConnectionInfo(c);
57 | else
58 | return null;
59 | }
60 | return mInstance;
61 | }
62 |
63 | /**
64 | * Reset connection info
65 | */
66 | public void resetConnectionInfo() {
67 | mDeviceAddress = null;
68 | mDeviceName = null;
69 | }
70 |
71 | /**
72 | * Get saved device name
73 | * @return String device name
74 | */
75 | public String getDeviceName() {
76 | return mDeviceName;
77 | }
78 |
79 | /**
80 | * Remember device name for future use
81 | * @param name device name
82 | */
83 | public void setDeviceName(String name) {
84 | mDeviceName = name;
85 |
86 | // At this time, connection is established successfully.
87 | // Save connection info in shared preference.
88 | SharedPreferences prefs = mContext.getSharedPreferences(Constants.PREFERENCE_NAME, Context.MODE_PRIVATE);
89 | SharedPreferences.Editor editor = prefs.edit();
90 | editor.putString(Constants.PREFERENCE_CONN_INFO_ADDRESS, mDeviceAddress);
91 | editor.putString(Constants.PREFERENCE_CONN_INFO_NAME, mDeviceName);
92 | editor.commit();
93 | }
94 |
95 | /**
96 | * Get device address string
97 | * @return String device address
98 | */
99 | public String getDeviceAddress() {
100 | return mDeviceAddress;
101 | }
102 |
103 | /**
104 | * Set device address
105 | * @param address device address
106 | */
107 | public void setDeviceAddress(String address) {
108 | mDeviceAddress = address;
109 | }
110 |
111 | }
112 |
--------------------------------------------------------------------------------
/src/com/hardcopy/btchat/fragments/FragmentAdapter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Bluetooth Connection Template
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.hardcopy.btchat.fragments;
18 |
19 | import java.util.Locale;
20 |
21 | import com.hardcopy.btchat.R;
22 | import com.hardcopy.btchat.R.string;
23 |
24 | import android.content.Context;
25 | import android.os.Bundle;
26 | import android.os.Handler;
27 | import android.support.v4.app.Fragment;
28 | import android.support.v4.app.FragmentManager;
29 | import android.support.v4.app.FragmentPagerAdapter;
30 |
31 |
32 | /**
33 | * A {@link FragmentPagerAdapter} that returns a fragment corresponding to
34 | * one of the sections/tabs/pages.
35 | */
36 | public class FragmentAdapter extends FragmentPagerAdapter {
37 |
38 | public static final String TAG = "FragmentAdapter";
39 |
40 | // TODO: Total count
41 | public static final int FRAGMENT_COUNT = 2;
42 |
43 | // TODO: Fragment position
44 | public static final int FRAGMENT_POS_EXAMPLE = 0;
45 | public static final int FRAGMENT_POS_SETTINGS = 1;
46 |
47 | // System
48 | private Context mContext = null;
49 | private Handler mHandler = null;
50 | private IFragmentListener mFragmentListener = null;
51 |
52 | private Fragment mExampleFragment = null;
53 | private Fragment mLLSettingsFragment = null;
54 |
55 | public FragmentAdapter(FragmentManager fm, Context c, IFragmentListener l, Handler h) {
56 | super(fm);
57 | mContext = c;
58 | mFragmentListener = l;
59 | mHandler = h;
60 | }
61 |
62 | @Override
63 | public Fragment getItem(int position) {
64 | // getItem is called to instantiate the fragment for the given page.
65 | Fragment fragment;
66 | //boolean needToSetArguments = false;
67 |
68 | if(position == FRAGMENT_POS_EXAMPLE) {
69 | if(mExampleFragment == null) {
70 | mExampleFragment = new ExampleFragment(mContext, mFragmentListener, mHandler);
71 | //needToSetArguments = true;
72 | }
73 | fragment = mExampleFragment;
74 |
75 | } else if(position == FRAGMENT_POS_SETTINGS) {
76 | if(mLLSettingsFragment == null) {
77 | mLLSettingsFragment = new LLSettingsFragment(mContext, mFragmentListener);
78 | //needToSetArguments = true;
79 | }
80 | fragment = mLLSettingsFragment;
81 |
82 | } else {
83 | fragment = null;
84 | }
85 |
86 | // TODO: If you have something to notify to the fragment.
87 | /*
88 | if(needToSetArguments) {
89 | Bundle args = new Bundle();
90 | args.putInt(ARG_SECTION_NUMBER, position + 1);
91 | fragment.setArguments(args);
92 | }
93 | */
94 |
95 | return fragment;
96 | }
97 |
98 | @Override
99 | public int getCount() {
100 | return FRAGMENT_COUNT;
101 | }
102 |
103 | @Override
104 | public CharSequence getPageTitle(int position) {
105 | Locale l = Locale.getDefault();
106 | switch (position) {
107 | case FRAGMENT_POS_EXAMPLE:
108 | return mContext.getString(R.string.title_example).toUpperCase(l);
109 | case FRAGMENT_POS_SETTINGS:
110 | return mContext.getString(R.string.title_ll_settings).toUpperCase(l);
111 | }
112 | return null;
113 | }
114 |
115 |
116 | }
117 |
--------------------------------------------------------------------------------
/src/com/hardcopy/btchat/service/ServiceMonitoring.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Bluetooth Connection Template
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.hardcopy.btchat.service;
18 |
19 | import java.util.List;
20 |
21 | import com.hardcopy.btchat.utils.AppSettings;
22 |
23 | import android.app.ActivityManager;
24 | import android.app.AlarmManager;
25 | import android.app.PendingIntent;
26 | import android.content.BroadcastReceiver;
27 | import android.content.ComponentName;
28 | import android.content.Context;
29 | import android.content.Intent;
30 | import android.os.SystemClock;
31 |
32 | public class ServiceMonitoring {
33 |
34 | private static long SERVICE_RESTART_INTERVAL = 60*1000;
35 |
36 |
37 | /**
38 | * Check if specified service is running or not
39 | * @param context
40 | * @param cls name of service
41 | * @return boolean is running or not
42 | */
43 | private static boolean isRunningService(Context context, Class> cls) {
44 | boolean isRunning = false;
45 |
46 | ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
47 | List info = activityManager.getRunningServices(Integer.MAX_VALUE);
48 |
49 | if (info != null) {
50 | for(ActivityManager.RunningServiceInfo serviceInfo : info) {
51 | ComponentName compName = serviceInfo.service;
52 | String className = compName.getClassName();
53 |
54 | if(className.equals(cls.getName())) {
55 | isRunning = true;
56 | break;
57 | }
58 | }
59 | }
60 | return isRunning;
61 | }
62 |
63 | /**
64 | * Start service monitoring to recover from unintended termination
65 | * @param context
66 | */
67 | public static void startMonitoring(Context context) {
68 | AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
69 | Intent intent = new Intent(context, ServiceMonitoringBR.class);
70 | PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
71 | am.setRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime(), SERVICE_RESTART_INTERVAL, pi);
72 | }
73 |
74 | /**
75 | * Stop service monitoring
76 | * @param context
77 | */
78 | public static void stopMonitoring(Context context) {
79 | AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
80 | Intent intent = new Intent(context, ServiceMonitoringBR.class);
81 | PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
82 | am.cancel(pi);
83 | }
84 |
85 |
86 | /**
87 | * Broadcast receiver
88 | */
89 | public static class ServiceMonitoringBR extends BroadcastReceiver {
90 | @Override
91 | public void onReceive(Context context, Intent intent) {
92 | // Logs.d("# Monitoring service");
93 |
94 | // Check settings value
95 | AppSettings.initializeAppSettings(context);
96 | if(!AppSettings.getBgService()) {
97 | stopMonitoring(context);
98 | return;
99 | }
100 | // If service is running, start service.
101 | if(isRunningService(context, BTCTemplateService.class) == false) {
102 | context.startService(new Intent(context, BTCTemplateService.class));
103 | }
104 | }
105 | }
106 |
107 | }
108 |
--------------------------------------------------------------------------------
/src/com/hardcopy/btchat/http/HttpAsyncTask.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Retro Watch - Open source smart watch project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.hardcopy.btchat.http;
18 |
19 | import java.io.IOException;
20 | import java.net.MalformedURLException;
21 | import java.net.URL;
22 |
23 | import com.hardcopy.btchat.utils.Logs;
24 |
25 | import android.os.AsyncTask;
26 |
27 |
28 | public class HttpAsyncTask extends AsyncTask implements HttpInterface
29 | {
30 | // Global variables
31 | public static final String tag = "HttpAsyncTask";
32 |
33 | // private Map mMap; // Disabled
34 | private int mType;
35 | private String mURL = null;
36 | private int mResultStatus = MSG_HTTP_RESULT_CODE_OK;
37 | private int mRequestType = REQUEST_TYPE_GET;
38 |
39 | // Context, system
40 | private HttpListener mListener;
41 |
42 | // Constructor
43 | public HttpAsyncTask(HttpListener listener, int type, String url, int requestType) {
44 | mListener = listener;
45 | mType = type; // Not used in async task. will be used in callback
46 | mURL = url;
47 | mRequestType = requestType;
48 | }
49 |
50 |
51 | protected String doInBackground(Void... unused)
52 | {
53 | Logs.d(tag, "###### HttpAsyncTask :: Starting HTTP request task ");
54 | String resultString = null;
55 | HttpRequester httpRequester = new HttpRequester();
56 |
57 | if(mListener==null || mURL==null) {
58 | Logs.d(tag, "###### Error!!! : mListener==null or mURL==null ");
59 | return null;
60 | } else {
61 | Logs.d(tag, "###### Request URL = "+mURL);
62 | }
63 |
64 | URL url = null;
65 | try {
66 | url = new URL(mURL);
67 | }
68 | catch (MalformedURLException e1) {
69 | e1.printStackTrace();
70 | mResultStatus = MSG_HTTP_RESULT_CODE_ERROR_REQUEST_EXCEPTION;
71 | Logs.d(tag, "###### Error!!! : MalformedURLException ");
72 | return "";
73 | }
74 |
75 | // Determine request type
76 | String reqType = null;
77 | if(mRequestType == REQUEST_TYPE_GET)
78 | reqType = REQUEST_TYPE_GET_STRING;
79 | else if(mRequestType == REQUEST_TYPE_POST)
80 | reqType = REQUEST_TYPE_POST_STRING;
81 | else
82 | reqType = REQUEST_TYPE_GET_STRING;
83 |
84 | // TODO: Manually set response encoding type.
85 | // Some page doesn't support UTF-8
86 | String encType = null;
87 | if(true) {
88 | encType = ENCODING_TYPE_UTF_8;
89 | }
90 | // else if( ) {
91 | // encType = ENCODING_TYPE_EUC_KR;
92 | // }
93 |
94 | // Request
95 | try {
96 | resultString = httpRequester.request(url, encType, reqType, null);
97 | // publishProgress(int);
98 | } catch (IOException e) {
99 | e.printStackTrace();
100 | mResultStatus = MSG_HTTP_RESULT_CODE_ERROR_REQUEST_EXCEPTION;
101 | Logs.d(tag, "###### Error!!! : HttpRequester makes IOException ");
102 | return "";
103 | }
104 |
105 | // Check result string
106 | if(resultString == null || resultString.length() < 1) {
107 | mResultStatus = MSG_HTTP_RESULT_CODE_ERROR_UNKNOWN;
108 | Logs.d(tag, "###### Error!!! : resultString - invalid result ");
109 | return "";
110 | }
111 |
112 | mResultStatus = MSG_HTTP_RESULT_CODE_OK;
113 | return resultString;
114 | }
115 |
116 | protected void onProgressUpdate(Integer... progress) {
117 | // TODO: set progress percentage
118 | // This code runs on UI thread
119 | }
120 |
121 | protected void onPostExecute(String result) {
122 | // This code runs on UI thread
123 | if(mListener != null) {
124 | mListener.OnReceiveHttpResponse(mType, result, mResultStatus);
125 | }
126 | }
127 |
128 |
129 | }
130 |
--------------------------------------------------------------------------------
/src/com/hardcopy/btchat/http/HttpFileAsyncTask.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Retro Watch - Open source smart watch project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.hardcopy.btchat.http;
18 |
19 | import java.io.File;
20 | import java.io.FileOutputStream;
21 | import java.io.InputStream;
22 | import java.io.OutputStream;
23 | import java.net.HttpURLConnection;
24 | import java.net.MalformedURLException;
25 | import java.net.URL;
26 |
27 | import com.hardcopy.btchat.utils.Logs;
28 | import com.hardcopy.btchat.utils.Utils;
29 |
30 | import android.os.AsyncTask;
31 |
32 |
33 | public class HttpFileAsyncTask extends AsyncTask implements HttpInterface {
34 | // Global variables
35 | public static final String tag = "HttpFileAsyncTask";
36 |
37 | private int mType;
38 | private String mID = null;
39 | private String mURL = null;
40 | private String mDir = null;
41 | private String mFileName = null;
42 | private int mResultStatus = MSG_HTTP_RESULT_CODE_OK;
43 |
44 | private static final int CONNECTION_TIMEOUT = 5000;
45 |
46 | // Context, system
47 | private HttpListener mListener;
48 |
49 |
50 | // Constructor
51 | public HttpFileAsyncTask(HttpListener l, int type, String id, String url, String directory, String filename) {
52 | mListener = l;
53 | mType = type; // Not used in async task. will be used in callback
54 | mID = id; // Not used in async task. will be used in callback
55 | mURL = url;
56 | mDir = directory;
57 | mFileName = filename;
58 | }
59 |
60 |
61 | protected String doInBackground(Void... unused)
62 | {
63 | if(mListener==null || mID==null || mURL==null || mDir==null || mFileName==null) {
64 | //Logs.d(tag, "###### Error!!! : Parameter is null. Check parameter");
65 | return "";
66 | }
67 |
68 | URL url = null;
69 | try {
70 | url = new URL(mURL);
71 | }
72 | catch (MalformedURLException e1) {
73 | e1.printStackTrace();
74 | mResultStatus = MSG_HTTP_RESULT_CODE_ERROR_REQUEST_EXCEPTION;
75 | Logs.d(tag, "# URL = "+url);
76 | //Logs.d(tag, "###### Error!!! : MalformedURLException ");
77 | return null;
78 | }
79 |
80 | if(Utils.checkFileExists(mDir, mFileName))
81 | return null;
82 | String filePathAndName = new String(mDir+"/"+mFileName);
83 |
84 | try {
85 | // Set up connection
86 | HttpURLConnection conn= (HttpURLConnection)url.openConnection();
87 | conn.setConnectTimeout(CONNECTION_TIMEOUT);
88 | conn.setReadTimeout(CONNECTION_TIMEOUT);
89 | conn.connect();
90 |
91 | // Copy input stream (one is for calculate bitmap size and another is for decode bitmap)
92 | InputStream inputStream = conn.getInputStream();
93 |
94 | // Make file and output stream
95 | File file = new File(filePathAndName);
96 | OutputStream outStream = new FileOutputStream(file);
97 |
98 | byte[] buf = new byte[1024];
99 | int len = 0;
100 |
101 | while ((len = inputStream.read(buf)) > 0) {
102 | outStream.write(buf, 0, len);
103 | }
104 | outStream.close();
105 | inputStream.close();
106 |
107 | mResultStatus = MSG_HTTP_RESULT_CODE_OK;
108 |
109 | } catch (Exception e) {
110 | mResultStatus = MSG_HTTP_RESULT_CODE_ERROR_UNKNOWN;
111 | //Logs.d(tag, "###### Error!!! : Cannot download file... ");
112 | e.printStackTrace();
113 | return null;
114 | }
115 |
116 | return filePathAndName;
117 | }
118 |
119 | protected void onProgressUpdate(Integer... progress) {
120 | // TODO: set progress percentage
121 | // This code runs on UI thread
122 | }
123 |
124 | protected void onPostExecute(String filename) {
125 | // This code runs on UI thread
126 | mListener.OnReceiveFileResponse(mType, mID, filename, mURL, mResultStatus);
127 | }
128 |
129 | }
130 |
--------------------------------------------------------------------------------
/src/com/hardcopy/btchat/bluetooth/TransactionBuilder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Bluetooth Connection Template
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.hardcopy.btchat.bluetooth;
18 |
19 | import com.hardcopy.btchat.utils.Constants;
20 |
21 | import android.os.Handler;
22 | import android.util.Log;
23 |
24 | /**
25 | * If you want to send something to remote
26 | * add methods here.
27 | *
28 | * begin() : Initialize parameters
29 | * setXxxx() : Add methods as you wish
30 | * settingFinished() : Every data is ready.
31 | * sendTransaction() : Send to remote
32 | *
33 | */
34 | public class TransactionBuilder {
35 |
36 | private static final String TAG = "TransactionBuilder";
37 |
38 | private BluetoothManager mBTManager = null;
39 | private Handler mHandler = null;
40 |
41 | public TransactionBuilder(BluetoothManager bm, Handler errorHandler) {
42 | mBTManager = bm;
43 | mHandler = errorHandler;
44 | }
45 |
46 | public Transaction makeTransaction() {
47 | return new Transaction();
48 | }
49 |
50 | public class Transaction {
51 |
52 | public static final int MAX_MESSAGE_LENGTH = 16;
53 |
54 | // Transaction instance status
55 | private static final int STATE_NONE = 0; // Instance created
56 | private static final int STATE_BEGIN = 1; // Initialize transaction
57 | private static final int STATE_SETTING_FINISHED = 2; // End of setting parameters
58 | private static final int STATE_TRANSFERED = 3; // End of sending transaction data
59 | private static final int STATE_ERROR = -1; // Error occurred
60 |
61 | // Transaction parameters
62 | private int mState = STATE_NONE;
63 | private byte[] mBuffer = null;
64 | private String mMsg = null;
65 |
66 |
67 | /**
68 | * Make new transaction instance
69 | */
70 | public void begin() {
71 | mState = STATE_BEGIN;
72 | mMsg = null;
73 | mBuffer = null;
74 | }
75 |
76 | /**
77 | * Set string to send
78 | * @param msg String to send
79 | */
80 | public void setMessage(String msg) {
81 | // TODO: do what you want
82 | mMsg = msg;
83 | }
84 |
85 | /**
86 | * Ready to send data to remote
87 | */
88 | public void settingFinished() {
89 | mState = STATE_SETTING_FINISHED;
90 | mBuffer = mMsg.getBytes();
91 | }
92 |
93 | /**
94 | * Send packet to remote
95 | * @return boolean is succeeded
96 | */
97 | public boolean sendTransaction() {
98 | if(mBuffer == null || mBuffer.length < 1) {
99 | Log.e(TAG, "##### Ooooooops!! No sending buffer!! Check command!!");
100 | return false;
101 | }
102 |
103 | // TODO: For debug. Comment out below lines if you want to see the packets
104 | /*
105 | if(mBuffer.length > 0) {
106 | StringBuilder sb = new StringBuilder();
107 | sb.append("Message : ");
108 |
109 | for(int i=0; i 0) {
124 | // Get the message bytes and tell the BluetoothManager to write
125 | mBTManager.write(mBuffer);
126 |
127 | mState = STATE_TRANSFERED;
128 | return true;
129 | }
130 | mState = STATE_ERROR;
131 | }
132 | // Report result
133 | mHandler.obtainMessage(Constants.MESSAGE_CMD_ERROR_NOT_CONNECTED).sendToTarget();
134 | }
135 | }
136 | return false;
137 | }
138 |
139 | /**
140 | * Get buffers to send to remote
141 | */
142 | public byte[] getPacket() {
143 | if(mState == STATE_SETTING_FINISHED) {
144 | return mBuffer;
145 | }
146 | return null;
147 | }
148 |
149 | } // End of class Transaction
150 |
151 | }
152 |
--------------------------------------------------------------------------------
/src/com/hardcopy/btchat/fragments/ExampleFragment.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Bluetooth Connection Template
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.hardcopy.btchat.fragments;
18 |
19 | import android.support.v4.app.Fragment;
20 | import android.text.Editable;
21 | import android.text.method.ScrollingMovementMethod;
22 | import android.content.Context;
23 | import android.os.Bundle;
24 | import android.os.Handler;
25 | import android.view.KeyEvent;
26 | import android.view.LayoutInflater;
27 | import android.view.View;
28 | import android.view.ViewGroup;
29 | import android.view.inputmethod.EditorInfo;
30 | import android.widget.Button;
31 | import android.widget.EditText;
32 | import android.widget.TextView;
33 |
34 | import com.hardcopy.btchat.R;
35 |
36 | public class ExampleFragment extends Fragment implements View.OnClickListener {
37 |
38 | private Context mContext = null;
39 | private IFragmentListener mFragmentListener = null;
40 | private Handler mActivityHandler = null;
41 |
42 | TextView mTextChat;
43 | EditText mEditChat;
44 | Button mBtnSend;
45 |
46 | public ExampleFragment(Context c, IFragmentListener l, Handler h) {
47 | mContext = c;
48 | mFragmentListener = l;
49 | mActivityHandler = h;
50 | }
51 |
52 | @Override
53 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
54 | View rootView = inflater.inflate(R.layout.fragment_main_dummy, container, false);
55 |
56 | mTextChat = (TextView) rootView.findViewById(R.id.text_chat);
57 | mTextChat.setMaxLines(1000);
58 | mTextChat.setVerticalScrollBarEnabled(true);
59 | mTextChat.setMovementMethod(new ScrollingMovementMethod());
60 |
61 | mEditChat = (EditText) rootView.findViewById(R.id.edit_chat);
62 | mEditChat.setOnEditorActionListener(mWriteListener);
63 |
64 | mBtnSend = (Button) rootView.findViewById(R.id.button_send);
65 | mBtnSend.setOnClickListener(this);
66 |
67 | return rootView;
68 | }
69 |
70 | @Override
71 | public void onClick(View v) {
72 | switch(v.getId()) {
73 | case R.id.button_send:
74 | String message = mEditChat.getText().toString();
75 | if(message != null && message.length() > 0)
76 | sendMessage(message);
77 | break;
78 | }
79 | }
80 |
81 |
82 | // The action listener for the EditText widget, to listen for the return key
83 | private TextView.OnEditorActionListener mWriteListener =
84 | new TextView.OnEditorActionListener() {
85 | public boolean onEditorAction(TextView view, int actionId, KeyEvent event) {
86 | // If the action is a key-up event on the return key, send the message
87 | if (actionId == EditorInfo.IME_NULL && event.getAction() == KeyEvent.ACTION_UP) {
88 | String message = view.getText().toString();
89 | if(message != null && message.length() > 0)
90 | sendMessage(message);
91 | }
92 | return true;
93 | }
94 | };
95 |
96 | // Sends user message to remote
97 | private void sendMessage(String message) {
98 | if(message == null || message.length() < 1)
99 | return;
100 | // send to remote
101 | if(mFragmentListener != null)
102 | mFragmentListener.OnFragmentCallback(IFragmentListener.CALLBACK_SEND_MESSAGE, 0, 0, message, null,null);
103 | else
104 | return;
105 | // show on text view
106 | if(mTextChat != null) {
107 | mTextChat.append("\nSend: ");
108 | mTextChat.append(message);
109 | int scrollamout = mTextChat.getLayout().getLineTop(mTextChat.getLineCount()) - mTextChat.getHeight();
110 | if (scrollamout > mTextChat.getHeight())
111 | mTextChat.scrollTo(0, scrollamout);
112 | }
113 | mEditChat.setText("");
114 | }
115 |
116 | private static final int NEW_LINE_INTERVAL = 1000;
117 | private long mLastReceivedTime = 0L;
118 |
119 | // Show messages from remote
120 | public void showMessage(String message) {
121 | if(message != null && message.length() > 0) {
122 | long current = System.currentTimeMillis();
123 |
124 | if(current - mLastReceivedTime > NEW_LINE_INTERVAL) {
125 | mTextChat.append("\nRcv: ");
126 | }
127 | mTextChat.append(message);
128 | int scrollamout = mTextChat.getLayout().getLineTop(mTextChat.getLineCount()) - mTextChat.getHeight();
129 | if (scrollamout > mTextChat.getHeight())
130 | mTextChat.scrollTo(0, scrollamout);
131 |
132 | mLastReceivedTime = current;
133 | }
134 | }
135 |
136 | }
137 |
--------------------------------------------------------------------------------
/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
14 |
15 |
16 |
19 |
20 |
21 |
22 |
25 |
29 |
30 |
31 |
32 |
35 |
39 |
43 |
44 |
45 |
46 |
49 |
50 |
51 |
55 |
56 |
60 |
61 |
67 |
68 |
72 |
73 |
74 |
78 |
79 |
83 |
84 |
91 |
92 |
100 |
101 |
109 |
110 |
118 |
119 |
127 |
128 |
129 |
135 |
136 |
137 |
138 |
--------------------------------------------------------------------------------
/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 | #111111
18 | #222222
19 | #333333
20 | #444444
21 | #555555
22 | #666666
23 | #777777
24 | #888888
25 | #999999
26 | #AAAAAA
27 | #BBBBBB
28 | #CCCCCC
29 | #DDDDDD
30 | #EEEEEE
31 | #FFFFFF
32 |
33 | #C1DBFA
34 | #A3CBF9
35 | #89B9F0
36 | #7DA7D9
37 | #448CCB
38 | #0072BC
39 | #004A80
40 | #003663
41 |
42 | #CBEEFB
43 | #A0E0F8
44 | #76D3F6
45 | #4EC4F1
46 | #1BB0E8
47 | #06A3DE
48 | #0076A3
49 | #005B7F
50 |
51 | #E6E5F8
52 | #CECBED
53 | #B3AEDD
54 | #8781BD
55 | #605CA8
56 | #2E3192
57 | #1B1464
58 | #0D004C
59 |
60 | #005E20
61 | #197B30
62 | #39B54A
63 | #7CC576
64 | #A3D39C
65 | #C0E5BB
66 | #CEEACA
67 | #DFF3DC
68 |
69 | #F4FDE5
70 | #EAF9D4
71 | #DBEFBD
72 | #C4DF9B
73 | #ACD373
74 | #8DC63F
75 | #598527
76 | #406618
77 |
78 | #005826
79 | #007236
80 | #00A651
81 | #3CB878
82 | #82CA9C
83 | #99D8B0
84 | #B6E9C9
85 | #D4F5E1
86 |
87 | #790000
88 | #9E0B0E
89 | #E0272E
90 | #F26C4F
91 | #F69679
92 | #FAB7A3
93 | #FBD0C3
94 | #FCE1D8
95 |
96 | #7D4900
97 | #9E0B0E
98 | #E3820F
99 | #F7941D
100 | #F7A94D
101 | #F7BA71
102 | #F6D1A5
103 | #F6E1C8
104 |
105 | #827B00
106 | #ABA000
107 | #D3C90C
108 | #ECE007
109 | #FEF108
110 | #FFF568
111 | #FFF799
112 | #FEFAC5
113 |
114 | #4B0049
115 | #630460
116 | #32004B
117 | #A864A8
118 | #BD8CBF
119 | #D7A3DA
120 | #F1B6F4
121 | #F9D8FB
122 |
123 | #32004B
124 | #440E62
125 | #662D91
126 | #8560A8
127 | #A186BE
128 | #BAA4D3
129 | #FFF799
130 | #EDE5F7
131 |
132 | #7B0046
133 | #7B0046
134 | #9E005D
135 | #EC008C
136 | #F06EAA
137 | #F49AC1
138 | #F9BDD8
139 | #FEE3EF
140 |
141 | #E2674A
142 | #E05C3E
143 | #DD4D2C
144 | #D34322
145 | #C13D1F
146 | #AF371D
147 | #9E321A
148 | #8C2C17
149 |
150 |
151 |
--------------------------------------------------------------------------------
/src/com/hardcopy/btchat/http/HttpRequester.java:
--------------------------------------------------------------------------------
1 | package com.hardcopy.btchat.http;
2 |
3 | import java.io.ByteArrayOutputStream;
4 | import java.io.IOException;
5 | import java.io.InputStream;
6 | import java.io.OutputStream;
7 | import java.net.HttpURLConnection;
8 | import java.net.MalformedURLException;
9 | import java.net.URL;
10 | import java.net.URLEncoder;
11 | import java.util.Iterator;
12 | import java.util.List;
13 | import java.util.Map;
14 |
15 |
16 | import android.util.Log;
17 |
18 | /*
19 | 만든이 : 고하나 (고또)
20 | 만든 날짜 : 2011.02.26
21 | 플랫폼 : 윈도 7 64bit, 이클립스, 안드로이드 SDK(2.1 ver7)
22 | */
23 |
24 |
25 | /// HTTP방식으로 데이터를 주고 리퀘스트 받아오는 클래스
26 | /// GET와 POST방식 두가지 다 사용 가능하다.
27 |
28 | /// 생성자 호출해서 클래스 인스턴스 생성한 다음
29 | /// request ( URL주소, 방식(GET or POST), 변수명+변수값 ) ; 함수로 보내고 받을 수 있다.
30 |
31 | public class HttpRequester
32 | {
33 | public String m_request ; /// 리퀘스트 내용을 통채로 저장할 스트링
34 | private HttpURLConnection m_con ; /// http방식으로 연결을 유지할 커넥션
35 | String m_cookies = "" ; /// 세션 유지에 필요한 쿠키
36 | boolean m_session = false ; /// 로그인 해서 세션 가지고 있는지 여부
37 | long m_sessionLimitTime = 600000 ; /// 세션 시간제한 (밀리세컨드)
38 | long m_sessionTime = 0 ; /// 세션을 얻은 시간
39 |
40 | private static final String ENCODING_TYPE_UTF_8 = "UTF-8";
41 | private static final String ENCODING_TYPE_EUC_KR = "EUC-KR";
42 | private static int TIMEOUT_VALUE = 5000;
43 |
44 | HttpRequester( ) /// 생성자
45 | {}
46 |
47 |
48 | /// 1. 세션이 유지되고있는지 체크
49 | /// 2. 시간을 넘겼어도 세션 제거하고 false~
50 | public boolean checkSession( )
51 | {
52 | if( !m_session ) {
53 | return false ;
54 | }
55 |
56 | if( System.currentTimeMillis( ) < m_sessionTime + m_sessionLimitTime ) {
57 | m_sessionTime = System.currentTimeMillis( ) ; /// 제한시간 아직 안넘었음 세션 유지 연장시킴
58 | return true ;
59 | } else {
60 | m_session = false ; /// 제한시간을 넘겼음 세션을 제거함
61 | return false ;
62 | }
63 | }
64 |
65 | /// Request를 받되 세션 유지를 위해 쿠키를 저장한다.
66 | public String requestAndSetSession( String uri, Map params ) throws MalformedURLException, IOException {
67 |
68 | String rec = request( new URL(uri), null, "POST", params ) ; /// 일단 주소에 데이터랑 보내고
69 |
70 | Map> imap = m_con.getHeaderFields( ) ; /// 맵에다 Http헤더를 받아냄
71 | if( imap.containsKey( "Set-Cookie" ) ) /// 그리고 거길 뒤져서 쿠키를 찾아냄
72 | {
73 | List lString = imap.get( "Set-Cookie" ) ; /// 쿠키를 스트링으로 쫙 저장함
74 | for( int i = 0 ; i < lString.size() ; i++ ) {
75 | m_cookies += lString.get( i ) ;
76 | }
77 | m_session = true ; /// 세션을 저장했으니
78 |
79 | } else {
80 | m_session = false ;
81 | }
82 | /// 돌려주는 값은 리퀘스트값 뿐이지만 m_session값을 셋팅하니까
83 | /// checkSession( ) 함수를 호출해서 쿠키를 성공적으로 얻었는지 확인 가능함
84 | return rec ;
85 | }
86 |
87 |
88 | /// 리퀘스트 받아오는 함수
89 | /// ( URL주소, 방식(GET or POST), 변수명+변수값 ) ;
90 | protected String request( URL url, String encType, String method, Map params) throws IOException
91 | {
92 | if(url == null) return "";
93 |
94 | InputStream in = null ; /// 받아올 인풋스트림
95 | OutputStream out = null ; /// POST방식일 경우 데이터를 전송할 아웃풋 스트림
96 |
97 | /// 연결하고 메소드 셋팅함
98 | m_con = (HttpURLConnection) url.openConnection( ) ;
99 | ///String wwwstring = URLEncoder.encode( url.toString() ) ;
100 | m_con.setRequestMethod(method);
101 | m_con.setConnectTimeout(TIMEOUT_VALUE);
102 | m_con.setReadTimeout(TIMEOUT_VALUE);
103 |
104 | /// 인코딩 정의 HTTP방식으로 전송할때는 urlencoded방식으로 인코딩해서 전송해야한다.
105 | m_con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
106 |
107 | /// 인풋스트림 쓸거라고 지정
108 | m_con.setDoInput(true);
109 |
110 | if( m_session ) {
111 | m_con.setRequestProperty( "cookie", m_cookies ) ;
112 | }
113 |
114 | /// 포스트방식일 경우 변수를 outputStream생성해서 서버로 전송
115 | if (method.equals("POST"))
116 | {
117 | /// 데이터를 주소와 별개로 전송한다.
118 | m_con.setDoOutput(true); /// 아웃풋 스트림 쓰기위에 아웃풋을 true로 켬
119 |
120 | String paramstr = buildParameters( params ) ; /// 파라메터를 문자열로 치환
121 |
122 | out = m_con.getOutputStream( ) ; /// 아웃풋 스트림 생성
123 | out.write( paramstr.getBytes( "UTF-8" ) ) ; /// UTF-8포멧으로 변경해서 변수를 쓴다.
124 | out.flush( ) ; /// 플러쉬~
125 | out.close( ) ; /// 스트림 닫기
126 | // Log.d( "jsonPrint", "post succes" ) ; /// 로그출력
127 | }
128 |
129 | // SuhYB. Find encoding type to prevent broken 2-byte character
130 | String encodingType = ENCODING_TYPE_EUC_KR;
131 | try {
132 | String headerType = m_con.getContentType();
133 | if(encType!=null && encType.length()>0)
134 | encodingType = encType;
135 | if(headerType !=null && headerType.toUpperCase().indexOf(ENCODING_TYPE_UTF_8) != -1) {
136 | encodingType = ENCODING_TYPE_UTF_8;
137 | }
138 | } catch(Exception e) {
139 | e.printStackTrace();
140 | encodingType = ENCODING_TYPE_UTF_8;
141 | }
142 |
143 | /// 받아온 데이터를 씍위한 스트림
144 | ByteArrayOutputStream bos = new ByteArrayOutputStream();
145 |
146 | /// 리퀘스트 데이터를 저장할 버퍼
147 | byte[] buf = new byte[131072];
148 | try
149 | {
150 | in = m_con.getInputStream(); /// 인풋스트림 생성
151 | //Log.d( "---recTime---", "" + (System.currentTimeMillis( ) - ti) ) ; /// == 시간 체크용 == inputstream얻는 요기서 시간 10초이상 넘어가면 큰일남
152 | /// 갤럭시 S에서 어떤앱은 WebView라던가 Http통신에서 15초인가 넘어가면 세션 끊기는
153 | /// 원인을 알 수 없는 경우도 있었음 다른기기 다 잘되는데 오로지 갤럭시 S만!!! 그랬음 참고 바람요
154 |
155 | /// 루프를 돌면서 리퀘스트로 받은내용을 저장한다.
156 | while (true)
157 | {
158 | int readlen = in.read(buf);
159 | if (readlen < 1)
160 | break;
161 | bos.write(buf, 0, readlen);
162 | }
163 |
164 | m_request = new String( bos.toByteArray( ), encodingType ) ; // SuhYB. 특정 페이지들의 글자 깨짐 방지를 위해 지정한 인코딩 타입으로 수신
165 | /////// 리퀘스트 받은 내용을 UTF-8로 변경해서 문자열로 저장 /////////////////
166 | /*
167 | File fl = new File( "/sdcard/rec.txt" ) ;
168 | FileOutputStream fos = new FileOutputStream( fl ) ;
169 | fos.write( bos.toByteArray( ) ) ;
170 | /**/
171 |
172 | return m_request ;
173 | }
174 | catch (IOException e)
175 | {
176 | /// 리퀘스트 받다가 에러가 나면 에러나면서 받은 메세지를 읽는다.
177 | if(m_con != null && m_con.getResponseCode() == 500)
178 | {
179 | /// 버퍼 리셋하고 에러값 받을 인풋스트림 생성해서 레어메세지 얻기
180 | bos.reset();
181 | InputStream err = m_con.getErrorStream();
182 | while (true)
183 | {
184 | int readlen = err.read( buf ) ;
185 | if ( readlen < 1 )
186 | break ;
187 | bos.write( buf, 0, readlen ) ;
188 | }
189 |
190 | /// 에러메세지를 문자열로 저장
191 | String output = new String(bos.toByteArray(), "UTF-8");
192 |
193 | /// 읽은 에러메세지를 출력한다.
194 | System.err.println(output);
195 | }
196 | throw e;
197 | }
198 | finally /// 500에러도 아니면 그냥 접속 끊어버림.... -_- 안되는데 답있나?
199 | {
200 | if ( in != null )
201 | in.close( ) ;
202 | if ( m_con != null )
203 | m_con.disconnect( ) ;
204 | }
205 | }
206 |
207 | /// 파라메터 받은 값을 "변수명=변수값&" 형식의 텍스트로 변환해주는 함수
208 | protected String buildParameters(Map params) throws IOException
209 | {
210 | if( params == null )
211 | return "" ;
212 |
213 | StringBuilder sb = new StringBuilder( ) ;
214 |
215 | /// 잘 아시겠지만 arg1=초코릿&arg2=아이스크림&arg3=핫초코 이런식으로 만들어서 날린다.
216 | for( Iterator i = params.keySet( ).iterator( ) ; i.hasNext( ) ; )
217 | {
218 | String key = (String) i.next();
219 | sb.append(key);
220 | sb.append("=");
221 | sb.append(URLEncoder.encode(String.valueOf(params.get(key)), "UTF-8"));
222 | if (i.hasNext())
223 | sb.append("&");
224 | }
225 | return sb.toString();
226 | }
227 |
228 | }
229 |
--------------------------------------------------------------------------------
/src/com/hardcopy/btchat/DeviceListActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Bluetooth Connection Template
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.hardcopy.btchat;
18 |
19 | import java.util.Set;
20 |
21 | import com.hardcopy.btchat.R;
22 |
23 | import android.app.Activity;
24 | import android.bluetooth.BluetoothAdapter;
25 | import android.bluetooth.BluetoothDevice;
26 | import android.content.BroadcastReceiver;
27 | import android.content.Context;
28 | import android.content.Intent;
29 | import android.content.IntentFilter;
30 | import android.os.Bundle;
31 | import android.util.Log;
32 | import android.view.View;
33 | import android.view.Window;
34 | import android.view.View.OnClickListener;
35 | import android.widget.AdapterView;
36 | import android.widget.ArrayAdapter;
37 | import android.widget.Button;
38 | import android.widget.ListView;
39 | import android.widget.TextView;
40 | import android.widget.AdapterView.OnItemClickListener;
41 |
42 |
43 | /**
44 | * This Activity appears as a dialog. It lists any paired devices and
45 | * devices detected in the area after discovery. When a device is chosen
46 | * by the user, the MAC address of the device is sent back to the parent
47 | * Activity in the result Intent.
48 | */
49 | public class DeviceListActivity extends Activity {
50 | // Debugging
51 | private static final String TAG = "DeviceListActivity";
52 | private static final boolean D = true;
53 |
54 | // Return Intent extra
55 | public static String EXTRA_DEVICE_ADDRESS = "device_address";
56 |
57 | // Member fields
58 | private BluetoothAdapter mBtAdapter;
59 | private ArrayAdapter mPairedDevicesArrayAdapter;
60 | private ArrayAdapter mNewDevicesArrayAdapter;
61 |
62 | // UI stuff
63 | Button mScanButton = null;
64 |
65 |
66 |
67 |
68 | @Override
69 | protected void onCreate(Bundle savedInstanceState) {
70 | super.onCreate(savedInstanceState);
71 |
72 | // Setup the window
73 | requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
74 | setContentView(R.layout.activity_device_list);
75 |
76 | // Set result CANCELED incase the user backs out
77 | setResult(Activity.RESULT_CANCELED);
78 |
79 | // Initialize the button to perform device discovery
80 | mScanButton = (Button) findViewById(R.id.button_scan);
81 | mScanButton.setOnClickListener(new OnClickListener() {
82 | public void onClick(View v) {
83 | mNewDevicesArrayAdapter.clear();
84 | doDiscovery();
85 | v.setVisibility(View.GONE);
86 | }
87 | });
88 |
89 | // Initialize array adapters. One for already paired devices and
90 | // one for newly discovered devices
91 | mPairedDevicesArrayAdapter = new ArrayAdapter(this, R.layout.adapter_device_name);
92 | mNewDevicesArrayAdapter = new ArrayAdapter(this, R.layout.adapter_device_name);
93 |
94 | // Find and set up the ListView for paired devices
95 | ListView pairedListView = (ListView) findViewById(R.id.paired_devices);
96 | pairedListView.setAdapter(mPairedDevicesArrayAdapter);
97 | pairedListView.setOnItemClickListener(mDeviceClickListener);
98 |
99 | // Find and set up the ListView for newly discovered devices
100 | ListView newDevicesListView = (ListView) findViewById(R.id.new_devices);
101 | newDevicesListView.setAdapter(mNewDevicesArrayAdapter);
102 | newDevicesListView.setOnItemClickListener(mDeviceClickListener);
103 |
104 | // Register for broadcasts when a device is discovered
105 | IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
106 | this.registerReceiver(mReceiver, filter);
107 |
108 | // Register for broadcasts when discovery has finished
109 | filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
110 | this.registerReceiver(mReceiver, filter);
111 |
112 | // Get the local Bluetooth adapter
113 | mBtAdapter = BluetoothAdapter.getDefaultAdapter();
114 |
115 | // Get a set of currently paired devices
116 | Set pairedDevices = mBtAdapter.getBondedDevices();
117 |
118 | // If there are paired devices, add each one to the ArrayAdapter
119 | if (pairedDevices.size() > 0) {
120 | findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);
121 | for (BluetoothDevice device : pairedDevices) {
122 | mPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
123 | }
124 | } else {
125 | String noDevices = getResources().getText(R.string.none_paired).toString();
126 | mPairedDevicesArrayAdapter.add(noDevices);
127 | }
128 | }
129 |
130 | @Override
131 | protected void onDestroy() {
132 | super.onDestroy();
133 |
134 | // Make sure we're not doing discovery anymore
135 | if (mBtAdapter != null) {
136 | mBtAdapter.cancelDiscovery();
137 | }
138 |
139 | // Unregister broadcast listeners
140 | this.unregisterReceiver(mReceiver);
141 | }
142 |
143 | /**
144 | * Start device discover with the BluetoothAdapter
145 | */
146 | private void doDiscovery() {
147 | if (D) Log.d(TAG, "doDiscovery()");
148 |
149 | // Indicate scanning in the title
150 | setProgressBarIndeterminateVisibility(true);
151 | setTitle(R.string.scanning);
152 |
153 | // Turn on sub-title for new devices
154 | findViewById(R.id.title_new_devices).setVisibility(View.VISIBLE);
155 |
156 | // If we're already discovering, stop it
157 | if (mBtAdapter.isDiscovering()) {
158 | mBtAdapter.cancelDiscovery();
159 | }
160 |
161 | // Request discover from BluetoothAdapter
162 | mBtAdapter.startDiscovery();
163 | }
164 |
165 | // The on-click listener for all devices in the ListViews
166 | private OnItemClickListener mDeviceClickListener = new OnItemClickListener() {
167 | public void onItemClick(AdapterView> av, View v, int arg2, long arg3) {
168 | // Cancel discovery because it's costly and we're about to connect
169 | mBtAdapter.cancelDiscovery();
170 |
171 | // Get the device MAC address, which is the last 17 chars in the View
172 | String info = ((TextView) v).getText().toString();
173 | if(info != null && info.length() > 16) {
174 | String address = info.substring(info.length() - 17);
175 | Log.d(TAG, "User selected device : " + address);
176 |
177 | // Create the result Intent and include the MAC address
178 | Intent intent = new Intent();
179 | intent.putExtra(EXTRA_DEVICE_ADDRESS, address);
180 |
181 | // Set result and finish this Activity
182 | setResult(Activity.RESULT_OK, intent);
183 | finish();
184 | }
185 | }
186 | };
187 |
188 | // The BroadcastReceiver that listens for discovered devices and
189 | // changes the title when discovery is finished
190 | private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
191 | @Override
192 | public void onReceive(Context context, Intent intent) {
193 | String action = intent.getAction();
194 |
195 | // When discovery finds a device
196 | if (BluetoothDevice.ACTION_FOUND.equals(action)) {
197 | // Get the BluetoothDevice object from the Intent
198 | BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
199 | // If it's already paired, skip it, because it's been listed already
200 | if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
201 | mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
202 | }
203 | // When discovery is finished, change the Activity title
204 | } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
205 | setProgressBarIndeterminateVisibility(false);
206 | setTitle(R.string.select_device);
207 | if (mNewDevicesArrayAdapter.getCount() == 0) {
208 | String noDevices = getResources().getText(R.string.none_found).toString();
209 | mNewDevicesArrayAdapter.add(noDevices);
210 | }
211 | mScanButton.setVisibility(View.VISIBLE);
212 | }
213 | }
214 | };
215 |
216 | }
217 |
--------------------------------------------------------------------------------
/src/com/hardcopy/btchat/utils/Utils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Retro Watch - Open source smart watch project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.hardcopy.btchat.utils;
18 |
19 | import java.io.File;
20 | import java.io.FileInputStream;
21 | import java.io.FileNotFoundException;
22 | import java.io.FileOutputStream;
23 | import java.io.IOException;
24 | import java.io.InputStream;
25 | import java.io.InputStreamReader;
26 | import java.io.Reader;
27 | import java.util.ArrayList;
28 | import java.util.Arrays;
29 | import java.util.Comparator;
30 | import java.util.List;
31 | import java.util.Map;
32 | import java.util.Set;
33 | import java.util.regex.Matcher;
34 | import java.util.regex.Pattern;
35 |
36 | import android.content.Context;
37 | import android.graphics.Bitmap;
38 | import android.graphics.BitmapFactory;
39 | import android.util.Log;
40 |
41 | import com.hardcopy.btchat.R;
42 |
43 | public class Utils {
44 | private Context mContext;
45 |
46 | private static final String TAG = "Utils";
47 |
48 | public Utils(Context c) {
49 | if(mContext == null) {
50 | mContext = c;
51 | initialize();
52 | }
53 | }
54 |
55 |
56 | private void initialize() {
57 | }
58 |
59 |
60 | //============================================================
61 | // Directory, File handling
62 | //============================================================
63 |
64 | public static void initFileDirectory(String path)
65 | {
66 | File directory = new File(path);
67 | if( !directory.exists() ) {
68 | directory.mkdirs();
69 | }
70 | }
71 |
72 | public static void deleteDirectory(String path) {
73 | if(path==null) return;
74 | if(Utils.isFileExist(new File(path))) {
75 | deleteFileDirRecursive(path);
76 | }
77 | }
78 |
79 | public static void deleteFileDirRecursive(String path) {
80 | File file = new File(path);
81 | File[] childFileList = file.listFiles();
82 | for(File childFile : childFileList)
83 | {
84 | if(childFile.isDirectory()) {
85 | deleteFileDirRecursive(childFile.getAbsolutePath()); //하위 디렉토리 루프
86 | }
87 | else {
88 | childFile.delete(); //하위 파일삭제
89 | }
90 | }
91 | file.delete(); //root 삭제
92 | }
93 |
94 | public static boolean checkFileExists(String directory, String filename)
95 | {
96 | if(directory==null || filename==null)
97 | return false;
98 | File kFile = new File(directory+"/"+filename);
99 | if(kFile != null) {
100 | return kFile.exists();
101 | }
102 | return false;
103 | }
104 |
105 | public static File makeDirectory(String dir_path){
106 | File dir = new File(dir_path);
107 | if (!dir.exists())
108 | {
109 | dir.mkdirs();
110 | Log.i(TAG , "!dir.exists");
111 | }else{
112 | Log.i(TAG , "dir.exists");
113 | }
114 |
115 | return dir;
116 | }
117 |
118 | public static File makeFile(File dir , String file_path){
119 | File file = null;
120 | boolean isSuccess = false;
121 | if(dir.isDirectory()){
122 | file = new File(file_path);
123 | if(file!=null&&!file.exists()){
124 | Log.i(TAG , "!file.exists");
125 | try {
126 | isSuccess = file.createNewFile();
127 | } catch (IOException e) {
128 | e.printStackTrace();
129 | } finally{
130 | Log.i(TAG, "파일생성 여부 = " + isSuccess);
131 | }
132 | }else{
133 | Log.i(TAG , "file.exists");
134 | }
135 | }
136 | return file;
137 | }
138 |
139 | public static String getAbsolutePath(File file){
140 | return ""+file.getAbsolutePath();
141 | }
142 |
143 | public static boolean deleteFile(File file){
144 | boolean result;
145 | if(file!=null&&file.exists()){
146 | file.delete();
147 | result = true;
148 | }else{
149 | result = false;
150 | }
151 | return result;
152 | }
153 |
154 | public static boolean isFile(File file){
155 | boolean result;
156 | if(file!=null&&file.exists()&&file.isFile()){
157 | result=true;
158 | }else{
159 | result=false;
160 | }
161 | return result;
162 | }
163 |
164 | public static boolean isDirectory(File dir){
165 | boolean result;
166 | if(dir!=null&&dir.isDirectory()){
167 | result=true;
168 | }else{
169 | result=false;
170 | }
171 | return result;
172 | }
173 |
174 | public static boolean isFileExist(File file){
175 | boolean result;
176 | if(file!=null&&file.exists()){
177 | result=true;
178 | }else{
179 | result=false;
180 | }
181 | return result;
182 | }
183 |
184 | public static boolean reNameFile(File file , File new_name){
185 | boolean result;
186 | if(file!=null&&file.exists()&&file.renameTo(new_name)){
187 | result=true;
188 | }else{
189 | result=false;
190 | }
191 | return result;
192 | }
193 |
194 | public static String[] getList(File dir){
195 | if(dir!=null&&dir.exists())
196 | return dir.list();
197 | return null;
198 | }
199 |
200 | public static boolean writeFile(File file , byte[] file_content){
201 | boolean result;
202 | FileOutputStream fos;
203 |
204 | if(file!=null&&file_content!=null){
205 | try {
206 | fos = new FileOutputStream(file);
207 | try {
208 | fos.write(file_content);
209 | fos.flush();
210 | fos.close();
211 | } catch (IOException e) {
212 | e.printStackTrace();
213 | }
214 | } catch (FileNotFoundException e) {
215 | e.printStackTrace();
216 | }
217 | result = true;
218 | }else{
219 | Logs.d(TAG, "##### writeFile :: file is null or file does not exists or content is null ");
220 | result = false;
221 | }
222 | return result;
223 | }
224 |
225 | public static String readFile(File file){
226 | StringBuilder sb = new StringBuilder();
227 | int readcount=0;
228 |
229 | if( file!=null && file.exists() ){
230 | try {
231 | FileInputStream fis = new FileInputStream(file);
232 | Reader in = new InputStreamReader(fis, "UTF-8");
233 | readcount = (int)file.length();
234 | char[] tempByte = new char[readcount];
235 | in.read(tempByte);
236 | // readcount = (int)file.length();
237 | // byte[] buffer = new byte[readcount];
238 | // fis.read(buffer);
239 | fis.close();
240 | sb.append(tempByte);
241 | } catch (Exception e) {
242 | e.printStackTrace();
243 | Logs.d(TAG, "##### writeFile :: Exception while FILE IO ");
244 | }
245 | } else {
246 | Logs.d(TAG, "##### writeFile :: file is null or file does not exists or content is null ");
247 | }
248 | return sb.toString();
249 | }
250 |
251 | public static boolean copyFile(File file , String save_file){
252 | boolean result;
253 | if(file!=null&&file.exists()){
254 | try {
255 | FileInputStream fis = new FileInputStream(file);
256 | FileOutputStream newfos = new FileOutputStream(save_file);
257 | int readcount=0;
258 | byte[] buffer = new byte[1024];
259 | while((readcount = fis.read(buffer,0,1024))!= -1){
260 | newfos.write(buffer,0,readcount);
261 | }
262 | newfos.close();
263 | fis.close();
264 | } catch (Exception e) {
265 | e.printStackTrace();
266 | }
267 | result = true;
268 | }else{
269 | result = false;
270 | }
271 | return result;
272 | }
273 |
274 | //============================================================
275 | // URL, File name
276 | //============================================================
277 |
278 | // url 파일이름 추출 (with extension)
279 | public static String convertUrlToFileName(String url)
280 | {
281 | String name = new File(url).getName();
282 | return name;
283 | }
284 |
285 | // TODO: url 파일이름 추출 (without extension)
286 | public static String convertUrlToFileNameWithoutExt(String url)
287 | {
288 | String name = new File(url).getName();
289 | // TODO
290 | return name;
291 | }
292 |
293 |
294 | public static final String REG_EXP_IMAGE_URL = "(?i)http://[a-zA-Z0-9_.\\-%&=?!:;@\"'/]*(?i)(.gif|.jpg|.png|.jpeg)";
295 |
296 | // TODO: Not working correctly
297 | public static List getImageURL(String str) {
298 | Pattern nonValidPattern = Pattern.compile(REG_EXP_IMAGE_URL);
299 |
300 | List result = new ArrayList();
301 | Matcher matcher = nonValidPattern.matcher(str);
302 | while (matcher.find()) {
303 | result.add(matcher.group(0));
304 | break;
305 | }
306 | return result;
307 | }
308 |
309 | public static Comparator