안녕하세요 열코입니다.

이번에 블루투스 프로그램 개발 도중 백업 파일을 업로드합니다.

연결 및 통신 코드 첨부되어있습니다.

참고하시기바랍니다.



activity_main.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
 
    <!-- 메인 화면-->
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
 
        <TextView
            android:textColor="#000000"
            android:layout_marginTop="20dp"
            android:layout_marginBottom="20dp"
            android:textSize="20dp"
            android:gravity="center_horizontal|center_vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="블루투스 연동 APP"/>
 
        <Button
            android:id="@+id/button_connect_bluetooth"
            android:textSize="15dp"
            android:layout_marginBottom="5dp"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"
            android:layout_weight="1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:text="블루투스 연결"/>
 
        <Button
            android:id="@+id/button_how_to"
            android:textSize="15dp"
            android:layout_marginBottom="5dp"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"
            android:layout_weight="1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:text="사용 방법"/>
 
        <Button
            android:id="@+id/button_inquire"
            android:textSize="15dp"
            android:layout_marginBottom="5dp"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"
            android:layout_weight="1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:text="문의 하기"/>
 
        <Button
            android:id="@+id/button_exit"
            android:textSize="15dp"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"
            android:layout_weight="1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:text="앱 종료"/>
 
        
    </LinearLayout>
 
</android.support.constraint.ConstraintLayout>
cs



bluetooth_communication.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="match_parent">
 
    <!-- 블루투스 통신 화면-->
    <LinearLayout
        android:id="@+id/linearlayout_setcolor"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
 
        <TextView
            android:id="@+id/textview_connection_status"
            android:textColor="#000000"
            android:layout_marginTop="20dp"
            android:layout_marginBottom="20dp"
            android:textSize="20dp"
            android:gravity="center_horizontal|center_vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="블루투스 연결 상태 : "/>
 
        <TextView
            android:textColor="#000000"
            android:layout_marginLeft="10dp"
            android:id="@+id/textview_connection_explaination"
            android:textSize="15dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="디바이스 연결 설명"/>
 
        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/button_pairing"
            android:text="페어링 하기"/>
 
        <TextView
            android:id="@+id/textview_alarm_log"
            android:textColor="#000000"
            android:layout_marginLeft="10dp"
            android:layout_marginBottom="10dp"
            android:textSize="15dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text=" ▣ 알림 기록"/>
 
        <ScrollView
            android:layout_weight="1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fillViewport="true">
            <ListView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:id="@+id/listview_alarm_log">
            </ListView>
        </ScrollView>
 
       
    </LinearLayout>
 
</android.support.constraint.ConstraintLayout>
cs


connect_bluetooth.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="match_parent">
 
    <!-- 블루투스 연결 화면-->
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
 
        <TextView
            android:textColor="#000000"
            android:layout_marginTop="20dp"
            android:layout_marginBottom="20dp"
            android:textSize="20dp"
            android:gravity="center_horizontal|center_vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="블루투스 연결"/>
 
        <Button
            android:id="@+id/button_setting_menu"
            android:textSize="15dp"
            android:layout_marginBottom="5dp"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="디바이스 신규 등록"/>
 
        <TextView
            android:textColor="#000000"
            android:layout_marginTop="10dp"
            android:layout_marginBottom="10dp"
            android:textSize="15dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text=" ▣ 페어링 된 디바이스"/>
 
        <ScrollView
            android:layout_weight="1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fillViewport="true">
            <ListView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:id="@+id/listview_pairing_devices">
            </ListView>
        </ScrollView>
 
      
    </LinearLayout>
 
</android.support.constraint.ConstraintLayout>
cs


MainActivity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package com.example.simt.simtbluetoothapp;
 
import android.content.DialogInterface;
import android.content.Intent;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
 
