안드로이드 개발 질문/답변
(글 수 45,052)
안녕하세요. 이번에 새로 가입하게 된 한입먹은사과입니다.
안드로이드 개발을 공부하다가 서비스와 액티비티간 값을 전달해야 할 일이 생겨 aidl을 사용하게 되었습니다.
그런데 액티비티에서 값이 정상적으로 넘어가지 않는 것 같더군요.
일단 코드를 첨부하겠습니다.
AntitheftService.java
public class AntitheftService extends Service{
// Debugging
private static final String TAG = "AntitheftService";
private static final boolean D = true;
//set Limit of Temperature and Humidity
public static int templimit;
public static int humiditylimit;
private Handler mHandler;
boolean ModeAlert = false;
int Temp = 0;
boolean Sensor1 = false;
boolean Sensor2 = false;
ServiceBody sb1;
@Override
public IBinder onBind(Intent intent){
//TODO Auto-generated method stub
sb1 = new ServiceBody();
sb1.start();
return mService;
}
Context context = getApplicationContext();
class ServiceBody extends Thread
{
public void start(){
Log.i(TAG,"Service task is running.");
while(true){
if(ModeAlert == true) //If the mode is alert....
{
if(Temp >= 50){
//The house is on fire.
Log.i(TAG, "The House is on fire");
}
if(Sensor1 = true){
//The door is open.
//30 Second...
Log.i(TAG,"The Door is open.");
}
if(Sensor2 = true){
//The window is open.
//Security Breach.
Log.i(TAG,"The window is open. Security Breach");
}
}
else if(ModeAlert == false){
Log.i(TAG,"ignore all.");
}
}
}
}
IATService.Stub mService = new IATService.Stub(){
public int getTemp(int temp) throws RemoteException {
Temp = temp;
Log.i(TAG,"Current temperature is "+getString(Temp) + "degree");
return Temp;
}
public boolean getSensor1(boolean s1) throws RemoteException{
Sensor1 = s1;
return Sensor1;
}
public boolean getSensor2(boolean s2) throws RemoteException{
//TODO Auto-generated method stub
Sensor2 = s2;
return Sensor2;
}
public boolean getState(boolean state) throws RemoteException{
ModeAlert = state;
return ModeAlert;
}
};
@Override
public void onCreate() {
super.onCreate();
Log.e(TAG,"Service is created.");
}
@Override
public void onDestroy(){
super.onDestroy();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId){
return super.onStartCommand(intent, flags, startId);
}
}
그리고 액티비티인
BluetoothApp.java
/**
* This is the main Activity that displays the current chat session.
*/
public class BluetoothApp extends Activity {
// Debugging
private static final String TAG = "BluetoothApp";
private static final boolean D = true;
// Message types sent from the BluetoothAppService Handler
public static final int MESSAGE_STATE_CHANGE = 1;
public static final int MESSAGE_READ = 2;
public static final int MESSAGE_WRITE = 3;
public static final int MESSAGE_DEVICE_NAME = 4;
public static final int MESSAGE_TOAST = 5;
// Key names received from the BluetoothAppService Handler
public static final String DEVICE_NAME = "device_name";
public static final String TOAST = "toast";
// Intent request codes
private static final int REQUEST_CONNECT_DEVICE_SECURE = 1;
private static final int REQUEST_CONNECT_DEVICE_INSECURE = 2;
private static final int REQUEST_ENABLE_BT = 3;
// Layout Views
private EditText mOutEditText;
private TextView TempView;
private TextView HumidView;
// Name of the connected device
private String mConnectedDeviceName = null;
// Array adapter for the conversation thread
private ArrayAdapter<String> mConversationArrayAdapter;
// String buffer for outgoing messages
private StringBuffer mOutStringBuffer;
// Local Bluetooth adapter
private BluetoothAdapter mBluetoothAdapter = null;
// Member object for the chat services
private BluetoothAppService mChatService = null;
//Interface for Mode
Button alert;
//Service for Anti-Theft
IATService mService;
ServiceConnection connection;
//values for service
int Temp = 0;
boolean Sensor1 = false;
boolean Sensor2 = false;
handlerThread AThandlerThread;
boolean alertmode = false;
//Service Connection for AntitheftService
ServiceConnection ATServiceConnection = new ServiceConnection(){
public void onServiceConnected(ComponentName name, IBinder service){
mService = IATService.Stub.asInterface(service);
AThandlerThread = new handlerThread();
AThandlerThread.start();
}
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
mService = null;
}
};
//Function for handling received data.
public void DataOutput(String readMessage){
int sel = 0;
String displayMessage = new String();
if(readMessage.startsWith("T") == true)
{
sel = 1;
}
else if(readMessage.startsWith("S1") == true)
{
sel = 3;
}
else if(readMessage.startsWith("S2") == true)
{
sel = 4;
}
if(sel == 1)
{
displayMessage = readMessage.substring(1,3);
Temp = Integer.parseInt(displayMessage);
displayMessage = displayMessage + "도";
TempView.setText(displayMessage);
}
else if(sel == 2)
{
displayMessage = readMessage.substring(1,3) + "%";
HumidView.setText(displayMessage);
}
else if(sel == 3)
{
displayMessage = readMessage.substring(2, 3);
Sensor1 = Boolean.parseBoolean(displayMessage);
}
else if(sel == 4)
{
displayMessage = readMessage.substring(2, 3);
Sensor1 = Boolean.parseBoolean(displayMessage);
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(D) Log.e(TAG, "+++ ON CREATE +++");
// Set up the window layout
setContentView(R.layout.roomstat);
// Get local Bluetooth adapter
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
// If the adapter is null, then Bluetooth is not supported
if (mBluetoothAdapter == null) {
Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).show();
finish();
return;
}
if(mService == null){
bindService(new Intent(BluetoothApp.this, AntitheftService.class), ATServiceConnection, Context.BIND_AUTO_CREATE);
Toast.makeText(getApplicationContext(), "Ready", Toast.LENGTH_SHORT).show();
}
//Button for setting mode.
alert = (Button)findViewById(R.id.button1);
alert.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if(alertmode == false){
alertmode = true;
alert.setText("설정");
}
else if(alertmode == true){
alertmode = false;
alert.setText("해제");
}
}
});
}
@Override
public void onStart() {
super.onStart();
if(D) Log.e(TAG, "++ ON START ++");
// If BT is not on, request that it be enabled.
// setupChat() will then be called during onActivityResult
if (!mBluetoothAdapter.isEnabled()) {
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
// Otherwise, setup the chat session
} else {
if (mChatService == null) setupChat();
}
}
@Override
public synchronized void onResume() {
super.onResume();
if(D) Log.e(TAG, "+ ON RESUME +");
// Performing this check in onResume() covers the case in which BT was
// not enabled during onStart(), so we were paused to enable it...
// onResume() will be called when ACTION_REQUEST_ENABLE activity returns.
if (mChatService != null) {
// Only if the state is STATE_NONE, do we know that we haven't started already
if (mChatService.getState() == BluetoothAppService.STATE_NONE) {
// Start the Bluetooth chat services
mChatService.start();
}
}
if(mService != null){
}
}
private void setupChat() {
Log.d(TAG, "setupChat()");
//Initialize temperature information text
TempView = (TextView)findViewById(R.id.temp_value);
// Initialize the BluetoothAppService to perform bluetooth connections
mChatService = new BluetoothAppService(this, mHandler);
// Initialize the buffer for outgoing messages
mOutStringBuffer = new StringBuffer("");
}
@Override
public synchronized void onPause() {
super.onPause();
if(D) Log.e(TAG, "- ON PAUSE -");
}
@Override
public void onStop() {
super.onStop();
if(D) Log.e(TAG, "-- ON STOP --");
}
@Override
public void onDestroy() {
super.onDestroy();
// Stop the Bluetooth chat services
if (mChatService != null) mChatService.stop();
if(D) Log.e(TAG, "--- ON DESTROY ---");
}
private void ensureDiscoverable() {
if(D) Log.d(TAG, "ensure discoverable");
if (mBluetoothAdapter.getScanMode() !=
BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);
}
}
/**
* Sends a message.
* @param message A string of text to send.
*/
private void sendMessage(String message) {
// Check that we're actually connected before trying anything
if (mChatService.getState() != BluetoothAppService.STATE_CONNECTED) {
Toast.makeText(this, R.string.not_connected, Toast.LENGTH_SHORT).show();
return;
}
// Check that there's actually something to send
if (message.length() > 0) {
// Get the message bytes and tell the BluetoothAppService to write
byte[] send = message.getBytes();
mChatService.write(send);
// Reset out string buffer to zero and clear the edit text field
mOutStringBuffer.setLength(0);
mOutEditText.setText(mOutStringBuffer);
}
}
/*// The action listener for the EditText widget, to listen for the return key
private TextView.OnEditorActionListener mWriteListener =
new TextView.OnEditorActionListener() {
public boolean onEditorAction(TextView view, int actionId, KeyEvent event) {
// If the action is a key-up event on the return key, send the message
if (actionId == EditorInfo.IME_NULL && event.getAction() == KeyEvent.ACTION_UP) {
String message = view.getText().toString();
sendMessage(message);
}
if(D) Log.i(TAG, "END onEditorAction");
return true;
}
};*/
// The Handler that gets information back from the BluetoothAppService
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_STATE_CHANGE:
if(D) Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
switch (msg.arg1) {
case BluetoothAppService.STATE_CONNECTED:
case BluetoothAppService.STATE_CONNECTING:
case BluetoothAppService.STATE_LISTEN:
case BluetoothAppService.STATE_NONE:
}
break;
case MESSAGE_WRITE:
byte[] writeBuf = (byte[]) msg.obj;
// construct a string from the buffer
String writeMessage = new String(writeBuf);
mConversationArrayAdapter.add("Me: " + writeMessage);
break;
case MESSAGE_READ:
byte[] readBuf = (byte[]) msg.obj;
// construct a string from the valid bytes in the buffer
String readMessage = new String(readBuf, 0, msg.arg1);
DataOutput(readMessage);
break;
case MESSAGE_DEVICE_NAME:
// save the connected device's name
mConnectedDeviceName = msg.getData().getString(DEVICE_NAME);
Toast.makeText(getApplicationContext(), "Connected to "
+ mConnectedDeviceName, Toast.LENGTH_SHORT).show();
break;
case MESSAGE_TOAST:
Toast.makeText(getApplicationContext(), msg.getData().getString(TOAST),
Toast.LENGTH_SHORT).show();
break;
}
}
};
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if(D) Log.d(TAG, "onActivityResult " + resultCode);
switch (requestCode) {
case REQUEST_CONNECT_DEVICE_SECURE:
// When DeviceListActivity returns with a device to connect
if (resultCode == Activity.RESULT_OK) {
connectDevice(data, true);
}
break;
case REQUEST_CONNECT_DEVICE_INSECURE:
// When DeviceListActivity returns with a device to connect
if (resultCode == Activity.RESULT_OK) {
connectDevice(data, false);
}
break;
case REQUEST_ENABLE_BT:
// When the request to enable Bluetooth returns
if (resultCode == Activity.RESULT_OK) {
// Bluetooth is now enabled, so set up a chat session
setupChat();
} else {
// User did not enable Bluetooth or an error occured
Log.d(TAG, "BT not enabled");
Toast.makeText(this, R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show();
finish();
}
}
}
private void connectDevice(Intent data, boolean secure) {
// Get the device MAC address
String address = data.getExtras()
.getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
// Get the BLuetoothDevice object
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
// Attempt to connect to the device
mChatService.connect(device, secure);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.option_menu, menu);
return true;
}
public class handlerThread extends Thread{
public void start(){
while(true){
try{
mService.getTemp(Temp);
mService.getSensor1(Sensor1);
mService.getSensor2(Sensor2);
mService.getState(alertmode);
}catch(RemoteException e){
e.printStackTrace();
}
}
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
Intent serverIntent = null;
switch (item.getItemId()) {
case R.id.scan:
// Launch the DeviceListActivity to see devices and do scan
serverIntent = new Intent(this, DeviceListActivity.class);
startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE_SECURE);
return true;
/*case R.id.insecure_connect_scan:
// Launch the DeviceListActivity to see devices and do scan
serverIntent = new Intent(this, DeviceListActivity.class);
startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE_INSECURE);
return true;*/
case R.id.discoverable:
// Ensure this device is discoverable by others
ensureDiscoverable();
return true;
}
return false;
}
}
액티비티는 블루투스 챗 예제에서 MESSAGE_READ를 이용해 메시지를 읽을 때,
DataOutput 함수를 이용해서 int값인 Temp와 boolean인 Sensor1, Sensor2에 값을 저장하도록 했습니다.
그리고 ServiceConnection에서 OnServiceConnected에 HandlerThread 쓰레드를 이용해서 AntitheftService에 계속 값을 보내도록했고요.
그리고 AntitheftService는 값을 받으면 ServiceBody 쓰레드에서 로그캣 메시지를 보내야 하는데, 지금 로그캣 메시지를 못 띄우고 있습니다. 어느 부분이 잘못 되었을까요?
첫 질문이고 공지사항은 모두 읽었습니다. ^^



