package com.alexkang.bluechat;
import android.app.Activity;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.provider.MediaStore;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
public class ClientActivity extends Activity {
public static final int PICK_IMAGE = 1;
private ArrayList<Integer> acceptableDevices = new ArrayList<>();
private EditText mMessage;
private ProgressDialog mProgressDialog;
private String mUsername;
private BluetoothAdapter mBluetoothAdapter;
private BluetoothSocket mSocket;
private ChatManager mChatManager;
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
int deviceClass = device.getBluetoothClass().getDeviceClass();
if (acceptableDevices.contains(deviceClass)) {
new ConnectThread(device).start();
}
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chatroom);
if (getActionBar() != null) {
getActionBar().setDisplayHomeAsUpEnabled(true);
}
acceptableDevices.add(BluetoothClass.Device.COMPUTER_HANDHELD_PC_PDA);
acceptableDevices.add(BluetoothClass.Device.COMPUTER_PALM_SIZE_PC_PDA);
acceptableDevices.add(BluetoothClass.Device.PHONE_SMART);
Button mAttachButton = (Button) findViewById(R.id.attach);
Button mSendButton = (Button) findViewById(R.id.send);
mMessage = (EditText) findViewById(R.id.message);
mChatManager = new ChatManager(this, false);
mProgressDialog = new ProgressDialog(this);
mAttachButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
uploadAttachment();
}
});
mSendButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
sendMessage();
}
});
mProgressDialog.setMessage(getString(R.string.looking_for_chatroom));
mProgressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialogInterface) {
finish();
}
});
mProgressDialog.show();
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
mUsername = sharedPref.getString("username", mBluetoothAdapter.getName());
startDeviceSearch();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
Intent i = new Intent(this, MainActivity.class);
startActivity(i);
finish();
}
return super.onOptionsItemSelected(item);
}
private void startDeviceSearch() {
mBluetoothAdapter.enable();
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter);
new WaitForBluetoothThread().start();
}
private void sendMessage() {
byte[] byteArray;
if (mMessage.getText().toString().length() == 0) {
return;
}
try {
byte[] messageBytes = mMessage.getText().toString().getBytes();
byteArray = mChatManager.buildPacket(
ChatManager.MESSAGE_SEND,
mUsername,
messageBytes
);
} catch (Exception e) {
return;
}
mChatManager.writeMessage(byteArray);
mMessage.setText("");
}
private void uploadAttachment() {
Intent i = new Intent();
i.setType("image/*");
i.setAction(Intent.ACTION_PICK);
startActivityForResult(Intent.createChooser(i, getString(R.string.select_picture)), PICK_IMAGE);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == PICK_IMAGE) {
if (resultCode == RESULT_OK) {
Uri image = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(image, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
new SendImageThread(picturePath).start();
cursor.close();
}
}
}
@Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(mReceiver);
if (mSocket != null) {
try {
mSocket.close();
} catch (IOException e) {
System.err.println("Failed to close socket");
System.err.println(e.toString());
}
}
if (mProgressDialog.isShowing()) {
mProgressDialog.dismiss();
}
mBluetoothAdapter.cancelDiscovery();
}
private void manageSocket(BluetoothSocket socket) {
mSocket = socket;
mChatManager.startConnection(socket, mProgressDialog);
}
private class WaitForBluetoothThread extends Thread {
public void run() {
while (true) {
if (mBluetoothAdapter.isEnabled()) {
mBluetoothAdapter.startDiscovery();
break;
}
}
}
}
private class SendImageThread extends Thread {
private Bitmap bitmap;
public SendImageThread(String picturePath) {
this.bitmap = BitmapFactory.decodeFile(picturePath);
}
public void run() {
if (bitmap == null) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getBaseContext(), getString(R.string.image_is_incompatible), Toast.LENGTH_SHORT).show();
}
});
return;
}
if (bitmap.getWidth() > 1024 || bitmap.getHeight() > 1024) {
float scalingFactor;
if (bitmap.getWidth() >= bitmap.getHeight()) {
scalingFactor = 1024f / bitmap.getWidth();
} else {
Matrix fixRotation = new Matrix();
fixRotation.postRotate(90);
scalingFactor = 1024f / bitmap.getHeight();
}
bitmap = Bitmap.createScaledBitmap(
bitmap,
(int) (bitmap.getWidth() * scalingFactor),
(int) (bitmap.getHeight() * scalingFactor),
false
);
}
try {
ByteArrayOutputStream output = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 15, output);
byte[] imageBytes = output.toByteArray();
byte[] packet = mChatManager.buildPacket(
ChatManager.MESSAGE_SEND_IMAGE,
mUsername,
imageBytes
);
mChatManager.writeMessage(packet);
} catch (Exception e) {
System.err.println("Failed to send image");
System.err.println(e.toString());
}
}
}
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
public ConnectThread(BluetoothDevice device) {
BluetoothSocket tmp = null;
try {
tmp = device.createRfcommSocketToServiceRecord(
java.util.UUID.fromString(MainActivity.UUID));
} catch (Exception e) {
System.err.println("Failed to connect");
System.err.println(e.toString());
}
mmSocket = tmp;
}
public void run() {
try {
mmSocket.connect();
} catch (IOException e) {
try {
mmSocket.close();
} catch (IOException e2) {
return;
}
}
runOnUiThread(new Runnable() {
@Override
public void run() {
manageSocket(mmSocket);
}
});
}
}
}