public class MainActivity extends AppCompatActivity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        // 버튼 객체 생성 및 xml id 연결
        Button button_connect_bluetooth = (Button) findViewById(R.id.button_connect_bluetooth);
        Button button_how_to = (Button) findViewById(R.id.button_how_to);
        Button button_inqure = (Button) findViewById(R.id.button_inquire);
        Button button_exit = (Button) findViewById(R.id.button_exit);
 
        // "블루투스 연결" 버튼 클릭 이벤트
        button_connect_bluetooth.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 새 창에서 ConnectBluetoothActivity 실행
                Intent intent = new Intent(MainActivity.this, ConnectBluetoothActivity.class);
                startActivity(intent);
            }
        });
 
        // "사용 방법" 버튼 클릭 이벤트
        button_how_to.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 새 창에서 HowToActivity 실행
                Intent intent = new Intent(MainActivity.this, HowToActivity.class);
                startActivity(intent);
            }
        });
 
        // "문의하기" 버튼 클릭 이벤트
        button_inqure.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 새 창에서 InquireActivity 실행
                Intent intent = new Intent(MainActivity.this, InquireActivity.class);
                startActivity(intent);
            }
        });
 
        // "앱 종료" 버튼 클릭 이벤트
        button_exit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 종료 확인 다이얼로그(대화창) 생성
                AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this, android.R.style.Theme_DeviceDefault_Light_Dialog);
                builder.setMessage("정말로 앱을 종료하시겠습니까?").setTitle("앱 종료")
                        .setPositiveButton("아니오"new DialogInterface.OnClickListener() {
                            // 아니오 버튼을 눌렀을 때
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                // 아무 작동없이 함수를 종료
                                return;
                            }
                        })
                        .setNeutralButton("예"new DialogInterface.OnClickListener() {
                            // 예 버튼을 눌렀을 때
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                // 앱을 종료
                                finish();
                            }
                        })
                        .setCancelable(false).show();
            }
        });
    }
}
 
cs


ConnectBluetoothActivity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
package com.example.simt.simtbluetoothapp;
 
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
import android.provider.Settings;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
 
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.UUID;
 
public class ConnectBluetoothActivity extends AppCompatActivity {
    // onActivityResult의 RequestCode 식별자
    private static final int REQUEST_NEW_DEVICE = 1;
    private static final int REQUEST_ENABLE_BT = 2;
 
    // 블루투스 사용 객체
    private BluetoothAdapter bluetoothAdapter;
    private BluetoothDevice bluetoothDevice;
    private Set<BluetoothDevice> bluetoothDeviceSet;
    private BluetoothSocket bluetoothSocket;
    public static InputStream inputStream;
 
    // xml 객체
    private ListView listView_pairing_devices; // 페어링 된 디바이스 리스트뷰 객체
 
