/* * Copyright 2015 Google Inc. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package io.github.webbluetoothcg.bletestperipheral; import android.app.Activity; import android.bluetooth.BluetoothGattCharacteristic; import android.bluetooth.BluetoothGattDescriptor; import android.bluetooth.BluetoothGattService; import android.os.Bundle; import android.os.ParcelUuid; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.view.inputmethod.EditorInfo; import android.widget.Button; import android.widget.EditText; import android.widget.SeekBar; import android.widget.SeekBar.OnSeekBarChangeListener; import android.widget.TextView; import android.widget.TextView.OnEditorActionListener; import android.widget.Toast; import java.util.UUID; public class BatteryServiceFragment extends ServiceFragment { private static final UUID BATTERY_SERVICE_UUID = UUID .fromString("0000180F-0000-1000-8000-00805f9b34fb"); private static final UUID BATTERY_LEVEL_UUID = UUID .fromString("00002A19-0000-1000-8000-00805f9b34fb"); private static final int INITIAL_BATTERY_LEVEL = 50; private static final int BATTERY_LEVEL_MAX = 100; private static final String BATTERY_LEVEL_DESCRIPTION = "The current charge level of a " + "battery. 100% represents fully charged while 0% represents fully discharged."; private ServiceFragmentDelegate mDelegate; // UI private EditText mBatteryLevelEditText; private final OnEditorActionListener mOnEditorActionListener = new OnEditorActionListener() { @Override public boolean onEditorAction(TextView textView, int actionId, KeyEvent event) { if (actionId == EditorInfo.IME_ACTION_DONE) { String newBatteryLevelString = textView.getText().toString(); // Need to check if the string is empty since isDigitsOnly returns // true for empty strings. if (!newBatteryLevelString.isEmpty() && android.text.TextUtils.isDigitsOnly(newBatteryLevelString)) { int newBatteryLevel = Integer.parseInt(newBatteryLevelString); if (newBatteryLevel <= BATTERY_LEVEL_MAX) { setBatteryLevel(newBatteryLevel, textView); } else { Toast.makeText(getActivity(), R.string.batteryLevelTooHigh, Toast.LENGTH_SHORT) .show(); } } else { Toast.makeText(getActivity(), R.string.batteryLevelIncorrect, Toast.LENGTH_SHORT) .show(); } } return false; } }; private SeekBar mBatteryLevelSeekBar; private final OnSeekBarChangeListener mOnSeekBarChangeListener = new OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if (fromUser) { setBatteryLevel(progress, seekBar); } } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { } }; private final OnClickListener mNotifyButtonListener = new OnClickListener() { @Override public void onClick(View v) { mDelegate.sendNotificationToDevices(mBatteryLevelCharacteristic); } }; // GATT private BluetoothGattService mBatteryService; private BluetoothGattCharacteristic mBatteryLevelCharacteristic; public BatteryServiceFragment() { mBatteryLevelCharacteristic = new BluetoothGattCharacteristic(BATTERY_LEVEL_UUID, BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_NOTIFY, BluetoothGattCharacteristic.PERMISSION_READ); mBatteryLevelCharacteristic.addDescriptor( Peripheral.getClientCharacteristicConfigurationDescriptor()); mBatteryLevelCharacteristic.addDescriptor( Peripheral.getCharacteristicUserDescriptionDescriptor(BATTERY_LEVEL_DESCRIPTION)); mBatteryService = new BluetoothGattService(BATTERY_SERVICE_UUID, BluetoothGattService.SERVICE_TYPE_PRIMARY); mBatteryService.addCharacteristic(mBatteryLevelCharacteristic); } // Lifecycle callbacks @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_battery, container, false); mBatteryLevelEditText = (EditText) view.findViewById(R.id.textView_batteryLevel); mBatteryLevelEditText.setOnEditorActionListener(mOnEditorActionListener); mBatteryLevelSeekBar = (SeekBar) view.findViewById(R.id.seekBar_batteryLevel); mBatteryLevelSeekBar.setOnSeekBarChangeListener(mOnSeekBarChangeListener); Button notifyButton = (Button) view.findViewById(R.id.button_batteryLevelNotify); notifyButton.setOnClickListener(mNotifyButtonListener); setBatteryLevel(INITIAL_BATTERY_LEVEL, null); return view; } @Override public void onAttach(Activity activity) { super.onAttach(activity); try { mDelegate = (ServiceFragmentDelegate) activity; } catch (ClassCastException e) { throw new ClassCastException(activity.toString() + " must implement ServiceFragmentDelegate"); } } @Override public void onDetach() { super.onDetach(); mDelegate = null; } public BluetoothGattService getBluetoothGattService() { return mBatteryService; } @Override public ParcelUuid getServiceUUID() { return new ParcelUuid(BATTERY_SERVICE_UUID); } private void setBatteryLevel(int newBatteryLevel, View source) { mBatteryLevelCharacteristic.setValue(newBatteryLevel, BluetoothGattCharacteristic.FORMAT_UINT8, /* offset */ 0); if (source != mBatteryLevelSeekBar) { mBatteryLevelSeekBar.setProgress(newBatteryLevel); } if (source != mBatteryLevelEditText) { mBatteryLevelEditText.setText(Integer.toString(newBatteryLevel)); } } @Override public void notificationsEnabled(BluetoothGattCharacteristic characteristic, boolean indicate) { if (characteristic.getUuid() != BATTERY_LEVEL_UUID) { return; } if (indicate) { return; } getActivity().runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(getActivity(), R.string.notificationsEnabled, Toast.LENGTH_SHORT) .show(); } }); } @Override public void notificationsDisabled(BluetoothGattCharacteristic characteristic) { if (characteristic.getUuid() != BATTERY_LEVEL_UUID) { return; } getActivity().runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(getActivity(), R.string.notificationsNotEnabled, Toast.LENGTH_SHORT) .show(); } }); } }