본문 바로가기

Android

.NET Android 관련 블루투스 프로젝트 기능 정리

이 글은 .net android webview, 블루투스 기능 과 blazor server를 활용한 프로젝트에서 사용한 기능 정리입니다.

 

1. 안드로이드 퍼미션 추가

<!--네트워크 상태 퍼미션-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!-- 카메라 퍼미션 -->
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" android:required="true" />
<!-- 5.0 버전 파일업로드 퍼미션 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<!-- 외부 저장소 사용 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<!--블루투스 권한-->
<uses-permission
android:name="android.permission.BLUETOOTH"
android:maxSdkVersion="30" />
<uses-permission
android:name="android.permission.BLUETOOTH_ADMIN"
android:maxSdkVersion="30" />
<!-- 기기 검색을 위한 권한(위치가 필요하지 않고 장비만 검색하기 위해 위치는 무시) -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"
android:usesPermissionFlags="neverForLocation" />
<!-- 페어링된 기기를 확인하기 위한 권한 -->
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />

 

2. OnCreate 매서드

OnCreate 매서드에서 코드 추가시 동작하는 기능

ㄱ.화면 고정

RequestedOrientation = ScreenOrientation.Landscape; //세로화면 고정
RequestedOrientation = ScreenOrientation.Portrait; //가로화면 고정

ㄴ.웹뷰 id 가져오기
Android.Webkit.WebView webView = (WebView)FindViewById(Resource.Id.webview);

ㄷ.웹뷰에서 JS 사용 허용

webView.Settings.JavaScriptEnabled = true;

ㄹ.웹뷰를 실행하는 디바이스 고유 ID 가져오기

string deviceid = Settings.Secure.GetString(this.ContentResolver, Settings.Secure.AndroidId);

ㅁ.웹뷰 실행

webView.LoadUrl("url");

반응형

3.블루투스 연결 다이얼로그

ㄱ. 블루투스 어댑터를 디폴트 어댑터로 설정

//bluetoothAdapter 값이 null 이면 디바이스가 블루투스를 지원하지 않는다는 의미

Android.Bluetooth.BluetoothAdapter bluetoothAdapter = BluetoothAdapter.DefaultAdapter;

 

ㄴ.블루투스 활성화 상태인지 아닌지 확인

bool bluetoothenable = bluetoothAdapter.Enable();

ㄷ.해당기기에 페어링 되어있는 불루투스 기기 찾기

ICollection<BluetoothDevice> devices = bluetoothAdapter.BondedDevices;

ㄹ. 디바이스에 기기 페어링을 위한 다이얼로그 생성

AlertDialog.Builder builder = new AlertDialog.Builder(Instance);

builder.SetTitle("페어링 되어있는 블루투스 디바이스 목록");

// 페어링 된 각각의 디바이스의 이름과 주소를 저장할 리스트 선언 및 추가
List<string> list = new List<string>();
List<string> listaddress = new List<string>();

foreach (var m in devices)
{
      list.Add(m.Name);
      listaddress.Add(m.Address);
}

list.Add("취소");

ㅁ. 선택시 이벤트 추가

EventHandler<DialogClickEventArgs> handler = (s, o) => {

if (o.Which != list.Count - 1)
{
        if (connectedDevice == "" || connectedDevice != list[o.Which])
        {
                connectDevice(listaddress[o.Which], list[o.Which]);
        }
}};

 // 해당 아이템을 눌렀을 때 호출 되는 이벤트 리스너
 builder.SetItems(list.ToArray(), handler);

ㅂ. 뒤로가기 버튼 누를 때 창이 안닫히도록 설정

builder.SetCancelable(false);

ㅅ. 다이얼로그 생성

AlertDialog alertDialog = builder.Create();

alertDialog.Show();

 

4.디바이스와 블루투스 연결

3번 ㅂ항목의 connectDevice(deviceaddress, deviceName)매서드에 관한 내용

ㄱ.디바이스 주소를 이용해서 bluetoothDevice 변수 값 할당

Android.Bluetooth.BluetoothDevice bluetoothDevice = bluetoothAdapter.GetRemoteDevice(deviceaddress);

ㄴ. UUID 생성

UUID uuid = Java.Util.UUID.FromString("00001101-0000-1000-8000-00805f9b34fb");

블루투스 프로토콜에 해당하는 값에 대한 내용은 아래 링크 참조

https://dsnight.tistory.com/13

 

[안드로이드] 블루투스 프로토콜 UUID 리스트

안드로이드 블루투스통신 예제는 인터넷에 많이 있을 것이다. 예를들면 블루투스통신 채팅 같은 예제.. 그러나 예제를 수정하여 블루투스 통신을 구현하려고 할 때 연결이 잘 안될수도 있다. 블

dsnight.tistory.com

 

ㄷ. Rfcomm 채널을 통해 블루투스 디바이스와 통신하는 소켓 생성 및 연결

Android.Bluetooth.BluetoothSocket bluetoothSocket = bluetoothDevice.CreateRfcommSocketToServiceRecord(uuid);

