/* * SimpleDevicePicker * Connect SDK * * Copyright (c) 2014 LG Electronics. * Created by Jason Lai on 19 Jan 2014 * * 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.connectsdk.device; import java.util.List; import android.app.Activity; import android.app.Dialog; import android.content.res.Resources; import android.util.Log; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.Toast; import com.connectsdk.core.Util; import com.connectsdk.service.DeviceService; import com.connectsdk.service.DeviceService.PairingType; import com.connectsdk.service.command.ServiceCommandError; /** * A device picker that automatically connects to the device * and automatically displays pairing dialogs when needed. * * NOTE: Most methods MUST be called from the main ui thread. */ public class SimpleDevicePicker implements ConnectableDeviceListener { protected Activity activity; protected DevicePicker picker; protected Dialog pickerDialog; protected Dialog pairingDialog; // Device that we're in the process of connecting to protected ConnectableDevice pendingDevice; // Connected, active device protected ConnectableDevice activeDevice; protected int selectDeviceResId; protected int simplePairingTitleResId; protected int simplePairingPromptResId; protected int pinPairingPromptResId; protected int connectionFailedResId; SimpleDevicePickerListener listener; public SimpleDevicePicker(Activity activity) { this.activity = activity; this.picker = new DevicePicker(activity); loadStringIds(); } /** * Get the currently selected device * @return current connected device */ public ConnectableDevice getCurrentDevice() { return activeDevice; } protected void loadStringIds() { selectDeviceResId = getStringId("connect_sdk_picker_select_device"); simplePairingTitleResId = getStringId("connect_sdk_pairing_simple_title_tv"); simplePairingPromptResId = getStringId("connect_sdk_pairing_simple_prompt_tv"); pinPairingPromptResId = getStringId("connect_sdk_pairing_pin_prompt_tv"); connectionFailedResId = getStringId("connect_sdk_connection_failed"); } protected int getStringId(String key) { // First try to get resource from application int id = this.activity.getResources().getIdentifier(key, "string", activity.getPackageName()); // Then try to get from Connect SDK library if (id == 0) { id = this.activity.getResources().getIdentifier(key, "string", "com.connectsdk"); } if (id == 0) { Log.w("ConnectSDK", "missing string resource for \"" + key + "\""); throw new Resources.NotFoundException(key); } return id; } public void setListener(SimpleDevicePickerListener listener) { this.listener = listener; } protected void cleanupPending() { if (pendingDevice != null) { pendingDevice.removeListener(this); pendingDevice = null; } } protected void cleanupActive() { if (pendingDevice != null) { pendingDevice.removeListener(this); pendingDevice = null; } } public void showPicker() { cleanupPending(); // remove any currently pending device hidePicker(); pickerDialog = picker.getPickerDialog(activity.getString(selectDeviceResId), new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapter, View view, int pos, long id) { ConnectableDevice device = (ConnectableDevice) adapter.getItemAtPosition(pos); selectDevice(device); } }); pickerDialog.show(); } public void hidePicker() { if (pickerDialog != null) { pickerDialog.dismiss(); pickerDialog = null; } } /** * Connect to a device * * @param device */ public void selectDevice(ConnectableDevice device) { if (device != null) { pendingDevice = device; pendingDevice.addListener(this); if (listener != null) { // Give listener a chance to setup device before connecting listener.onPrepareDevice(device); } if (!device.isConnected()) { device.connect(); } else { onDeviceReady(device); } } else { cleanupPending(); } } protected Dialog createSimplePairingDialog() { PairingDialog dialog = new PairingDialog(activity, pendingDevice); return dialog.getSimplePairingDialog(simplePairingTitleResId, simplePairingPromptResId); } protected Dialog createPinPairingDialog() { PairingDialog dialog = new PairingDialog(activity, pendingDevice); return dialog.getPairingDialog(pinPairingPromptResId); } protected void showPairingDialog(PairingType pairingType) { switch (pairingType) { case FIRST_SCREEN: pairingDialog = createSimplePairingDialog(); break; case PIN_CODE: pairingDialog = createPinPairingDialog(); break; case NONE: default: break; } if (pairingDialog != null) { pairingDialog.show(); } } /** * Hide the current pairing dialog and cancels the pairing attempt. */ public void hidePairingDialog() { // cancel pairing if (pairingDialog != null) { pairingDialog.dismiss(); pairingDialog = null; } } @Override public void onDeviceReady(final ConnectableDevice device) { Util.runOnUI(new Runnable() { @Override public void run() { hidePairingDialog(); if (device == pendingDevice) { activeDevice = pendingDevice; if (listener != null) listener.onPickDevice(pendingDevice); } } }); } @Override public void onDeviceDisconnected(final ConnectableDevice device) { if (device == pendingDevice) { pickFailed(device); } if (device == activeDevice) { cleanupActive(); } } @Override public void onCapabilityUpdated(ConnectableDevice device, List<String> added, List<String> removed) { } @Override public void onConnectionFailed(ConnectableDevice device, ServiceCommandError error) { if (device == pendingDevice) { pickFailed(device); } if (device == activeDevice) { cleanupActive(); } } @Override public void onPairingRequired(ConnectableDevice device, DeviceService service, final PairingType pairingType) { Log.d("SimpleDevicePicker", "pairing required for device " + device.getFriendlyName()); Util.runOnUI(new Runnable() { @Override public void run() { showPairingDialog(pairingType); } }); } protected void pickFailed(final ConnectableDevice device) { Util.runOnUI(new Runnable() { @Override public void run() { if (pendingDevice == device) { // Device failed before successfully picking device if (listener != null) { listener.onPickDeviceFailed(false); } } cleanupPending(); Toast.makeText(activity, connectionFailedResId, Toast.LENGTH_SHORT).show(); } }); } }