본문 바로가기
Android/기본기능

[Android] Android platform (API 30)에서 빌드가 되는 Test app 기본구조

by 백호루이 2023. 2. 16.
반응형

Android Studio에서 Empty app을 만들면 Emulator에서는 잘 돌아가도 Android platform에 이식해서 빌드를 하면 안되는 경우가 많다. 이를 수정한 소스코드를 기록용으로 저장한다.

 

아래는 버튼을 누르면 페어링된 기기의 블루투스 정보를 얻어서 api를 호출하는 간단한 앱이다.

 

<UI>

<MainActivity.java>

package com.lge.hfpclient;

//import androidx.appcompat.app.AppCompatActivity; // for Android Studio
import android.support.v7.app.AppCompatActivity; // for Android Platform

import android.Manifest;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothHeadsetClient;

import java.util.*;

public class MainActivity extends AppCompatActivity {
    private Button speakButton;
    private TextView speechTranscription;

    BluetoothAdapter mBluetoothAdapter;
    BluetoothHeadsetClient mHfpClientProfile;

    private static final String TAG = "HFP_Client";


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

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
		    requestPermissions(
		            new String[]{
		                    Manifest.permission.BLUETOOTH
		            },
		            1);
		}

        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        mBluetoothAdapter.getProfileProxy(this, new ProfileServiceListener(), BluetoothProfile.HEADSET_CLIENT);
        mBluetoothAdapter.getProfileProxy(this, new ProfileServiceListener(), BluetoothProfile.HEADSET);
        // Get a reference to the TextView and Button from the UI
        speechTranscription = findViewById(R.id.speechTranscription);
        speakButton = findViewById(R.id.speakButton);

        // Wire up speakButton to an onClickListener
        speakButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // get the list of paired devices
                Set<BluetoothDevice> devices = mBluetoothAdapter.getBondedDevices();
                BluetoothDevice device = null;
                if (devices.size() > 0) {
                    Iterator<BluetoothDevice> iter = devices.iterator();
                    while (iter.hasNext()) {
                        device = iter.next();
                        Log.d(TAG, "device info: "+device.getName()+"-"+device.getAddress());
                    }
                    // Voice Recognition Test
                    if (device == null) {
                        Log.d(TAG, "device == null");
                        return;
                    }
                    if (mHfpClientProfile == null) {
                        Log.d(TAG, "mHfpClientProfile == null");
                        return;
                    }

                    boolean ret = mHfpClientProfile.startVoiceRecognition(device);
                    Log.d(TAG, "startVoiceRecognition = "+ret);
                }
            }
        });
    }

    @Override
    protected void onResume() {
        super.onResume();
        mBluetoothAdapter.getProfileProxy(this, new ProfileServiceListener(), BluetoothProfile.HEADSET_CLIENT);
        mBluetoothAdapter.getProfileProxy(this, new ProfileServiceListener(), BluetoothProfile.HEADSET);
    }

    class ProfileServiceListener implements BluetoothProfile.ServiceListener {
        @Override
        public void onServiceConnected(int profile, BluetoothProfile bluetoothProfile) {
            Log.w(TAG, "onServiceConnected : "+ profile);
            switch (profile) {
                case BluetoothProfile.HEADSET_CLIENT:
                    mHfpClientProfile = (BluetoothHeadsetClient) bluetoothProfile;
                    break;
                default:
                    Log.w(TAG, "onServiceConnected : "+ profile);
            }
        }
    
        @Override
        public void onServiceDisconnected(int profile) {
            Log.w(TAG, "onServiceDisconnected : "+ profile);
            switch (profile) {
                case BluetoothProfile.HEADSET_CLIENT:
                    mHfpClientProfile = null;
                    break;
                default:
                    Log.w(TAG, "onServiceDisconnected : "+ profile);
            }
        }
    }
}

 

<AndroidManifest.xml>

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.lge.hfpclient">
    <uses-sdk android:minSdkVersion="23" />
    <!-- Added permissions -->
    <uses-permission android:name="android.permission.RECORD_AUDIO"/>
    <uses-permission android:name="android.permission.BLUETOOTH"/>
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
    <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE"/>
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity 
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>

 

<activity_main.xml>

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="vertical"
    tools:context=".MainActivity">
	<TextView
	    android:layout_width="match_parent"
	    android:layout_height="wrap_content"
	    android:text="Speech transcription will appear here"
	    android:id="@+id/speechTranscription" />

	<Button
	    android:id="@+id/speakButton"
	    android:layout_width="match_parent"
	    android:layout_height="wrap_content"
	    android:text="Speak"
	    android:textAllCaps="false" />
</LinearLayout>

 

<Android.mk>

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := optional
LOCAL_CERTIFICATE := platform
LOCAL_DEX_PREOPT := false
LOCAL_PACKAGE_NAME := HfpClient
LOCAL_SYSTEM_EXT_MODULE := true
LOCAL_PRIVATE_PLATFORM_APIS := true
LOCAL_SRC_FILES := $(call all-subdir-java-files)

LOCAL_STATIC_ANDROID_LIBRARIES := \
    $(ANDROID_SUPPORT_DESIGN_TARGETS) \
    android-support-transition \
    android-support-v13 \
    android-support-v7-appcompat \
    android-support-v7-cardview \
    android-support-v7-recyclerview \
    android-support-v7-palette \
    android-support-v4

#LOCAL_JAVA_LIBRARIES += telephony-common

LOCAL_RESOURCE_DIR += \
    $(LOCAL_PATH)/res

LOCAL_MANIFEST_FILE := AndroidManifest.xml

include $(BUILD_PACKAGE)
반응형

댓글