본문 바로가기
Android

비콘감지

by 일용직 코딩노동자 2019. 9. 10.
728x90
반응형

MainActivity.java

import java.util.ArrayList;
import java.util.Collection;

import java.util.List;


import org.altbeacon.beacon.Beacon;
import org.altbeacon.beacon.BeaconConsumer;
import org.altbeacon.beacon.BeaconManager;
import org.altbeacon.beacon.BeaconParser;
import org.altbeacon.beacon.MonitorNotifier;
import org.altbeacon.beacon.RangeNotifier;
import org.altbeacon.beacon.Region;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

import com.estimote.sdk.SystemRequirementsChecker;

public class MainActivity extends Activity implements BeaconConsumer
{
private String TAG = MainActivity.class.getSimpleName();
private BeaconManager beaconManager;
// 감지된 비콘들을 임시로 담을 리스트
private List<Beacon> beaconList = new ArrayList<>();
TextView textView;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);


SystemRequirementsChecker.checkWithDefaultDialogs(this);


// 실제로 비콘을 탐지하기 위한 비콘매니저 객체를 초기화
beaconManager = BeaconManager.getInstanceForApplication(this);
textView = (TextView)findViewById(R.id.tvId);

// 여기가 중요한데, 기기에 따라서 setBeaconLayout 안의 내용을 바꿔줘야 하는듯 싶다.
// 필자의 경우에는 아래처럼 하니 잘 동작했음.
beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));

// 비콘 탐지를 시작한다. 실제로는 서비스를 시작하는것.
beaconManager.bind(this);


}

@Override
protected void onDestroy() {
super.onDestroy();
beaconManager.unbind(this);
}

@Override
public void onBeaconServiceConnect() {

beaconManager.addMonitorNotifier(new MonitorNotifier() {
@Override
public void didEnterRegion(Region region) { //이 엔터를 타야만 비콘검색가능
// textView.setText("진입 \n");
}

@Override
public void didExitRegion(Region region) {
Log.d(TAG,"Exit : " + region.getId1());
}

@Override
public void didDetermineStateForRegion(int i, Region region) {

}
});

beaconManager.addRangeNotifier(new RangeNotifier() {
@Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
if (beacons.size() > 0) {
beaconList.clear();
for (Beacon beacon : beacons) {
beaconList.add(beacon);
}
}
}
});
try
{
//beaconManager.startMonitoringBeaconsInRegion(new Region("myRangingUniqueId", null, null, null));
beaconManager.startRangingBeaconsInRegion(new Region("myRangingUniqueId", null, null, null));
}
catch (RemoteException e)
{

}
}

// 버튼이 클릭되면 textView 에 비콘들의 정보를 뿌린다.
public void OnButtonClicked(View view){
// 아래에 있는 handleMessage를 부르는 함수. 맨 처음에는 0초간격이지만 한번 호출되고 나면
// 1초마다 불러온다.
handler.sendEmptyMessage(0);
}

Handler handler = new Handler() {
public void handleMessage(Message msg) {

// 비콘의 아이디와 거리를 측정하여 textView에 넣는다
for(Beacon beacon : beaconList)
{
// textView.append("했음 \n");+
textView.setText("ID : " + beacon.getId2() + " / " + "Distance : " + Double.parseDouble(String.format("%.3f", beacon.getDistance())) + "m\n");

}

// 자기 자신을 1초마다 호출
handler.sendEmptyMessageDelayed(0, 1000);
}
};
}

activity_main.xml

 

<?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">

<TextView
android:id="@+id/tvId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<Button
android:id="@+id/btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="비콘버튼"
android:onClick="OnButtonClicked"
/>
</android.support.constraint.ConstraintLayout>

메니페스트

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.yujin.myapplication">

<!--
안드로이드 API 23 (마시멜로우) 이상의 버전에서 필요한 권한입니다.
ACCESS_COARSE_LOCATION 혹은 ACCESS_FINE_LOCATION 중 1개의 권한만 필요로 합니다.
당사에서는 ACCESS_COARSE_LOCATION 권한을 권장합니다.
-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

<!-- 블루투스 -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />

<uses-feature
android:name="android.hardware.bluetooth_le"
android:required="true" />

<application

android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="MyApplication"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">

<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>

 

--결과--

 

궁금하신 사항은 댓글 남겨주세요.

728x90
반응형

댓글