1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.example.android.bluetoothadvertisements; 18 19 import android.bluetooth.le.AdvertiseCallback; 20 import android.content.BroadcastReceiver; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.content.IntentFilter; 24 import android.os.Bundle; 25 import android.support.v4.app.Fragment; 26 import android.view.LayoutInflater; 27 import android.view.View; 28 import android.view.ViewGroup; 29 import android.widget.Switch; 30 import android.widget.Toast; 31 32 /** 33 * Allows user to start & stop Bluetooth LE Advertising of their device. 34 */ 35 public class AdvertiserFragment extends Fragment implements View.OnClickListener { 36 37 /** 38 * Lets user toggle BLE Advertising. 39 */ 40 private Switch mSwitch; 41 42 /** 43 * Listens for notifications that the {@code AdvertiserService} has failed to start advertising. 44 * This Receiver deals with Fragment UI elements and only needs to be active when the Fragment 45 * is on-screen, so it's defined and registered in code instead of the Manifest. 46 */ 47 private BroadcastReceiver advertisingFailureReceiver; 48 49 @Override onCreate(Bundle savedInstanceState)50 public void onCreate(Bundle savedInstanceState) { 51 super.onCreate(savedInstanceState); 52 53 advertisingFailureReceiver = new BroadcastReceiver() { 54 55 /** 56 * Receives Advertising error codes from {@code AdvertiserService} and displays error messages 57 * to the user. Sets the advertising toggle to 'false.' 58 */ 59 @Override 60 public void onReceive(Context context, Intent intent) { 61 62 int errorCode = intent.getIntExtra(AdvertiserService.ADVERTISING_FAILED_EXTRA_CODE, -1); 63 64 mSwitch.setChecked(false); 65 66 String errorMessage = getString(R.string.start_error_prefix); 67 switch (errorCode) { 68 case AdvertiseCallback.ADVERTISE_FAILED_ALREADY_STARTED: 69 errorMessage += " " + getString(R.string.start_error_already_started); 70 break; 71 case AdvertiseCallback.ADVERTISE_FAILED_DATA_TOO_LARGE: 72 errorMessage += " " + getString(R.string.start_error_too_large); 73 break; 74 case AdvertiseCallback.ADVERTISE_FAILED_FEATURE_UNSUPPORTED: 75 errorMessage += " " + getString(R.string.start_error_unsupported); 76 break; 77 case AdvertiseCallback.ADVERTISE_FAILED_INTERNAL_ERROR: 78 errorMessage += " " + getString(R.string.start_error_internal); 79 break; 80 case AdvertiseCallback.ADVERTISE_FAILED_TOO_MANY_ADVERTISERS: 81 errorMessage += " " + getString(R.string.start_error_too_many); 82 break; 83 case AdvertiserService.ADVERTISING_TIMED_OUT: 84 errorMessage = " " + getString(R.string.advertising_timedout); 85 break; 86 default: 87 errorMessage += " " + getString(R.string.start_error_unknown); 88 } 89 90 Toast.makeText(getActivity(), errorMessage, Toast.LENGTH_LONG).show(); 91 } 92 }; 93 } 94 95 @Override onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)96 public View onCreateView(LayoutInflater inflater, ViewGroup container, 97 Bundle savedInstanceState) { 98 99 View view = inflater.inflate(R.layout.fragment_advertiser, container, false); 100 101 mSwitch = (Switch) view.findViewById(R.id.advertise_switch); 102 mSwitch.setOnClickListener(this); 103 104 return view; 105 } 106 107 /** 108 * When app comes on screen, check if BLE Advertisements are running, set switch accordingly, 109 * and register the Receiver to be notified if Advertising fails. 110 */ 111 @Override onResume()112 public void onResume() { 113 super.onResume(); 114 115 if (AdvertiserService.running) { 116 mSwitch.setChecked(true); 117 } else { 118 mSwitch.setChecked(false); 119 } 120 121 IntentFilter failureFilter = new IntentFilter(AdvertiserService.ADVERTISING_FAILED); 122 getActivity().registerReceiver(advertisingFailureReceiver, failureFilter); 123 124 } 125 126 /** 127 * When app goes off screen, unregister the Advertising failure Receiver to stop memory leaks. 128 * (and because the app doesn't care if Advertising fails while the UI isn't active) 129 */ 130 @Override onPause()131 public void onPause() { 132 super.onPause(); 133 getActivity().unregisterReceiver(advertisingFailureReceiver); 134 } 135 136 /** 137 * Returns Intent addressed to the {@code AdvertiserService} class. 138 */ getServiceIntent(Context c)139 private static Intent getServiceIntent(Context c) { 140 return new Intent(c, AdvertiserService.class); 141 } 142 143 /** 144 * Called when switch is toggled - starts or stops advertising. 145 */ 146 @Override onClick(View v)147 public void onClick(View v) { 148 // Is the toggle on? 149 boolean on = ((Switch) v).isChecked(); 150 151 if (on) { 152 startAdvertising(); 153 } else { 154 stopAdvertising(); 155 } 156 } 157 158 /** 159 * Starts BLE Advertising by starting {@code AdvertiserService}. 160 */ startAdvertising()161 private void startAdvertising() { 162 Context c = getActivity(); 163 c.startService(getServiceIntent(c)); 164 } 165 166 /** 167 * Stops BLE Advertising by stopping {@code AdvertiserService}. 168 */ stopAdvertising()169 private void stopAdvertising() { 170 Context c = getActivity(); 171 c.stopService(getServiceIntent(c)); 172 mSwitch.setChecked(false); 173 } 174 175 }