Commit fb4c1d5a authored by idic's avatar idic

很像可以work 應該

parent a85fa243
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
\ No newline at end of file
......@@ -41,7 +41,7 @@
<provider
android:name=".storage.PrivacyPolicyProvider"
android:authorities="@string/content_authority"
android:exported="false"/>
android:exported="true"/>
<activity
android:name=".DeviceOperatorActivity"/>
......
......@@ -9,35 +9,34 @@ import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Switch;
import android.widget.TextView;
import android.view.View;
import android.widget.*;
import org.prlab.idic.privacypolicy.adapter.MessageRecyclerViewAdapter;
import org.prlab.idic.privacypolicy.ble.BLECustomScript;
import org.prlab.idic.privacypolicy.pojo.Message;
import org.prlab.idic.privacypolicy.storage.PrivacyPolicyStorageImpl;
import org.prlab.idic.privacypolicy.tool.BaseUtils;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.UUID;
import static android.bluetooth.BluetoothGatt.GATT_SUCCESS;
public class DeviceOperatorActivity extends AppCompatActivity {
private static final String TAG = DeviceOperatorActivity.class.getSimpleName();
private String PRIVACY_POLICY_ACCEPT_UUID;
private UUID PRIVACY_POLICY_ACCEPT_UUID;
private PrivacyPolicyStorageImpl mPolicyStorage;
private String mTargetDeviceAddress;
private List<Message> messages = new LinkedList<>();
private List<Message> mMessages = new LinkedList<>();
private TextView mMessageBarTextView;
private EditText mTemperatureEditText;
private Button mTemperatureButton;
private Switch mAirPurifierSwitch;
private RecyclerView mMessageRecyclerView;
private RecyclerView.Adapter mMessageRecyclerViewAdapter;
private BluetoothManager mBluetoothManager;
......@@ -53,7 +52,7 @@ public class DeviceOperatorActivity extends AppCompatActivity {
mTargetDeviceAddress = getIntent().getStringExtra(getString(R.string.intent_target_address_key));
mPolicyStorage = new PrivacyPolicyStorageImpl(getContentResolver(), mTargetDeviceAddress);
PRIVACY_POLICY_ACCEPT_UUID = getString(R.string.uuid_accept_privacy_policy);
PRIVACY_POLICY_ACCEPT_UUID = UUID.fromString(getString(R.string.uuid_accept_privacy_policy));
initView();
initBluetooth();
......@@ -61,9 +60,15 @@ public class DeviceOperatorActivity extends AppCompatActivity {
private void initView() {
mMessageBarTextView = (TextView) findViewById(R.id.text_operation_message_bar);
mTemperatureEditText = (EditText) findViewById(R.id.);
mMessageRecyclerView = (RecyclerView) findViewById(R.id.recycler_view_operation_info);
mMessageRecyclerViewAdapter = new MessageRecyclerViewAdapter(getResources(), messages);
mTemperatureEditText = (EditText) findViewById(R.id.edit_operation_current_temperature);
mTemperatureButton = (Button) findViewById(R.id.button_operation_send_temperature);
mTemperatureButton.setOnClickListener(mTemperatureClickedListener);
mAirPurifierSwitch = (Switch) findViewById(R.id.switch_operation_air_purifier);
mAirPurifierSwitch.setOnCheckedChangeListener(mOnAirPurifierSwitchCheckedListener);
RecyclerView mMessageRecyclerView = (RecyclerView) findViewById(R.id.recycler_view_operation_info);
mMessageRecyclerViewAdapter = new MessageRecyclerViewAdapter(getResources(), mMessages);
mMessageRecyclerView.setAdapter(mMessageRecyclerViewAdapter);
}
......@@ -71,24 +76,125 @@ public class DeviceOperatorActivity extends AppCompatActivity {
mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
if (mBluetoothManager != null) {
mBluetoothAdapter = mBluetoothManager.getAdapter();
if (mBluetoothAdapter != null)
connect();
}
}
private final UUID ROOT_UUID = UUID.fromString("01122334-4556-6778-899a-abbccddeeff0");
private final UUID TEMPERATURE_UUID = UUID.fromString("01122334-4556-6778-899a-abbccddeeff1");
private final UUID AIR_UUID = UUID.fromString("01122334-4556-6778-899a-abbccddeeff2");
private View.OnClickListener mTemperatureClickedListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mBluetoothGatt != null) {
BluetoothGattService service = mBluetoothGatt.getService(ROOT_UUID);
BluetoothGattCharacteristic temperature = service == null ? null : service.getCharacteristic(TEMPERATURE_UUID);
if (temperature != null) {
temperature.setValue(BaseUtils.int2Bytes(Integer.parseInt(String.valueOf(mTemperatureEditText.getText()))));
mBluetoothGatt.writeCharacteristic(temperature);
}
}
}
};
private CompoundButton.OnCheckedChangeListener mOnAirPurifierSwitchCheckedListener = new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (mBluetoothGatt != null) {
BluetoothGattService service = mBluetoothGatt.getService(ROOT_UUID);
BluetoothGattCharacteristic airPurifier = service == null ? null : service.getCharacteristic(AIR_UUID);
if (airPurifier != null) {
airPurifier.setValue(isChecked ? BaseUtils.int2Bytes(1) : BaseUtils.int2Bytes(0));
mBluetoothGatt.writeCharacteristic(airPurifier);
}
}
}
};
private BLECustomScript mBLECustomScript = new BLECustomScript() {
int expectedSuccessValue = 0;
int successValue = 0;
private void requestServices() {
if (successValue == expectedSuccessValue) {
setMessageBar("Try to request services.");
addMessage("Request Services", "Try to get temperature & air purifier state.");
requestTemperature();
}
}
private void requestValue(UUID characteristicUUID) {
synchronized (mBluetoothGatt) {
BluetoothGattService service = mBluetoothGatt.getService(ROOT_UUID);
BluetoothGattCharacteristic characteristic = service.getCharacteristic(characteristicUUID);
if (characteristic != null) {
mBluetoothGatt.readCharacteristic(characteristic);
}
}
}
private void requestTemperature() {
requestValue(TEMPERATURE_UUID);
}
private void requestAirPurifier() {
requestValue(AIR_UUID);
}
private void resolveTemperature(final int value) {
runOnUiThread(new Runnable() {
@Override
public void run() {
if (value == -99) {
addMessage("Temperature Service", "Get failure -> " + value);
mTemperatureEditText.setEnabled(false);
mTemperatureButton.setEnabled(false);
} else {
addMessage("Temperature Service", "Get success -> " + value);
mTemperatureEditText.setEnabled(true);
mTemperatureButton.setEnabled(true);
}
mTemperatureEditText.setText(String.valueOf(value));
}
});
}
private void resolveAirPurifier(final int value) {
runOnUiThread(new Runnable() {
@Override
public void run() {
if (value != -1) {
addMessage("Air Purifier Service", "Get success -> " + (value == 1 ? "running" : "sleeping"));
} else {
addMessage("Air Purifier Service", "Get failure -> " + String.valueOf(value));
}
mAirPurifierSwitch.setChecked(value == 1);
}
});
}
@Override
public void onDiscoverServiceCompleted(BluetoothGatt gatt) {
expectedSuccessValue = 0;
successValue = 0;
setMessageBar("Enable privacy policy setting.");
for (BluetoothGattService service : gatt.getServices()) {
List<String> layerUUIDs = new LinkedList<>();
layerUUIDs.add(String.valueOf(service.getUuid()));
//Write service layer selection
int selection = mPolicyStorage.get(layerUUIDs);
if (selection != -1) {
for (BluetoothGattCharacteristic characteristic : service.getCharacteristics()) {
if (PRIVACY_POLICY_ACCEPT_UUID.equals(characteristic.getUuid().toString())) {
characteristic.setValue(BaseUtils.intArrray2ByteArray(selection));
gatt.writeCharacteristic(characteristic);
}
BluetoothGattCharacteristic characteristic = service.getCharacteristic(PRIVACY_POLICY_ACCEPT_UUID);
if (characteristic != null) {
characteristic.setValue(BaseUtils.int2Bytes(selection));
Log.i(TAG, Arrays.toString(BaseUtils.int2Bytes(selection)));
gatt.writeCharacteristic(characteristic);
expectedSuccessValue++;
addMessage("Policy Setting", "Set " + BaseUtils.stringList2ArrayString(layerUUIDs) + " to " + selection + ".");
}
}
for (BluetoothGattCharacteristic characteristic : service.getCharacteristics()) {
......@@ -96,11 +202,13 @@ public class DeviceOperatorActivity extends AppCompatActivity {
//Write characteristic layer selection
selection = mPolicyStorage.get(layerUUIDs);
if (selection != -1) {
for (BluetoothGattDescriptor descriptor : characteristic.getDescriptors()) {
if (PRIVACY_POLICY_ACCEPT_UUID.equals(descriptor.getUuid().toString())) {
descriptor.setValue(BaseUtils.intArrray2ByteArray(selection));
gatt.writeDescriptor(descriptor);
}
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(PRIVACY_POLICY_ACCEPT_UUID);
if (descriptor != null) {
descriptor.setValue(BaseUtils.int2Bytes(selection));
Log.i(TAG, Arrays.toString(BaseUtils.int2Bytes(selection)));
gatt.writeDescriptor(descriptor);
expectedSuccessValue++;
addMessage("Policy Setting", "Set " + BaseUtils.stringList2ArrayString(layerUUIDs) + " to " + selection + ".");
}
}
layerUUIDs.remove(layerUUIDs.size() - 1);
......@@ -109,12 +217,53 @@ public class DeviceOperatorActivity extends AppCompatActivity {
}
@Override
public void onWriteCompleted(BluetoothGatt gatt, int status, byte[] values) {
public void onWriteCharacteristicCompleted(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status, byte[] values) {
if (PRIVACY_POLICY_ACCEPT_UUID.equals(characteristic.getUuid())) {
successValue++;
List<String> layerUUIDs = new LinkedList<>();
layerUUIDs.add(characteristic.getService().getUuid().toString());
addMessage("Policy Setting",
"Set " + BaseUtils.stringList2ArrayString(layerUUIDs) +
(status == GATT_SUCCESS ? " success" : " failure") + " .");
requestServices();
} else if (TEMPERATURE_UUID.equals(characteristic.getUuid())) {
addMessage("Temperature Setting",
"Set " + BaseUtils.bytesToInt(values) + " to air conditioning.");
requestTemperature();
} else if (AIR_UUID.equals(characteristic.getUuid())) {
addMessage("Air Purifier Setting", "Turn " +
(BaseUtils.bytesToInt(values) == 1 ? " on" : " off") + "air purifier" + ".");
requestAirPurifier();
}
}
@Override
public void onReadCharacteristicCompleted(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status, byte[] values) {
if (TEMPERATURE_UUID.equals(characteristic.getUuid())) {
resolveTemperature(BaseUtils.bytesToInt(values));
if (mTemperatureEditText.getText().toString().equals("")) {
requestAirPurifier();
}
} else if (AIR_UUID.equals(characteristic.getUuid())) {
resolveAirPurifier(BaseUtils.bytesToInt(values));
}
}
@Override
public void onWriteDescriptorCompleted(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status, byte[] values) {
if (PRIVACY_POLICY_ACCEPT_UUID.equals(descriptor.getUuid())) {
successValue++;
List<String> layerUUIDs = new LinkedList<>();
layerUUIDs.add(descriptor.getCharacteristic().getService().getUuid().toString());
layerUUIDs.add(descriptor.getCharacteristic().getUuid().toString());
addMessage("Policy setting", "Set " + BaseUtils.stringList2ArrayString(layerUUIDs) +
(status == GATT_SUCCESS ? " success" : " failure") + " .");
requestServices();
}
}
@Override
public void onReadCompleted(BluetoothGatt gatt, int status, byte[] values) {
public void onReadDescriptorCompleted(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status, byte[] values) {
}
......@@ -143,9 +292,11 @@ public class DeviceOperatorActivity extends AppCompatActivity {
if (status == GATT_SUCCESS) {
if (newState == BluetoothGatt.STATE_CONNECTED) {
gatt.discoverServices();
addMessage("Connection State Change ", "Device " + mac + " is connected.");
} else if (newState == BluetoothGatt.STATE_DISCONNECTED) {
mBluetoothGatt.close();
mBluetoothGatt = null;
addMessage("Connection State Change ", "Device " + mac + " is disconnected.");
}
}
//重連機制,但好像只會一直bind住。
......@@ -164,19 +315,29 @@ public class DeviceOperatorActivity extends AppCompatActivity {
@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
if ((status & (BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION | BluetoothGatt.GATT_INSUFFICIENT_ENCRYPTION)) != 0) {
boolean isSuccessful = gatt.getDevice().createBond();
Log.i(TAG, "Create Bond is " + isSuccessful);
} else {
mBLECustomScript.onReadCompleted(mBluetoothGatt, status, characteristic.getValue());
}
// if ((status & (BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION | BluetoothGatt.GATT_INSUFFICIENT_ENCRYPTION)) != 0) {
// boolean isSuccessful = gatt.getDevice().createBond();
// Log.i(TAG, "Create Bond is " + isSuccessful);
// }
mBLECustomScript.onReadCharacteristicCompleted(mBluetoothGatt, characteristic, status, characteristic.getValue());
}
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
mBLECustomScript.onWriteCompleted(mBluetoothGatt, status, characteristic.getValue());
mBLECustomScript.onWriteCharacteristicCompleted(mBluetoothGatt, characteristic, status, characteristic.getValue());
}
@Override
public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
mBLECustomScript.onReadDescriptorCompleted(mBluetoothGatt, descriptor, status, descriptor.getValue());
}
@Override
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
mBLECustomScript.onWriteDescriptorCompleted(mBluetoothGatt, descriptor, status, descriptor.getValue());
}
};
private void registerPairRequestReceiver() {
......@@ -268,4 +429,31 @@ public class DeviceOperatorActivity extends AppCompatActivity {
}
}
}
private void setMessageBar(final String message) {
runOnUiThread(new Runnable() {
@Override
public void run() {
mMessageBarTextView.setText(message);
}
});
}
private void addMessage(String event, String message) {
addMessage(event, message, false);
}
private void addMessage(final String event, final String message, final boolean isMarked) {
runOnUiThread(new Runnable() {
@Override
public void run() {
mMessages.add(new Message()
.setEvent(event)
.setContent(message)
.setMarked(isMarked));
mMessageRecyclerViewAdapter.notifyItemInserted(mMessages.size() - 1);
}
});
}
}
......@@ -227,10 +227,10 @@ public class MainActivity extends AppCompatActivity {
manufacturerData = manufacturerSpecificDataSparseArray.get(key);
}
String uuid = null;
BluetoothDevice device = result.getDevice();
if (null != manufacturerData && BeaconType.NORMAL_BEACON == BeaconUtils.getBeaconType(manufacturerData)) {
uuid = BeaconUtils.calculateUuidString(Arrays.copyOfRange(manufacturerData, 2, 18));
}
BluetoothDevice device = result.getDevice();
return new BluetoothDeviceInformation()
.setName(device == null ? null : device.getName())
.setAddress(device == null ? null : device.getAddress())
......
......@@ -37,7 +37,7 @@ public class ScanResultRecyclerViewAdapter extends RecyclerView.Adapter<ScanResu
List<BluetoothDeviceInformation> devices) {
this.BONDED_STRING = resources.getString(R.string.bluetooth_bonded);
this.NOT_BONDED_STRING = resources.getString(R.string.bluetooth_not_bonded);
this.RSSI_UNIT = " " + resources.getString(R.string.rssi_unit);
this.RSSI_UNIT = " " + resources.getString(R.string.unit_rssi);
this.mOnPolicyImageClickListener = mOnPolicyImageClickListener;
this.mOnConnectButtonClickListener = mOnConnectButtonClickListener;
this.devices = devices;
......
......@@ -2,6 +2,8 @@ package org.prlab.idic.privacypolicy.ble;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
/**
* Created by IDIC on 2017/2/21.
......@@ -9,8 +11,10 @@ import android.bluetooth.BluetoothGatt;
public interface BLECustomScript {
void onDiscoverServiceCompleted(BluetoothGatt gatt);
void onWriteCompleted(BluetoothGatt gatt, int status, byte[] values);
void onReadCompleted(BluetoothGatt gatt, int status, byte[] values);
void onWriteCharacteristicCompleted(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status, byte[] values);
void onReadCharacteristicCompleted(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status, byte[] values);
void onWriteDescriptorCompleted(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status, byte[] values);
void onReadDescriptorCompleted(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status, byte[] values);
void onPairRequestReceived(BluetoothDevice device, int pin);
void onPaired(BluetoothDevice device);
void onUnpaired(BluetoothDevice device);
......
......@@ -125,8 +125,12 @@ public class BaseUtils {
return UUIDs;
}
public static byte[] intArrray2ByteArray(int i) {
return ByteBuffer.allocate(4).putInt(1695609641).array();
public static byte[] int2Bytes(int i) {
return ByteBuffer.allocate(4).putInt(i).array();
}
public static int bytesToInt(byte[] bytes) {
return ByteBuffer.wrap(bytes).getInt();
}
}
......@@ -20,6 +20,8 @@
android:layout_height="@dimen/small_item_size"/>
<RelativeLayout
android:paddingStart="@dimen/activity_horizontal_margin"
android:paddingEnd="@dimen/activity_horizontal_margin"
android:id="@+id/layout_operation_temperature"
android:layout_below="@id/text_operation_message_bar"
android:gravity="center_vertical"
......@@ -68,6 +70,8 @@
</RelativeLayout>
<RelativeLayout
android:paddingStart="@dimen/activity_horizontal_margin"
android:paddingEnd="@dimen/activity_horizontal_margin"
android:id="@+id/layout_operation_air_purifier"
android:layout_below="@id/layout_operation_temperature"
android:gravity="center_vertical"
......@@ -99,8 +103,8 @@
android:background="@color/colorImplicit" />
<android.support.v7.widget.RecyclerView
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingStart="@dimen/activity_horizontal_margin"
android:paddingEnd="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
android:layout_below="@id/layout_operation_air_purifier"
......
......@@ -108,7 +108,7 @@
android:layout_height="1dp"/>
<TextView
android:text="@string/statement_title"
android:text="@string/policy_statement_title"
android:gravity="center_vertical"
android:textSize="@dimen/font_bigger_size"
android:layout_width="match_parent"
......
<resources>
<string name="app_name">BLEPrivacyPolicyNegotiator</string>
<string name="uuid_accept_privacy_policy">22222222&#8211;2222&#8211;2222&#8211;2222&#8211;222222222222</string>
<string name="uuid_accept_privacy_policy">22222222-2222-2222-2222-222222222222</string>
<string name="action_enable_scan">Start Scanning</string>
<string name="action_disable_scan">Stop Scanning</string>
......@@ -18,6 +18,9 @@
<string name="message_scan_stop">Stop scanning.</string>
<string name="message_enable_first">Enable Bluetooth first. Press scanning button again.</string>
<string name="message_current_temperature">Current temperature</string>
<string name="message_air_purifier_status">Air Purifier state</string>
<string name="message_choose_policy">The policies you need to choose as follows.</string>
<string name="message_collect_data">We may collect data as follows.</string>
<string name="message_more_detail">More Detail</string>
......@@ -31,7 +34,6 @@
<string name="bluetooth_bonded">BONDED</string>
<string name="bluetooth_not_bonded">NOT BONDED</string>
<string name="rssi_unit">dBm</string>
<string name="get_policy_url">http://140.118.110.172:4567/policy.json</string>
<string name="get_policy_id_parameter_key">id</string>
......@@ -79,6 +81,8 @@
<string name="policy_statement_consequence_title">Consequence</string>
<string name="policy_statement_access_title">Access</string>
<string name="policy_statement_remedies">Remedies</string>
<string name="policy_statement_title">Statement</string>
<string name="policy_statement_retention">Retention</string>
<string name="intent_report_id_key">REPORT_TARGET_ID</string>
<string name="intent_report_mac_key">REPORT_TARGET_MAC</string>
......@@ -86,10 +90,7 @@
<string name="intent_target_address_key">DEVICE_TARGET_ADDRESS</string>
<string name="intent_device_info_key">DEVICE_INFO_KEY</string>
<string name="intent_policy_info_key">POLICY_INFO_KEY</string>
<string name="statement_title">Statements</string>
<string name="policy_statement_retention">Retention</string>
<string name="unit_temperature">°C</string>
<string name="message_current_temperature">Current temperature</string>
<string name="message_air_purifier_status">Air Purifier status</string>
<string name="unit_rssi">dBm</string>
</resources>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment