blob: 0edca45205460c792e2b725081540999e45f4a6e [file] [log] [blame]
/*
* Copyright 2014 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 com.google.samples.apps.iosched.nearby;
import android.app.Activity;
import android.os.Handler;
import android.text.Html;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.google.samples.apps.iosched.R;
import java.util.*;
import static com.google.samples.apps.iosched.util.LogUtils.makeLogTag;
/**
* Adapter class for building views related to BLE devices.
*/
public class NearbyDeviceAdapter extends BaseAdapter {
String TAG = makeLogTag("NearbyDeviceAdapter");
private ArrayList<NearbyDevice> mNearbyDevices;
private Activity mActivity;
private Handler mHandler = new Handler();
private long mLastChangeRequestTime = 0;
private long NOTIFY_DELAY = 300;
NearbyDeviceAdapter(Activity activity) {
mNearbyDevices = new ArrayList<NearbyDevice>();
mActivity = activity;
}
@Override
public int getCount() {
return mNearbyDevices.size();
}
@Override
public Object getItem(int i) {
return mNearbyDevices.get(i);
}
@Override
public long getItemId(int i) {
NearbyDevice device = mNearbyDevices.get(i);
return System.identityHashCode(device);
}
@Override
public View getView(int i, View view, ViewGroup container) {
if (view == null) {
view = mActivity.getLayoutInflater().inflate(R.layout.ble_listitem_device, null);
}
NearbyDevice device = mNearbyDevices.get(i);
DeviceMetadata deviceMetadata = device.getInfo();
TextView infoView;
infoView = (TextView) view.findViewById(R.id.title);
if (deviceMetadata != null) {
String title = deviceMetadata.title;
if (!TextUtils.isEmpty(title)) {
infoView.setText(Html.fromHtml(deviceMetadata.title));
infoView.setVisibility(View.VISIBLE);
} else {
infoView.setVisibility(View.GONE);
}
} else {
infoView.setText(R.string.loading);
infoView.setVisibility(View.VISIBLE);
}
infoView = (TextView) view.findViewById(R.id.url);
if (deviceMetadata != null) {
infoView.setText(deviceMetadata.siteUrl);
} else {
infoView.setText(device.getUrl());
}
infoView = (TextView) view.findViewById(R.id.description);
if (deviceMetadata != null) {
String description = deviceMetadata.description;
if (!TextUtils.isEmpty(description)) {
infoView.setText(Html.fromHtml(deviceMetadata.description));
infoView.setVisibility(View.VISIBLE);
} else {
infoView.setVisibility(View.GONE);
}
} else {
infoView.setVisibility(View.INVISIBLE);
}
ImageView iconView = (ImageView) view.findViewById(R.id.icon);
if (deviceMetadata != null) {
iconView.setImageBitmap(deviceMetadata.icon);
} else {
iconView.setImageResource(R.drawable.empty_nearby_icon);
}
return view;
}
public void addDevice(final NearbyDevice device) {
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
mNearbyDevices.add(device);
device.setAdapter(NearbyDeviceAdapter.this);
queueChangedNotification();
}
});
}
public NearbyDevice getExistingDevice(NearbyDevice candidateDevice) {
for (NearbyDevice device : mNearbyDevices) {
if (device.getUrl().equals(candidateDevice.getUrl())) {
return device;
}
}
return null;
}
public ArrayList<NearbyDevice> removeExpiredDevices() {
// Get a list of devices that we need to remove.
ArrayList<NearbyDevice> toRemove = new ArrayList<NearbyDevice>();
for (NearbyDevice device : mNearbyDevices) {
if (device.isLastSeenAfter(NearbyDeviceManager.MAX_INACTIVE_TIME)) {
toRemove.add(device);
}
}
// Remove those devices from the list and notify the listener.
for (final NearbyDevice device : toRemove) {
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
mNearbyDevices.remove(device);
queueChangedNotification();
}
});
}
return toRemove;
}
public void updateListUI() {
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
queueChangedNotification();
}
});
}
private Runnable mNotifyRunnable = new Runnable() {
@Override
public void run() {
notifyDataSetChanged();
}
};
public void queueChangedNotification() {
long now = System.currentTimeMillis();
// If a notification was recently issued, create a pending notification.
if (now - mLastChangeRequestTime < NOTIFY_DELAY) {
// Ignore if there's a pending timer already.
mHandler.removeCallbacks(mNotifyRunnable);
mHandler.postDelayed(mNotifyRunnable, NOTIFY_DELAY);
} else {
// Otherwise, if there's no active timer, notify immediately.
Log.i(TAG, "queueChangedNotification: Immediately notifying.");
notifyDataSetChanged();
}
}
@Override
public void notifyDataSetChanged() {
Log.i(TAG, "queueChangedNotification: notifyDataSetChanged");
Collections.sort(mNearbyDevices, mRssiComparator);
super.notifyDataSetChanged();
// Cancel the pending notification timer if there is one.
mHandler.removeCallbacks(mNotifyRunnable);
mLastChangeRequestTime = System.currentTimeMillis();
}
private Comparator<NearbyDevice> mRssiComparator = new Comparator<NearbyDevice>() {
@Override
public int compare(NearbyDevice lhs, NearbyDevice rhs) {
return rhs.getAverageRSSI() - lhs.getAverageRSSI();
}
};
}