    // 일반 객체
    private String device_name;
 
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.connect_bluetooth);
 
        // 리스트 뷰 객체와 xml id 연결
        listView_pairing_devices = (ListView)findViewById(R.id.listview_pairing_devices);
 
        // 버튼 객체 생성 및 xml id 연결
        Button button_setting_menu = (Button)findViewById(R.id.button_setting_menu);
        // "디바이스 신규 등록" 버튼 클릭 이벤트
        button_setting_menu.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 블루투스 설정 화면 띄워주기
                Intent intent = new Intent(Settings.ACTION_BLUETOOTH_SETTINGS);
                // 종료 후 onActivityResult 호출, requestCode가 넘겨짐
                startActivityForResult(intent, REQUEST_NEW_DEVICE);
            }
        });
 
        // 블루투스 활성화 확인 함수 호출
        checkBluetooth();
    }
 
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        switch (requestCode) {
            // 블루투스 설정화면 종료 시
            case REQUEST_NEW_DEVICE :
                checkBluetooth();
                break;
            // 블루투스 활성화 선택 종료 시
            case REQUEST_ENABLE_BT :
                // 활성화 버튼을 눌렀을 때
                if(resultCode == RESULT_OK) {
                    selectDevice();
                }
                // 취소 버튼을 눌렀을 때
                else if(resultCode == RESULT_CANCELED) {
                    Toast.makeText(getApplicationContext(), "블루투스를 활성화 하지 않아 앱을 종료합니다.", Toast.LENGTH_LONG).show();
                    // 앱 종료
                    finish();
                }
                break;
        }
        super.onActivityResult(requestCode, resultCode, data);
    }
 
    // 블루투스 활성화 확인 함수
    public void checkBluetooth() {
        bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        // 단말기가 블루투스를 지원하지 않을 때
        if(bluetoothAdapter == null) {
            Toast.makeText(getApplicationContext(), "단말기가 블루투스를 지원하지 않습니다.", Toast.LENGTH_LONG).show();
            finish(); // 앱 종료
        }
        // 블루투스를 지원할 때
        else {
            // 블루투스가 활성화 상태
            if(bluetoothAdapter.isEnabled()) {
                // 블루투스 선택 함수 호출
                selectDevice();
            }
            // 블루투스가 비 활성화 상태
            else {
                // 블루투스를 활성화
                Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                startActivityForResult(intent, REQUEST_ENABLE_BT);
            }
        }
    }
 
    // 블루투스 선택 함수
    public void selectDevice() {
        // 페어링 된 디바이스 목록을 불러옴
        bluetoothDeviceSet = bluetoothAdapter.getBondedDevices();
 
        // 리스트를 만듬
        List<String> list = new ArrayList<>();
        for(BluetoothDevice bluetoothDevice : bluetoothDeviceSet) {
            list.add(bluetoothDevice.getName());
        }
 
        // 어레이어뎁터로 리스트뷰에 리스트를 생성
        final ArrayAdapter arrayAdapter = new ArrayAdapter(ConnectBluetoothActivity.this, android.R.layout.simple_list_item_1, list);
        listView_pairing_devices.setAdapter(arrayAdapter);
        listView_pairing_devices.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            // 리스트 뷰의 아이템을 클릭했을 때
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                device_name = arrayAdapter.getItem(position).toString();
 
                // 프로그레스 다이얼로그 생성
                CheckTypesTask task = new CheckTypesTask();
                task.execute();
            }
        });
    }
 
    // 클릭 된 디바이스와 연결하는 함수
    public void connectDevice(String deviceName) {
        // 블루투스 연결 할 디바이스를 찾음
        for(BluetoothDevice device : bluetoothDeviceSet) {
            if(deviceName.equals(device.getName())) {
                bluetoothDevice = device;
                break;
            }
        }
 
        // UUID 생성
        UUID uuid = java.util.UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
 
        try {
            // 블루투스 소켓 생성
            bluetoothSocket = bluetoothDevice.createRfcommSocketToServiceRecord(uuid);
            bluetoothSocket.connect();
            // 데이터 받기 위해 인풋스트림 생성
            inputStream = bluetoothSocket.getInputStream();
 
            // 블루투스 수신 시작 호출
            Intent intent = new Intent(ConnectBluetoothActivity.this, BluetoothCommunicationActivity.class);
            startActivity(intent);
        }
        catch (Exception e) {
            // 쓰레드에서 UI처리를 위한 핸들러
            Message msg = handler.obtainMessage();
            handler.sendMessage(msg);
        }
    }
 
    // 핸들러 선언
    final Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            Toast.makeText(getApplicationContext(), "블루투스 연결을 다시 시도해주세요.", Toast.LENGTH_SHORT).show();
        }
    };
 
    // 프로그레스 다이얼로그 생성
    private class CheckTypesTask extends AsyncTask<Void, Void, Void> {
        ProgressDialog asyncDialog = new ProgressDialog(
                ConnectBluetoothActivity.this);
 
        @Override
        protected void onPreExecute() {
            asyncDialog.setCancelable(false);
            asyncDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
            asyncDialog.setMessage(device_name + "과 연결중입니다.");
 
            // show dialog
            asyncDialog.show();
            super.onPreExecute();
        }
 
        // 백그라운드에서 실행
        @Override
        protected Void doInBackground(Void... arg0) {
            connectDevice(device_name);
            return null;
        }
 
        // 백그라운드가 모두 끝난 후 실행
        @Override
        protected void onPostExecute(Void result) {
            asyncDialog.dismiss();
            super.onPostExecute(result);
        }
    }
}
 
cs


BluetoothCommunication.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
package com.example.simt.simtbluetoothapp;
 
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
import android.os.Vibrator;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
 
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
 
public class BluetoothCommunicationActivity extends AppCompatActivity {
 
    // xml 객체 선언
    private LinearLayout linearLayout_setcolor;
    private TextView textView_connection_status;
    private TextView textView_connection_explaination;
    private ListView listView_alarm_log;
    private Button button_pairing;
    private TextView textView_alarm_log;
 
    // 일반 변수 객체 선언
    private List<String> list;
    private ArrayAdapter arrayAdapter;
    private int log_num = 1;
 
    // 쓰레드 사용 객체 선언
    private int readBufferPosition;
    private byte[] readBuffer;
    private Thread thread;
 
