package org.deviceconnect.android.deviceplugin.hitoe.activity; import android.app.ActionBar; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.res.Resources; import android.os.Bundle; import android.os.Handler; import android.provider.Settings; import android.support.v4.app.FragmentActivity; import android.view.LayoutInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.ListView; import android.widget.TextView; import org.deviceconnect.android.activity.PermissionUtility; import org.deviceconnect.android.deviceplugin.hitoe.BuildConfig; import org.deviceconnect.android.deviceplugin.hitoe.HitoeApplication; import org.deviceconnect.android.deviceplugin.hitoe.R; import org.deviceconnect.android.deviceplugin.hitoe.data.HitoeConstants; import org.deviceconnect.android.deviceplugin.hitoe.data.HitoeDevice; import org.deviceconnect.android.deviceplugin.hitoe.data.HitoeManager; import org.deviceconnect.android.deviceplugin.hitoe.fragment.dialog.ErrorDialogFragment; import org.deviceconnect.android.deviceplugin.hitoe.fragment.dialog.PinCodeDialogFragment; import org.deviceconnect.android.deviceplugin.hitoe.fragment.dialog.ProgressDialogFragment; import org.deviceconnect.android.deviceplugin.hitoe.util.BleUtils; import java.util.ArrayList; import java.util.List; /** * This activity is hitoe list screen. * @author NTT DOCOMO, INC. */ public abstract class HitoeListActivity extends FragmentActivity { /** * デフォルトのタイトル文字列. */ public static final String DEFAULT_TITLE = "サービス一覧"; /** * Adapter. */ protected DeviceAdapter mDeviceAdapter; /** * Error Dialog. */ private ErrorDialogFragment mErrorDialogFragment; /** * Progress Dialog. */ private ProgressDialogFragment mProgressDialogFragment; /** * Handler. */ protected final Handler mHandler = new Handler(); /** * Bluetooth device list view. */ protected ListView mListView; /** * footer view. */ protected View mFooterView; /** * Enabled connected button. */ protected boolean mEnableConnectedBtn; /** * Progress dialog flag. */ protected boolean mCheckDialog; /** * Now connecting device. */ protected HitoeDevice mConnectingDevice; @Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_hitoe_device_list); HitoeApplication app = (HitoeApplication) getApplication(); app.initialize(); setUI(); mDeviceAdapter = new DeviceAdapter(this, createDeviceContainers()); mListView = (ListView) findViewById(R.id.device_list_view); mListView.setAdapter(mDeviceAdapter); mListView.setItemsCanFocus(true); LayoutInflater inflater = getLayoutInflater(); mFooterView = inflater.inflate(R.layout.item_hitoe_searching, null); if (getActionBar() != null) { getActionBar().setDisplayHomeAsUpEnabled(true); getActionBar().setDisplayOptions(0, ActionBar.DISPLAY_SHOW_HOME); getActionBar().setTitle(DEFAULT_TITLE); } } /** * Initialize sub classs's ui. */ protected abstract void setUI(); @Override protected void onResume() { super.onResume(); addFooterView(); } @Override protected void onPause() { super.onPause(); mHandler.removeCallbacksAndMessages(null); } /** * Gets a instance of HitoeManager. * * @return HitoeManager */ protected HitoeManager getManager() { HitoeApplication application = (HitoeApplication) getApplication(); return application.getHitoeManager(); } @Override public boolean onOptionsItemSelected(final MenuItem item) { if (item.getItemId() == android.R.id.home) { finish(); return true; } return super.onOptionsItemSelected(item); } /** * Added the view at ListView. */ protected void addFooterView() { runOnUiThread(new Runnable() { @Override public void run() { LayoutInflater inflater = getLayoutInflater(); if (mFooterView != null) { mListView.removeFooterView(mFooterView); } if (!BleUtils.isBLEPermission(HitoeListActivity.this)) { Button btn = (Button) findViewById(R.id.btn_add_open); btn.setVisibility(View.GONE); mFooterView = inflater.inflate(R.layout.item_hitoe_error, null); TextView textView = (TextView) mFooterView.findViewById(R.id.error_message); textView.setText(getString(R.string.hitoe_setting_dialog_error_permission)); Button permission = (Button) mFooterView.findViewById(R.id.button_permission); permission.setVisibility(View.VISIBLE); permission.setText(R.string.bluetooth_settings_ble_permission_off); permission.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { PermissionUtility.requestPermissions(HitoeListActivity.this, mHandler, BleUtils.BLE_PERMISSIONS, new PermissionUtility.PermissionRequestCallback() { @Override public void onSuccess() { } @Override public void onFail(final String deniedPermission) { } }); } }); mListView.addFooterView(mFooterView); } else if (!BleUtils.isEnabled(HitoeListActivity.this)) { Button btn = (Button) findViewById(R.id.btn_add_open); btn.setVisibility(View.GONE); mFooterView = inflater.inflate(R.layout.item_hitoe_error, null); TextView textView = (TextView) mFooterView.findViewById(R.id.error_message); textView.setText(getString(R.string.hitoe_setting_dialog_disable_bluetooth)); Button bluetooth = (Button) mFooterView.findViewById(R.id.button_permission); bluetooth.setVisibility(View.VISIBLE); bluetooth.setText(R.string.bluetooth_settings_button); bluetooth.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(); intent.setAction(Settings.ACTION_BLUETOOTH_SETTINGS); startActivity(intent); } }); mDeviceAdapter.clear(); mDeviceAdapter.notifyDataSetChanged(); mListView.addFooterView(mFooterView); } else if (BleUtils.isEnabled(HitoeListActivity.this) && !mEnableConnectedBtn) { mFooterView = inflater.inflate(R.layout.item_hitoe_searching, null); mListView.addFooterView(mFooterView); } else if (BleUtils.isEnabled(HitoeListActivity.this) && mEnableConnectedBtn && createDeviceContainers().size() == 0) { Button btn = (Button) findViewById(R.id.btn_add_open); btn.setVisibility(View.VISIBLE); mFooterView = inflater.inflate(R.layout.item_hitoe_error, null); TextView textView = (TextView) mFooterView.findViewById(R.id.error_message); textView.setText(getString(R.string.alert_add_device)); Button bluetooth = (Button) mFooterView.findViewById(R.id.button_permission); bluetooth.setVisibility(View.GONE); mListView.addFooterView(mFooterView); } else { Button btn = (Button) findViewById(R.id.btn_add_open); btn.setVisibility(View.VISIBLE); mDeviceAdapter.clear(); mDeviceAdapter.addAll(createDeviceContainers()); mDeviceAdapter.notifyDataSetChanged(); } } }); } /** * Create a list of device. * * @return list of device */ protected List<HitoeDevice> createDeviceContainers() { getManager().readHitoeDeviceForDB(); List<HitoeDevice> resDevice = new ArrayList<HitoeDevice>(); for (HitoeDevice device:getManager().getRegisterDevices()) { if (device.getPinCode() != null && mEnableConnectedBtn) { resDevice.add(device); } else if (device.getPinCode() == null && !mEnableConnectedBtn) { resDevice.add(device); } } return resDevice; } /** * Connect to the BLE device that have heart rate service. * * @param device BLE device that have heart rate service. */ protected void connectDevice(final HitoeDevice device) { if (BleUtils.isEnabled(this)) { mConnectingDevice = device; showProgressDialog(device.getName()); getManager().connectHitoeDevice(device); } } /** * Disconnect to the BLE device that have heart rate service. * * @param device BLE device that have heart rate service. */ protected void disconnectDevice(final HitoeDevice device) { runOnUiThread(new Runnable() { @Override public void run() { getManager().disconnectHitoeDevice(device); HitoeDevice container = findDeviceContainerByAddress(device.getId()); if (container != null) { container.setRegisterFlag(false); mDeviceAdapter.notifyDataSetChanged(); } } }); } /** * Display the dialog of connecting a ble device. * * @param name device name */ protected void showProgressDialog(final String name) { dismissProgressDialog(); Resources res = getResources(); String title = res.getString(R.string.hitoe_setting_connecting_title); String message = res.getString(R.string.hitoe_setting_connecting_message, name); mProgressDialogFragment = ProgressDialogFragment.newInstance(title, message); mProgressDialogFragment.show(getSupportFragmentManager(), "dialog"); mCheckDialog = true; } /** * Dismiss the dialog of connecting a ble device. */ protected void dismissProgressDialog() { mCheckDialog = false; mHandler.removeCallbacksAndMessages(null); if (mProgressDialogFragment != null) { mProgressDialogFragment.dismiss(); mProgressDialogFragment = null; } } /** * Display the error dialog of not connect device. * * @param name device name */ protected void showErrorDialogNotConnect(final String name) { Resources res = getResources(); String message; if (name == null) { message = res.getString(R.string.hitoe_setting_dialog_error_message, getString(R.string.hitoe_setting_default_name)); } else { message = res.getString(R.string.hitoe_setting_dialog_error_message, name); } showErrorDialog(message); } /** * Display the error dialog. * * @param message error message */ protected void showErrorDialog(final String message) { dismissErrorDialog(); try { Resources res = getResources(); String title = res.getString(R.string.hitoe_setting_dialog_error_title); mErrorDialogFragment = ErrorDialogFragment.newInstance(title, message); mErrorDialogFragment.show(getSupportFragmentManager(), "error_dialog"); mErrorDialogFragment.setOnDismissListener(new DialogInterface.OnDismissListener() { @Override public void onDismiss(DialogInterface dialog) { mErrorDialogFragment = null; } }); } catch (IllegalStateException e) { if (BuildConfig.DEBUG) { e.printStackTrace(); } } } /** * Dismiss the error dialog. */ protected void dismissErrorDialog() { try { if (mErrorDialogFragment != null) { mErrorDialogFragment.dismiss(); mErrorDialogFragment = null; } } catch (IllegalStateException e) { if (BuildConfig.DEBUG) { e.printStackTrace(); } } } /** * Look for a DeviceContainer with the given address. * * @param address address of device * @return The DeviceContainer that has the given address or null */ protected HitoeDevice findDeviceContainerByAddress(final String address) { int size = mDeviceAdapter.getCount(); for (int i = 0; i < size; i++) { HitoeDevice container = mDeviceAdapter.getItem(i); if (container.getId().equalsIgnoreCase(address)) { return container; } } return null; } /** * Returns true if this address contains the mDeviceAdapter. * * @param address address of device * @return true if address is an element of mDeviceAdapter, false otherwise */ protected boolean containAddressForAdapter(final String address) { int size = mDeviceAdapter.getCount(); for (int i = 0; i < size; i++) { HitoeDevice container = mDeviceAdapter.getItem(i); if (container.getId().equals(address)) { return true; } } return false; } /** * Returns true if this address contains the mDeviceAdapter. * * @param address address of device * @return true if address is an element of mDeviceAdapter, false otherwise */ protected boolean containAddressForList(final String address) { List<HitoeDevice> devices = createDeviceContainers(); int size = devices.size(); for (int i = 0; i < size; i++) { HitoeDevice container = devices.get(i); if (container.getId().equals(address)) { return true; } } return false; } /** * Device List's adapter. */ protected class DeviceAdapter extends ArrayAdapter<HitoeDevice> { /** * Adapter inflater. */ private LayoutInflater mInflater; /** * Constructor. * @param context context * @param objects hitoe's list */ public DeviceAdapter(final Context context, final List<HitoeDevice> objects) { super(context, 0, objects); mInflater = (LayoutInflater) context.getSystemService( Context.LAYOUT_INFLATER_SERVICE); } @Override public View getView(final int position, View convertView, final ViewGroup parent) { if (convertView == null) { convertView = mInflater.inflate(R.layout.item_hitoe_device, null); } final HitoeDevice device = getItem(position); String name = device.getName(); if (device.isRegisterFlag()) { if (getManager().containConnectedHitoeDevice(device.getId())) { name += "\n" + getResources().getString(R.string.hitoe_setting_online); } else { name += "\n" + getResources().getString(R.string.hitoe_setting_offline); } } TextView nameView = (TextView) convertView.findViewById(R.id.device_name); nameView.setText(name); TextView addressView = (TextView) convertView.findViewById(R.id.device_address); addressView.setText(device.getId()); final Button btn = (Button) convertView.findViewById(R.id.btn_connect_device); if (mEnableConnectedBtn) { btn.setVisibility(View.VISIBLE); if (device.isRegisterFlag()) { btn.setBackgroundResource(R.drawable.button_red); btn.setText(R.string.hitoe_setting_disconnect); } else { btn.setBackgroundResource(R.drawable.button_blue); btn.setText(R.string.hitoe_setting_connect); } btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(final View v) { for (HitoeDevice d: getManager().getRegisterDevices()) { if (!d.getName().equals(device.getName()) && d.isRegisterFlag()) { getManager().disconnectHitoeDevice(d); } } if (device.isRegisterFlag()) { btn.setBackgroundResource(R.drawable.button_blue); btn.setText(R.string.hitoe_setting_connect); disconnectDevice(device); } else { if (device.getPinCode() == null) { final Resources res = getResources(); PinCodeDialogFragment pinDialog = PinCodeDialogFragment.newInstance(); pinDialog.show(getSupportFragmentManager(), "pin_dialog"); pinDialog.setOnPinCodeListener(new PinCodeDialogFragment.OnPinCodeListener() { @Override public void onPinCode(final String pin) { if (pin.isEmpty()) { showErrorDialog( res.getString(R.string.hitoe_setting_dialog_error_message02)); return; } device.setPinCode(pin); connectDevice(device); } }); } else { connectDevice(device); } mHandler.postDelayed(new Runnable() { @Override public void run() { if (mCheckDialog) { device.setPinCode(null); runOnUiThread(new Runnable() { @Override public void run() { dismissProgressDialog(); Resources res = getResources(); showErrorDialog( res.getString(R.string.hitoe_setting_dialog_error_message04)); } }); } } }, HitoeConstants.DISCOVERY_CYCLE_TIME); } } }); } else { btn.setVisibility(View.GONE); } return convertView; } } }