안드로이드 개발 질문/답변
(글 수 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 쓰레드에서 로그캣 메시지를 보내야 하는데, 지금 로그캣 메시지를 못 띄우고 있습니다. 어느 부분이 잘못 되었을까요?
첫 질문이고 공지사항은 모두 읽었습니다. ^^