    // WakeLock 사용 객체
    private PowerManager powerManager;
    private PowerManager.WakeLock wakeLock;
 
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.bluetooth_communication);
 
        // xml 객체 id 연결
        linearLayout_setcolor = (LinearLayout)findViewById(R.id.linearlayout_setcolor);
        textView_connection_status = (TextView)findViewById(R.id.textview_connection_status);
        textView_connection_explaination = (TextView)findViewById(R.id.textview_connection_explaination);
        listView_alarm_log = (ListView)findViewById(R.id.listview_alarm_log);
        button_pairing = (Button)findViewById(R.id.button_pairing);
        textView_alarm_log = (TextView)findViewById(R.id.textview_alarm_log);
 
        // 리스트 뷰 어댑터 생성
        list = new ArrayList<>();
        arrayAdapter = new ArrayAdapter(BluetoothCommunicationActivity.this, android.R.layout.simple_list_item_1, list);
        // 항상 최하단 아이템으로 유지
        listView_alarm_log.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
        listView_alarm_log.setAdapter(arrayAdapter);
 
        // 페어링 하기 버튼 클릭 이벤트
        button_pairing.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
                startActivity(new Intent(BluetoothCommunicationActivity.this, ConnectBluetoothActivity.class));
            }
        });
 
        // WakeLock 객체 생성 및 설정
        powerManager = (PowerManager)getSystemService(Context.POWER_SERVICE);
        wakeLock = powerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK |
                PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.ON_AFTER_RELEASE, "WAKELOCK");
 
        // 동적 버튼 객체 생성
        final Button newbtn = new Button(BluetoothCommunicationActivity.this);
 
        // UI 변경은 핸들러에서 처리
        @SuppressLint("HandlerLeak"final Handler handler = new Handler() {
            public void handleMessage(Message msg) {
                // 연결 되지 않았을 때
                linearLayout_setcolor.setBackgroundColor(Color.rgb(179,179,179));
                textView_connection_status.setTextColor(Color.RED);
                textView_connection_status.setText("블루투스 연결 상태 : 불량");
                textView_connection_explaination.setText("블루투스 디바이스와 연결 상태가 좋지 않습니다.\n" +
                        "계속해서 연결 상태가 좋지 않을 경우 아래 버튼을 눌러 다시 페어링을 시도하세요.");
 
                // 버튼 보이기
                button_pairing.setVisibility(View.VISIBLE);
                listView_alarm_log.setVisibility(View.INVISIBLE);
                textView_alarm_log.setVisibility(View.INVISIBLE);
            }
        };
 
        // 수신 버퍼 저장 위치
        readBufferPosition = 0;
        readBuffer = new byte[10];
 
        // 문자 수신 쓰레드
        thread = new Thread(new Runnable() {
            @Override
            public void run() {
                // 인터럽트 호출 전까지 반복
                while(!Thread.currentThread().isInterrupted()) {
                    // 수신 데이터 확인 변수
                    int byteAvailabe = 0;
 
                    // 문자열 개수를 받아옴
                    try {
                        byteAvailabe = ConnectBluetoothActivity.inputStream.available();
                    }
                    catch (IOException e) {
                        e.printStackTrace();
                    }
 
                    Log.d("Thread""From Bluetooth Data : " + byteAvailabe);
 
                    // 데이터가 수신된 경우
                    if(byteAvailabe > 0) {
                        // 데이터 크기만큼 바이트 배열 생성
                        byte[] packetByte = new byte[byteAvailabe];
                        // 바이트 배열 크기만큼 읽어옴
                        try {
                            ConnectBluetoothActivity.inputStream.read(packetByte);
                        }
                        catch (IOException e) {
                            e.printStackTrace();
                        }
 
                        for(int i = 0; i < byteAvailabe; i++) {
                            final byte readData = packetByte[i];
                            if(readData != '\n') {
                                // 읽어온 바이트 배열을 인코딩 된 배열로 복사
                                byte[] encodedByte = new byte[readBufferPosition];
                                System.arraycopy(readBuffer, 0, encodedByte, 0, encodedByte.length);
 
                                try {
                                    String data = new String(encodedByte, "US-ASCII");
                                }
                                catch (UnsupportedEncodingException e) {
                                    e.getStackTrace();
                                }
 
                                readBufferPosition = 0;
 
                                final PendingIntent pendingIntent = PendingIntent.getActivity(BluetoothCommunicationActivity.this0,
                                        new Intent(getApplicationContext(), BluetoothCommunicationActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);
 
                                handler.post(new Runnable() {
                                    // 알림 객체 선언
                                    NotificationManager notificationManager;
                                    Notification.Builder builder;
 
                                    @Override
                                    public void run() {
                                        // 버튼 숨기기
                                        button_pairing.setVisibility(View.INVISIBLE);
                                        listView_alarm_log.setVisibility(View.VISIBLE);
                                        textView_alarm_log.setVisibility(View.VISIBLE);
 
                                        // 0 입력 받을 때
                                        if(readData == 48) {
                                            linearLayout_setcolor.setBackgroundColor(Color.rgb(185,255,198));
                                            textView_connection_status.setTextColor(Color.BLACK);
                                            textView_connection_status.setText("블루투스 연결 상태 : 정상");
                                            textView_connection_explaination.setText("블루투스 디바이스와 성공적으로 페어링했습니다.");
                                        }
                                        // 1 입력 받을 때
                                        else {
                                            // 현재 시간을 받아옴
                                            long now = System.currentTimeMillis();
                                            Date date = new Date(now);
                                            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM월 dd일 - HH시 mm분 ss초");
                                            String nowDate = simpleDateFormat.format(date);
 
                                            linearLayout_setcolor.setBackgroundColor(Color.rgb(243,197,197));
                                            textView_connection_explaination.setText("센서가 감지되었습니다.");
 
                                            // 알림 객체 설정
                                            builder = new Notification.Builder(BluetoothCommunicationActivity.this)
                                                    .setSmallIcon(R.drawable.ic_launcher_background) // 아이콘 설정
                                                    .setContentTitle(nowDate) // 제목 설정
                                                    .setContentText("센서가 감지되었습니다."// 내용 설정
                                                    .setAutoCancel(true)
                                                    .setTicker("센서가 감지되었습니다."// 한줄 내용 설명
                                                    .setContentIntent(pendingIntent);
                                            notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
                                            // 젤리빈 버전 이상 알림
                                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                                                notificationManager.notify(0, builder.build());
                                            }
 
                                            // 로그 리스트에 추가
                                            list.add(log_num + ". " + nowDate);
                                            arrayAdapter.notifyDataSetChanged();
                                            log_num++;
 
                                            // 진동 객체 설정
                                            Vibrator vibrator = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
                                            vibrator.vibrate(1000);
 
                                            // 알림 소리 설정
                                            Uri uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
                                            Ringtone ringtone = RingtoneManager.getRingtone(getApplicationContext(), uri);
                                            ringtone.play();
 
                                            // WakeLock 깨우기 및 해제
                                            wakeLock.acquire();
                                            wakeLock.release();
                                        }
                                    }
                                });
                            }
                        }
                    }
                    // 데이터가 수신되지 않은 경우
                    else {
                        // 메세지 핸들러 호출
                        Message msg = handler.obtainMessage();
                        handler.sendMessage(msg);
                    }
 
                    try {
                        // 2초 간격으로 반복
                        Thread.sleep(1000);
                    }
                    catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        // 쓰레드 시작
        thread.start();
    }
}
 
cs




안녕하세요 열코입니다.


프로그램 개발 중에 설정 화면을 불러와야 하는 상황이 발생할 수도 있죠?

이번에는 안드로이드 프로그래밍 중 설정 화면을 호출하는 방법에 대해 알아보겠습니다.


저는 먼저 activity_main.xml에 버튼을 아래와 같이 추가했습니다.


<Button

            android:layout_gravity="center_horizontal"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:id="@+id/setting_btn"

            android:text="설정 버튼">

</Button>


위 코드에 대해 잠깐 설명하자면,

android:layout_gravity="center_horizontal" : 버튼을 레이아웃의 중앙에 정렬합니다.

android:layout_width="wrap_content" : 버튼의 너비를 설정합니다.

android:layout_height="wrap_content" : 버튼의 높이를 설정합니다.

android:id="@+id/setting_btn" : 버튼의 id를 설정합니다. (java 단에서 사용하기 위함)

android:text="설정 버튼" : 버튼의 텍스트를 설정합니다.



다음으로 MainActivity.java로 넘어갑니다.

먼저 버튼 객체를 하나 생성해 줍시다.


private Button buttonSetting;


그리고 버튼객체를 xml의 버튼과 연결해줘야겠죠?


buttonSetting = (Button)findViewById(R.id.setting_btn);


위와 같이 xml에서 버튼에 설정한 id를 통해 java의 버튼객체와 연결해줍니다.


그리고 버튼을 클릭했을 때 이벤트를 발생시켜주어야 합니다.

이를 버튼 클릭 이벤트라고 하며, onClickListener를 사용하여 아래와 같이 구현할 수 있습니다.


buttonSetting.setOnClickListener(new View.OnClickListener() {

    @Override

    public void onClick(View v) {

        Intent intent = new Intent(Settings.ACTION_SETTINGS);

        startActivityForResult(intent, 0);

    }

});


Intent를 사용하여 새로운 창을 생성하여 설정 화면을 띄워주는 코드입니다.

코드가 실행되고 난 후 ActivityForResult를 통해 onActivityResult가 호출되게 됩니다.

위의 Settings.ACTION_SETTINGS에서 Intent의 매개변수를 변경하여 원하는 설정 화면을 띄울 수 있습니다.

Settings의 메소드는 아래와 같습니다.



ACTION_SETTINGS : 기본 설정 화면

ACTION_ACCESSIBILITY_SETTINGS : 접근성 설정 화면

ACTION_AIRPLANE_MODE_SETTINGS : 비행기 모드 설정 화면

ACTION_APPLICATION_SETTINGS : 앱 관련 설정 화면

ACTION_BLUETOOTH_SETTINGS : 블루투스 설정 화면

ACTION_DATE_SETTINGS : 날짜 및 시간 설정 화면

ACTION_DISPLAY_SETTINGS : 디스플레이 설정 화면

ACTION_FINGERPRINT_ENROLL : 지문 등록 설정 화면

ACTION_INTERNAL_STORAGE_SETTINGS : 내부 저장소 설정 화면

ACTION_SOUND_SETTINGS : 사운드 및 볼륨 설정 화면

ACTION_WIFI_SETTINGS : 와이파이 설정 화면


그 외 설정에 대해선 여기를 확인하세요.


설정이 모두 끝난 후 다시 앱으로 돌아오면 Intent에서 onActivityResult를 호출하게 됩니다.

onActivityResult는 오버라이딩 메소드로 alt+insert키를 눌러 Override Method를 선택한 후 

onActivityResult를 생성한 후 다음과 같이 코드를 작성합니다.


@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    switch(requestCode) {

        case 0 :

            // 할일 작성

            break;

    }

    super.onActivityResult(requestCode, resultCode, data);

}


위에 Intent를 최초 호출할 때 startActivityForResult에서 두번째 매개변수로 0을 보내주었었죠?

그 요청 코드가 바로 여기서 사용되는 코드입니다.

설정 화면에서 다시 앱으로 넘어오면서 onActivityResult 가 호출되며, swtich문에서 case 0부분에 걸리게 됩니다.

저는 설정 화면에서 어떤 설정을 하고 돌아왔을 때 리스트를 갱신해야 하므로 위와 같은 코드를 사용했으며,

필요시에만 작성하셔도 됩니다.



이상 '안드로이드 설정 화면 호출'에 대해 알아보았습니다.

질문 또는 오타나 잘못된 정보가 있는 경우 댓글로 달아주세요!

공감♡ 버튼을 눌러주시면 더욱 유용하고 좋은 포스팅으로 찾아뵙겠습니다.





안녕하세요 열코입니다.

안드로이드 앱 개발 중 알림 기능을 구현하는 도중 휴대폰이 꺼져있는 상태에서

알림이 발생하면 화면을 깨우는 기능이 필요하여 검색하는 도중

안드로이드에서 제공하는 WakeLock에 대해 알게되었고 이에 대한 내용을 정리했습니다.

WakeLock은 PowerManger 클래스의 메소드이며 앱이 항상 켜져있음을 나타내는 메커니즘입니다.

그러면 이제 WakeLock을 사용하는 방법에 대해 알아보겠습니다.


안드로이드 기능 WakeLock을 사용하기 위해서는 안드로이드 권한을 얻어야합니다.


※ WakeLock 기능 사용을 위해 안드로이드 권한 얻는 법

WakeLock 권한을 얻는 방법은 간단합니다.

AndroidManifest.xml에 다음과 같은 코드를 추가합니다.

<uses-permission android:name="android.permission.WAKE_LOCK" />




안드로이드에게 WakeLock 권한을 얻었으니 이제 사용하러 가야겠죠?

MainActivity로 갑니다.

WakeLock을 사용하기 위해 PowerManager와 WakeLock객체를 선언해야합니다.

WakeLock을 사용하려는 코드쪽이나 클래스 상단부분에 다음과 같이 선언합니다.


PowerManager powerManager;

PowerManager.WakeLock wakeLock;


그리고 WakeLock을 사용하려는 코드쪽이나 onCreate 클래스내에 다음과 같이 정의합니다.


powerManager = (PowerManager)getSystemService(Context.POWER_SERVICE);

wakeLock = powerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.ON_AFTER_RELEASE, "WAKELOCK");


WakeLock 객체 정의 부분에 newWakeLock 함수의 매개변수에 대한 설명입니다.


PowerManger.SCREEN_BRIGHT_WAKE_LOCK : CPU와 화면을 밝게하며 키보드는 off 상태입니다.

(여기서 화면을 살짝 어둡게 키기위해서 PowerManger.DIM_WAKE_LOCK을 사용할 수도 있습니다.

또한 CPU만 On시키기 위해 PowerManger.PARTIAL_WAKE_LOCK을 사용하기도 합니다.)

PowerManger.ACQUIRE_CAUSES_WAKEUP : WakeLock에게 조명이 켜지도록 합니다.

PowerManger.ON_AFTER_RELEASE : WakeLock이 Release되고 조명이 오래 유지되도록 합니다.


자 이제 WakeLock을 사용하기 위한 모든 준비가 끝났습니다.

WakeLock을 사용하려는 코드쪽으로 이동해서 다음과 같은 코드를 추가합니다.


wakeLock.acquire(); // WakeLock 깨우기

wakeLock.release(); // WakeLock 해제



위와 같이 acquire() 함수를 통해 잠들어있는 단말기를 깨울 수 있습니다.

여기서 바로 release() 함수를 통해 WakeLock을 해제해줍니다.

WakeLock을 사용하는 순간 단말기에 많은 배터리가 지속해서 소모하기 때문에 WakeLock이

더이상 필요없는 시점에 최대한 빨리 release() 작업을 수행하는것이 바람직합니다.

그렇기 때문에 단말기를 깨운 직후 바로 WakeLock을 해제해주는 것입니다.


또한 acquire() 함수에 long 형식의 매개변수를 추가함으로써 WakeLock을 해제하기 전까지

시간제한(milisecond 단위)을 지정할 수도 있습니다.


또한 안드로이드 WakeLock에 대해 더 궁금하신 사항은 여기를 확인하세요.



이상 '안드로이드 WakeLock'에 대해 알아보았습니다.

질문 또는 오타나 잘못된 정보가 있는 경우 댓글로 달아주세요!

공감♡ 버튼을 눌러주시면 더욱 유용하고 좋은 포스팅으로 찾아 뵙겠습니다.





안녕하세요 열코입니다.

오늘은 안드로이드 앱에서 진동 사용하는 방법에 대해 알아보겠습니다.

이 진동 기능은 사용자에게 어떤 알림을 직관적으로 주기 위해 사용하는데요.

보통 기존에 앱에서는 소리와 진동을 함께 줌으로써 사용자에게 알림 확인을 극대화시킵니다.

따라서 이 진동 기능은 앱 개발에서 꼭 필요한 기능이라고 할 수 있습니다.

그렇다면 안드로이드 앱에서 진동 기능을 어떻게 구현하는지에 대해 알아보겠습니다.


다른 기능도 마찬가지지만 안드로이드에서 제공하는 기본적인 기능(카메라, 와이파이 등)을

사용하기 위해서는 권한이 필요합니다.

이 진동(Vibrate) 기능을 사용하기 위해서도 마찬가지인데요.


※ 진동 기능을 사용하기 위해 안드로이드 권한 얻는법

방법은 아주 간단합니다.

AndroidManifest.xml에 다음과 같은 코드를 추가합니다.

<uses-permission android:name="android.permission.VIBRATE" />


자 이제 안드로이드 앱에서 진동기능을 사용하기 위한 과정이 모두 끝났습니다.

정말 간단하죠?


이제 실제로 프로그램내에서 진동 기능을 사용하기 위한 방법에 대해 알아보겠습니다.

먼저 첫번째로 Vibrator 객체를 만들어주어야합니다.


진동 기능을 사용하려고 하는 코드쪽이나 클래스 상단부분에 다음과 같이 선언합니다.

private Vibrator vibrator;


다음 진동기능을 사용하려는 코드쪽에서 vibrator 객체를 다음과 같이 정의합니다.

 vibrator = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);


이제 vibrator 객체를 통해 진동을 발생시키기만 하면 됩니다.

안드로이드에서 제공하는 Vibrator 객체의 진동 발생 방법은 두가지가 있습니다.

첫번째는 지정된 시간동안 진동하는 방법이고

두번째는 지정된 패턴으로 진동하는 방법입니다.


먼저 첫번째, 지정된 시간동안 진동하는 방법에 대해 알아보겠습니다.

vibrator.vibrate(1000); // 1초간 진동


이렇게 하면 끝입니다.

프로그램이 작동되다가 해당 코드를 만나면 1초간 진동이 발생합니다.

여기서 vibrate 함수의 매개변수로 1000을 주었는데,

이는 단위가 milisecond인 int형 매개변수로써, 1000 ms = 1s 입니다.

0.5초간 진동을 주고싶다면 1000대신 500을 입력하면 됩니다.



두번째로, 지정된 패턴으로 진동하는 방법입니다.

두번째 방법은 미리 패턴을 다음과 같이 지정 해 주어야합니다.

long[] pattern = {1000, 50, 1000, 50}; // 1초 진동, 0.05초 대기, 1초 진동, 0.05초 대기

vibrator.vibrate(pattern, -1);


위와같이 패턴을 설정할 때에는 진동, 대기, 진동, 대기... 이런 순으로 지정해주시면 됩니다.

만약 1초간 진동을 3번 울리고 싶으시면 3번 반복하시면 됩니다.

두번째 매개변수인 -1은 반복하지 않겠다는 설정입니다.

다시 말해 지정된 패턴동안 진동을 단 1번만 발생시키겠다는 뜻입니다.


만약 두번째 매개변수를 0으로 준다면 진동은 지정된 패턴으로 무한으로 진동하게 됩니다.

이를 멈추게 하기위해서는 다음과 같은 코드를 추가합니다.

vibrator.cancel();


추가로 단말기의 기본 알림음을 발생시키는 코드를 추가하여 진동+소리로 알릴 수 있습니다

Uri uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

Ringtone ringtone = RingtoneManager.getRingtone(getApplicationContext(), uri);

ringtone.play();



android vibrator에 대해 더 궁금하신 사항은 여기를 클릭하세요.


이상 '안드로이드 진동 기능 사용법'에 대해 알아보았습니다.

질문 또는 오타나 잘못된 정보가 있는 경우 댓글로 달아주세요!

공감♡ 버튼을 눌러주시면 더욱 유용하고 좋은 포스팅으로 찾아 뵙겠습니다.






안드로이드앱 개발중 뜬금없이 프로젝트가 실행되지 않았다.

Run App을 눌러봐도 다음과 같은 오류만 나올 뿐


Error: Activity class { ... } does not exist.


전혀 실행되지 않았다.


프로젝트를 처음 실행하면 앱이 하나 생성되는데,

USB를 컴퓨터에 연결한 상태에서 앱을 삭제했기 때문에

발생하는 문제였다.

위와 같은 오류가 나는 이유는 ADB는 앱이 휴대폰에 있는걸로 인식하기 때문이다.


해결방법은 다음과 같다.

설정에 들어가면 저장소(Storage)가 있는데 해당 앱 이름을 찾아서 삭제해주면 된다.






혹시 다른 문제가 발생한 유저들을 위해

앱을 삭제하지 않았는데 위와 같은 오류가 발생했을 시 해결방안


1. 안드로이드 스튜디오에서 상단 메뉴에 build - Clean Project 클릭, rebuild project 클릭 후 실행


2. 해당 프로젝트 코드를 모두 백업하고 프로젝트 삭제 후 새로 만들어서 사용


3. build.gradle에 다음과 같이 코드 추가

android {
defaultConfig {
    applicationId "패키지명"  
  }
}


4. AndroidManifest.xml에서 다음과 같이 변경

<activity android:name="패키지명.액티비티명" >



위 4가지 방법을 모두 사용해봐도 문제가 해결되지 않을 시 댓글로 문의주세요.




to Top