//블루투스 연결 실패 시 아래 코드에서 오류가 발생함.

bluetoothSocket.Connect();

 

ㄹ. 데이터 송,수신 스트림

System.IO.Stream outputStream = bluetoothSocket.OutputStream;

System.IO.inputStream = bluetoothSocket.InputStream;

 

ㅁ. 블루투스 수신 시 이벤트를 thread로 실행

ThreadStart ts1 = new ThreadStart(receiveData);

thread = new System.Threading.Thread(ts1);

thread.Start();

 

5. 블루투스 수신 이벤트

// 데이터를 수신 버퍼 생성
byte[] readBuffer = new byte[1024];
// 데이터를 수신 확인

int byteAvailable = inputStream.Read(readBuffer);
if (byteAvailable > 0)
{
     string receivedata = System.Text.Encoding.Default.GetString(readBuffer);
     Instance.webView.Post(() => { Instance.webView.LoadUrl("javascript:'웹의js함수명'('" + receivedata  + "')"); });
}

 

6. Web과 .Net  Android  연계

ㄱ. Web에서  .Net Android 

function CallAndroidMethod() {
      " Android  프로젝트명"." Android  매서드";

      //AndroidApp1이라는 프로젝트에서 AndroidMethod 라는 매서드를 실행한다.

      //AndroidApp1.AndroidMethod();
}

 

// Android  쪽 매서드 위에 [JavascriptInterface], [Export] 선언해주면 웹에서도 호출 가능하게 한다

[JavascriptInterface]
[Export]

public void AndroidMethod (){

       //안드로이드에서 실행하는 내용

}

 

ㄴ. .Net Android에서 Web

Instance는 oncreate 매서드에서 MainActivity  Instance = this; 코드를 전역변수로 선언 후 사용

Instance.webView.Post(() => { Instance.webView.LoadUrl("javascript:'웹의js함수명'('"파라미터"')"); });

 

7. 파일 다운로드 로직

 

private class MyDownloadListener : Java.Lang.Object, IDownloadListener
{
    public void OnDownloadStart(string url, string userAgent, string contentDisposition, string mimetype, long contentLength)
    {
        try
        {
            DownloadManager.Request request = new DownloadManager.Request(Android.Net.Uri.Parse(url)); // [다운로드 매니저 객체 생성]
            DownloadManager manager = (DownloadManager)Android.App.Application.Context.GetSystemService(Context.DownloadService);

            string[] parts = contentDisposition.Split(";");
            var fileName = parts[1].Split("=")[1];
            request.SetMimeType(mimetype);
            request.AddRequestHeader("User-Agent", userAgent);
            request.SetDescription("Downloading File"); // [다운로드 중 표시되는 내용]
            request.SetTitle(fileName);// [다운로드 제목 표시]
            request.AllowScanningByMediaScanner();
            request.SetNotificationVisibility((DownloadVisibility)1); // [앱 상단에 다운로드 상태 표시]
            request.SetDestinationInExternalPublicDir(Android.OS.Environment.DirectoryDownloads, fileName);
            manager.Enqueue(request);
        }
        catch
        {

        }
    }
}

코드 작성 후
OnCreate 부분에 아래 코드 추가

webView.SetDownloadListener(new MyDownloadListener()); 

 

8.사진 업로드

public class CustomWebChromeClient : WebChromeClient
{
    Activity mActivity = null;
    public CustomWebChromeClient(Activity activity)
    {
        mActivity = activity;
    }
    public override bool OnShowFileChooser(Android.Webkit.WebView webView, IValueCallback filePathCallback, FileChooserParams fileChooserParams)
    {
        MainActivity.mUploadCallbackAboveL = filePathCallback;

        //TakePhoto();  
        Java.IO.File imageStorageDir = new Java.IO.File(Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryPictures), Guid.NewGuid() + ".jpg");

        // Create camera captured image file path and name, add ticks to make it unique   


        MainActivity.imageUri = FileProvider.GetUriForFile(mActivity,
                    " "com.companyname.프로젝트명.fileprovider" " , imageStorageDir);
        //Create camera capture image intent and add it to the chooser  
        Intent captureIntent = new Intent(MediaStore.ActionImageCapture);
        captureIntent.PutExtra(MediaStore.ExtraOutput, MainActivity.imageUri);

        Intent i = new Intent(Intent.ActionGetContent);
        i.AddCategory(Intent.CategoryOpenable);
        i.SetType("image/*");
        Intent chooserIntent = Intent.CreateChooser(i, "Choose image");

        chooserIntent.PutExtra(Intent.ExtraInitialIntents, new Intent[] { captureIntent });

        MainActivity.Instance.StartActivityForResult(chooserIntent, MainActivity.PHOTO_REQUEST);
        return true;
    }
}

코드 작성 후

OnCreate 부분에 아래 코드 추가
webView.SetWebChromeClient(new CustomWebChromeClient(this)); 

반응형