/* * Copyright (C) 2015 The Android Open Source Project * * 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 com.example.android.bluetoothadvertisements; import android.bluetooth.le.AdvertiseCallback; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Switch; import android.widget.Toast; /** * Allows user to start & stop Bluetooth LE Advertising of their device. */ public class AdvertiserFragment extends Fragment implements View.OnClickListener { /** * Lets user toggle BLE Advertising. */ private Switch mSwitch; /** * Listens for notifications that the {@code AdvertiserService} has failed to start advertising. * This Receiver deals with Fragment UI elements and only needs to be active when the Fragment * is on-screen, so it's defined and registered in code instead of the Manifest. */ private BroadcastReceiver advertisingFailureReceiver; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); advertisingFailureReceiver = new BroadcastReceiver() { /** * Receives Advertising error codes from {@code AdvertiserService} and displays error messages * to the user. Sets the advertising toggle to 'false.' */ @Override public void onReceive(Context context, Intent intent) { int errorCode = intent.getIntExtra(AdvertiserService.ADVERTISING_FAILED_EXTRA_CODE, -1); mSwitch.setChecked(false); String errorMessage = getString(R.string.start_error_prefix); switch (errorCode) { case AdvertiseCallback.ADVERTISE_FAILED_ALREADY_STARTED: errorMessage += " " + getString(R.string.start_error_already_started); break; case AdvertiseCallback.ADVERTISE_FAILED_DATA_TOO_LARGE: errorMessage += " " + getString(R.string.start_error_too_large); break; case AdvertiseCallback.ADVERTISE_FAILED_FEATURE_UNSUPPORTED: errorMessage += " " + getString(R.string.start_error_unsupported); break; case AdvertiseCallback.ADVERTISE_FAILED_INTERNAL_ERROR: errorMessage += " " + getString(R.string.start_error_internal); break; case AdvertiseCallback.ADVERTISE_FAILED_TOO_MANY_ADVERTISERS: errorMessage += " " + getString(R.string.start_error_too_many); break; case AdvertiserService.ADVERTISING_TIMED_OUT: errorMessage = " " + getString(R.string.advertising_timedout); break; default: errorMessage += " " + getString(R.string.start_error_unknown); } Toast.makeText(getActivity(), errorMessage, Toast.LENGTH_LONG).show(); } }; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_advertiser, container, false); mSwitch = (Switch) view.findViewById(R.id.advertise_switch); mSwitch.setOnClickListener(this); return view; } /** * When app comes on screen, check if BLE Advertisements are running, set switch accordingly, * and register the Receiver to be notified if Advertising fails. */ @Override public void onResume() { super.onResume(); if (AdvertiserService.running) { mSwitch.setChecked(true); } else { mSwitch.setChecked(false); } IntentFilter failureFilter = new IntentFilter(AdvertiserService.ADVERTISING_FAILED); getActivity().registerReceiver(advertisingFailureReceiver, failureFilter); } /** * When app goes off screen, unregister the Advertising failure Receiver to stop memory leaks. * (and because the app doesn't care if Advertising fails while the UI isn't active) */ @Override public void onPause() { super.onPause(); getActivity().unregisterReceiver(advertisingFailureReceiver); } /** * Returns Intent addressed to the {@code AdvertiserService} class. */ private static Intent getServiceIntent(Context c) { return new Intent(c, AdvertiserService.class); } /** * Called when switch is toggled - starts or stops advertising. */ @Override public void onClick(View v) { // Is the toggle on? boolean on = ((Switch) v).isChecked(); if (on) { startAdvertising(); } else { stopAdvertising(); } } /** * Starts BLE Advertising by starting {@code AdvertiserService}. */ private void startAdvertising() { Context c = getActivity(); c.startService(getServiceIntent(c)); } /** * Stops BLE Advertising by stopping {@code AdvertiserService}. */ private void stopAdvertising() { Context c = getActivity(); c.stopService(getServiceIntent(c)); mSwitch.setChecked(false); } }