The dound device list is now implemented as a recyclerview.
This commit is contained in:
+22
-8
@@ -3,25 +3,24 @@ package uk.co.alt236.btlescan.ui.common.recyclerview;
|
|||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public abstract class BaseRecyclerViewAdapter extends RecyclerView.Adapter<BaseViewHolder<? extends RecyclerViewItem>> {
|
public abstract class BaseRecyclerViewAdapter extends RecyclerView.Adapter<BaseViewHolder<? extends RecyclerViewItem>> {
|
||||||
|
|
||||||
private final List<? extends RecyclerViewItem> mItemList;
|
private final List<RecyclerViewItem> mItemList;
|
||||||
private final RecyclerViewBinderCore mCore;
|
private final RecyclerViewBinderCore mCore;
|
||||||
|
|
||||||
public BaseRecyclerViewAdapter(final RecyclerViewBinderCore core,
|
public BaseRecyclerViewAdapter(final RecyclerViewBinderCore core,
|
||||||
final List<RecyclerViewItem> items) {
|
final List<RecyclerViewItem> items) {
|
||||||
mItemList = items;
|
mItemList = new ArrayList<>();
|
||||||
mCore = core;
|
mCore = core;
|
||||||
|
mItemList.addAll(items);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <T extends RecyclerViewItem> void bind(final BaseViewBinder<T> binder,
|
public BaseRecyclerViewAdapter(final RecyclerViewBinderCore core) {
|
||||||
final BaseViewHolder<?> holder,
|
this(core, new ArrayList<RecyclerViewItem>());
|
||||||
final RecyclerViewItem item) {
|
|
||||||
|
|
||||||
//noinspection unchecked
|
|
||||||
binder.bind((BaseViewHolder<T>) holder, (T) item);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -52,4 +51,19 @@ public abstract class BaseRecyclerViewAdapter extends RecyclerView.Adapter<BaseV
|
|||||||
public RecyclerViewItem getItem(final int position) {
|
public RecyclerViewItem getItem(final int position) {
|
||||||
return mItemList.get(position);
|
return mItemList.get(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setData(Collection<? extends RecyclerViewItem> data) {
|
||||||
|
|
||||||
|
mItemList.clear();
|
||||||
|
mItemList.addAll(data);
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T extends RecyclerViewItem> void bind(final BaseViewBinder<T> binder,
|
||||||
|
final BaseViewHolder<?> holder,
|
||||||
|
final RecyclerViewItem item) {
|
||||||
|
|
||||||
|
//noinspection unchecked
|
||||||
|
binder.bind((BaseViewHolder<T>) holder, (T) item);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
@@ -1,5 +1,6 @@
|
|||||||
package uk.co.alt236.btlescan.ui.common.recyclerview;
|
package uk.co.alt236.btlescan.ui.common.recyclerview;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
@@ -12,6 +13,7 @@ import java.util.List;
|
|||||||
public class RecyclerViewBinderCore {
|
public class RecyclerViewBinderCore {
|
||||||
public static final int INVALID_VIEWTYPE = -1;
|
public static final int INVALID_VIEWTYPE = -1;
|
||||||
|
|
||||||
|
private static final String TAG = RecyclerViewBinderCore.class.getSimpleName();
|
||||||
private final List<Class<? extends BaseViewHolder<? extends RecyclerViewItem>>> mViewHolderClasses;
|
private final List<Class<? extends BaseViewHolder<? extends RecyclerViewItem>>> mViewHolderClasses;
|
||||||
private final List<BaseViewBinder<? extends RecyclerViewItem>> mViewBinders;
|
private final List<BaseViewBinder<? extends RecyclerViewItem>> mViewBinders;
|
||||||
private final List<Integer> mLayoutIds;
|
private final List<Integer> mLayoutIds;
|
||||||
@@ -64,6 +66,10 @@ public class RecyclerViewBinderCore {
|
|||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (result == INVALID_VIEWTYPE) {
|
||||||
|
Log.w(TAG, "Could not get viewType for " + item);
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,126 +0,0 @@
|
|||||||
package uk.co.alt236.btlescan.ui.main;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.support.v4.widget.SimpleCursorAdapter;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.ImageView;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice;
|
|
||||||
import uk.co.alt236.bluetoothlelib.device.beacon.BeaconType;
|
|
||||||
import uk.co.alt236.bluetoothlelib.device.beacon.BeaconUtils;
|
|
||||||
import uk.co.alt236.bluetoothlelib.device.beacon.ibeacon.IBeaconDevice;
|
|
||||||
import uk.co.alt236.btlescan.R;
|
|
||||||
import uk.co.alt236.btlescan.util.Constants;
|
|
||||||
import uk.co.alt236.easycursor.objectcursor.EasyObjectCursor;
|
|
||||||
|
|
||||||
// Adapter for holding devices found through scanning.
|
|
||||||
/*package*/ class DeviceListAdapter extends SimpleCursorAdapter {
|
|
||||||
private final LayoutInflater mInflator;
|
|
||||||
private final Activity mActivity;
|
|
||||||
|
|
||||||
public DeviceListAdapter(final Activity activity, final EasyObjectCursor<BluetoothLeDevice> cursor) {
|
|
||||||
super(activity, R.layout.list_item_device, cursor, new String[0], new int[0], 0);
|
|
||||||
mInflator = activity.getLayoutInflater();
|
|
||||||
mActivity = activity;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@Override
|
|
||||||
public EasyObjectCursor<BluetoothLeDevice> getCursor() {
|
|
||||||
return ((EasyObjectCursor<BluetoothLeDevice>) super.getCursor());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BluetoothLeDevice getItem(final int i) {
|
|
||||||
return getCursor().getItem(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getItemId(final int i) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View getView(final int i, View view, final ViewGroup viewGroup) {
|
|
||||||
final ViewHolder viewHolder;
|
|
||||||
// General ListView optimization code.
|
|
||||||
if (view == null) {
|
|
||||||
view = mInflator.inflate(R.layout.list_item_device, null);
|
|
||||||
viewHolder = new ViewHolder();
|
|
||||||
viewHolder.deviceAddress = (TextView) view.findViewById(R.id.device_address);
|
|
||||||
viewHolder.deviceName = (TextView) view.findViewById(R.id.device_name);
|
|
||||||
viewHolder.deviceRssi = (TextView) view.findViewById(R.id.device_rssi);
|
|
||||||
viewHolder.deviceIcon = (ImageView) view.findViewById(R.id.device_icon);
|
|
||||||
viewHolder.deviceLastUpdated = (TextView) view.findViewById(R.id.device_last_update);
|
|
||||||
viewHolder.ibeaconMajor = (TextView) view.findViewById(R.id.ibeacon_major);
|
|
||||||
viewHolder.ibeaconMinor = (TextView) view.findViewById(R.id.ibeacon_minor);
|
|
||||||
viewHolder.ibeaconDistance = (TextView) view.findViewById(R.id.ibeacon_distance);
|
|
||||||
viewHolder.ibeaconUUID = (TextView) view.findViewById(R.id.ibeacon_uuid);
|
|
||||||
viewHolder.ibeaconTxPower = (TextView) view.findViewById(R.id.ibeacon_tx_power);
|
|
||||||
viewHolder.ibeaconSection = view.findViewById(R.id.ibeacon_section);
|
|
||||||
viewHolder.ibeaconDistanceDescriptor = (TextView) view.findViewById(R.id.ibeacon_distance_descriptor);
|
|
||||||
view.setTag(viewHolder);
|
|
||||||
} else {
|
|
||||||
viewHolder = (ViewHolder) view.getTag();
|
|
||||||
}
|
|
||||||
|
|
||||||
final BluetoothLeDevice device = getCursor().getItem(i);
|
|
||||||
final String deviceName = device.getName();
|
|
||||||
final double rssi = device.getRssi();
|
|
||||||
|
|
||||||
if (deviceName != null && deviceName.length() > 0) {
|
|
||||||
viewHolder.deviceName.setText(deviceName);
|
|
||||||
} else {
|
|
||||||
viewHolder.deviceName.setText(R.string.unknown_device);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (BeaconUtils.getBeaconType(device) == BeaconType.IBEACON) {
|
|
||||||
final IBeaconDevice iBeacon = new IBeaconDevice(device);
|
|
||||||
final String accuracy = Constants.DOUBLE_TWO_DIGIT_ACCURACY.format(iBeacon.getAccuracy());
|
|
||||||
|
|
||||||
viewHolder.deviceIcon.setImageResource(R.drawable.ic_device_ibeacon);
|
|
||||||
viewHolder.ibeaconSection.setVisibility(View.VISIBLE);
|
|
||||||
viewHolder.ibeaconMajor.setText(String.valueOf(iBeacon.getMajor()));
|
|
||||||
viewHolder.ibeaconMinor.setText(String.valueOf(iBeacon.getMinor()));
|
|
||||||
viewHolder.ibeaconTxPower.setText(String.valueOf(iBeacon.getCalibratedTxPower()));
|
|
||||||
viewHolder.ibeaconUUID.setText(iBeacon.getUUID());
|
|
||||||
viewHolder.ibeaconDistance.setText(
|
|
||||||
mActivity.getString(R.string.formatter_meters, accuracy));
|
|
||||||
viewHolder.ibeaconDistanceDescriptor.setText(iBeacon.getDistanceDescriptor().toString());
|
|
||||||
} else {
|
|
||||||
viewHolder.deviceIcon.setImageResource(R.drawable.ic_bluetooth);
|
|
||||||
viewHolder.ibeaconSection.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
final String rssiString =
|
|
||||||
mActivity.getString(R.string.formatter_db, String.valueOf(rssi));
|
|
||||||
final String runningAverageRssiString =
|
|
||||||
mActivity.getString(R.string.formatter_db, String.valueOf(device.getRunningAverageRssi()));
|
|
||||||
|
|
||||||
viewHolder.deviceLastUpdated.setText(
|
|
||||||
android.text.format.DateFormat.format(
|
|
||||||
Constants.TIME_FORMAT, new java.util.Date(device.getTimestamp())));
|
|
||||||
viewHolder.deviceAddress.setText(device.getAddress());
|
|
||||||
viewHolder.deviceRssi.setText(rssiString + " / " + runningAverageRssiString);
|
|
||||||
return view;
|
|
||||||
}
|
|
||||||
|
|
||||||
static class ViewHolder {
|
|
||||||
TextView deviceName;
|
|
||||||
TextView deviceAddress;
|
|
||||||
TextView deviceRssi;
|
|
||||||
TextView ibeaconUUID;
|
|
||||||
TextView ibeaconMajor;
|
|
||||||
TextView ibeaconMinor;
|
|
||||||
TextView ibeaconTxPower;
|
|
||||||
TextView ibeaconDistance;
|
|
||||||
TextView ibeaconDistanceDescriptor;
|
|
||||||
TextView deviceLastUpdated;
|
|
||||||
View ibeaconSection;
|
|
||||||
ImageView deviceIcon;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package uk.co.alt236.btlescan.ui.main;
|
||||||
|
|
||||||
|
import uk.co.alt236.btlescan.ui.common.recyclerview.BaseRecyclerViewAdapter;
|
||||||
|
import uk.co.alt236.btlescan.ui.common.recyclerview.RecyclerViewBinderCore;
|
||||||
|
|
||||||
|
/*package*/ class DeviceRecyclerAdapter extends BaseRecyclerViewAdapter {
|
||||||
|
public DeviceRecyclerAdapter(RecyclerViewBinderCore core) {
|
||||||
|
super(core);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,28 +6,37 @@ import android.bluetooth.BluetoothDevice;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.AdapterView;
|
|
||||||
import android.widget.ListView;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.anthonycr.grant.PermissionsManager;
|
import com.anthonycr.grant.PermissionsManager;
|
||||||
import com.anthonycr.grant.PermissionsResultAction;
|
import com.anthonycr.grant.PermissionsResultAction;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import butterknife.Bind;
|
import butterknife.Bind;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice;
|
import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice;
|
||||||
|
import uk.co.alt236.bluetoothlelib.device.beacon.BeaconType;
|
||||||
|
import uk.co.alt236.bluetoothlelib.device.beacon.BeaconUtils;
|
||||||
|
import uk.co.alt236.bluetoothlelib.device.beacon.ibeacon.IBeaconDevice;
|
||||||
import uk.co.alt236.btlescan.R;
|
import uk.co.alt236.btlescan.R;
|
||||||
import uk.co.alt236.btlescan.containers.BluetoothLeDeviceStore;
|
import uk.co.alt236.btlescan.containers.BluetoothLeDeviceStore;
|
||||||
import uk.co.alt236.btlescan.ui.common.Navigation;
|
import uk.co.alt236.btlescan.ui.common.Navigation;
|
||||||
|
import uk.co.alt236.btlescan.ui.common.recyclerview.RecyclerViewBinderCore;
|
||||||
|
import uk.co.alt236.btlescan.ui.common.recyclerview.RecyclerViewItem;
|
||||||
|
import uk.co.alt236.btlescan.ui.main.recyclerview.model.IBeaconItem;
|
||||||
|
import uk.co.alt236.btlescan.ui.main.recyclerview.model.LeDeviceItem;
|
||||||
import uk.co.alt236.btlescan.util.BluetoothLeScanner;
|
import uk.co.alt236.btlescan.util.BluetoothLeScanner;
|
||||||
import uk.co.alt236.btlescan.util.BluetoothUtils;
|
import uk.co.alt236.btlescan.util.BluetoothUtils;
|
||||||
import uk.co.alt236.easycursor.objectcursor.EasyObjectCursor;
|
|
||||||
|
|
||||||
public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {
|
public class MainActivity extends AppCompatActivity {
|
||||||
@Bind(R.id.tvBluetoothLe)
|
@Bind(R.id.tvBluetoothLe)
|
||||||
protected TextView mTvBluetoothLeStatus;
|
protected TextView mTvBluetoothLeStatus;
|
||||||
@Bind(R.id.tvBluetoothStatus)
|
@Bind(R.id.tvBluetoothStatus)
|
||||||
@@ -35,14 +44,15 @@ public class MainActivity extends AppCompatActivity implements AdapterView.OnIte
|
|||||||
@Bind(R.id.tvItemCount)
|
@Bind(R.id.tvItemCount)
|
||||||
protected TextView mTvItemCount;
|
protected TextView mTvItemCount;
|
||||||
@Bind(android.R.id.list)
|
@Bind(android.R.id.list)
|
||||||
protected ListView mList;
|
protected RecyclerView mList;
|
||||||
@Bind(android.R.id.empty)
|
@Bind(android.R.id.empty)
|
||||||
protected View mEmpty;
|
protected View mEmpty;
|
||||||
|
|
||||||
|
private RecyclerViewBinderCore mCore;
|
||||||
private BluetoothUtils mBluetoothUtils;
|
private BluetoothUtils mBluetoothUtils;
|
||||||
private BluetoothLeScanner mScanner;
|
private BluetoothLeScanner mScanner;
|
||||||
private DeviceListAdapter mDeviceListAdapter;
|
|
||||||
private BluetoothLeDeviceStore mDeviceStore;
|
private BluetoothLeDeviceStore mDeviceStore;
|
||||||
|
private DeviceRecyclerAdapter mRecyclerAdapter;
|
||||||
|
|
||||||
private final BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
|
private final BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
|
||||||
@Override
|
@Override
|
||||||
@@ -50,13 +60,21 @@ public class MainActivity extends AppCompatActivity implements AdapterView.OnIte
|
|||||||
|
|
||||||
final BluetoothLeDevice deviceLe = new BluetoothLeDevice(device, rssi, scanRecord, System.currentTimeMillis());
|
final BluetoothLeDevice deviceLe = new BluetoothLeDevice(device, rssi, scanRecord, System.currentTimeMillis());
|
||||||
mDeviceStore.addDevice(deviceLe);
|
mDeviceStore.addDevice(deviceLe);
|
||||||
final EasyObjectCursor<BluetoothLeDevice> c = mDeviceStore.getDeviceCursor();
|
final List<RecyclerViewItem> itemList = new ArrayList<>();
|
||||||
|
|
||||||
|
for (final BluetoothLeDevice leDevice : mDeviceStore.getDeviceList()) {
|
||||||
|
if (BeaconUtils.getBeaconType(leDevice) == BeaconType.IBEACON) {
|
||||||
|
itemList.add(new IBeaconItem(new IBeaconDevice(leDevice)));
|
||||||
|
} else {
|
||||||
|
itemList.add(new LeDeviceItem(leDevice));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
runOnUiThread(new Runnable() {
|
runOnUiThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
mDeviceListAdapter.swapCursor(c);
|
mRecyclerAdapter.setData(itemList);
|
||||||
updateItemCount(mDeviceListAdapter.getCount());
|
updateItemCount(mRecyclerAdapter.getItemCount());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -67,8 +85,8 @@ public class MainActivity extends AppCompatActivity implements AdapterView.OnIte
|
|||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_main);
|
setContentView(R.layout.activity_main);
|
||||||
ButterKnife.bind(this);
|
ButterKnife.bind(this);
|
||||||
mList.setEmptyView(mEmpty);
|
mCore = RecyclerViewCoreFactory.create(this, new Navigation(this));
|
||||||
mList.setOnItemClickListener(this);
|
mList.setLayoutManager(new LinearLayoutManager(this));
|
||||||
mDeviceStore = new BluetoothLeDeviceStore();
|
mDeviceStore = new BluetoothLeDeviceStore();
|
||||||
mBluetoothUtils = new BluetoothUtils(this);
|
mBluetoothUtils = new BluetoothUtils(this);
|
||||||
mScanner = new BluetoothLeScanner(mLeScanCallback, mBluetoothUtils);
|
mScanner = new BluetoothLeScanner(mLeScanCallback, mBluetoothUtils);
|
||||||
@@ -88,7 +106,7 @@ public class MainActivity extends AppCompatActivity implements AdapterView.OnIte
|
|||||||
menu.findItem(R.id.menu_refresh).setActionView(R.layout.actionbar_progress_indeterminate);
|
menu.findItem(R.id.menu_refresh).setActionView(R.layout.actionbar_progress_indeterminate);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mList.getCount() > 0) {
|
if (mRecyclerAdapter != null && mRecyclerAdapter.getItemCount() > 0) {
|
||||||
menu.findItem(R.id.menu_share).setVisible(true);
|
menu.findItem(R.id.menu_share).setVisible(true);
|
||||||
} else {
|
} else {
|
||||||
menu.findItem(R.id.menu_share).setVisible(false);
|
menu.findItem(R.id.menu_share).setVisible(false);
|
||||||
@@ -97,12 +115,6 @@ public class MainActivity extends AppCompatActivity implements AdapterView.OnIte
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
|
|
||||||
final BluetoothLeDevice device = mDeviceListAdapter.getItem(position);
|
|
||||||
new Navigation(this).openDetailsActivity(device);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(final MenuItem item) {
|
public boolean onOptionsItemSelected(final MenuItem item) {
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
@@ -146,16 +158,14 @@ public class MainActivity extends AppCompatActivity implements AdapterView.OnIte
|
|||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
final boolean mIsBluetoothOn = mBluetoothUtils.isBluetoothOn();
|
|
||||||
final boolean mIsBluetoothLePresent = mBluetoothUtils.isBluetoothLeSupported();
|
|
||||||
|
|
||||||
if (mIsBluetoothOn) {
|
if (mBluetoothUtils.isBluetoothOn()) {
|
||||||
mTvBluetoothStatus.setText(R.string.on);
|
mTvBluetoothStatus.setText(R.string.on);
|
||||||
} else {
|
} else {
|
||||||
mTvBluetoothStatus.setText(R.string.off);
|
mTvBluetoothStatus.setText(R.string.off);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mIsBluetoothLePresent) {
|
if (mBluetoothUtils.isBluetoothLeSupported()) {
|
||||||
mTvBluetoothLeStatus.setText(R.string.supported);
|
mTvBluetoothLeStatus.setText(R.string.supported);
|
||||||
} else {
|
} else {
|
||||||
mTvBluetoothLeStatus.setText(R.string.not_supported);
|
mTvBluetoothLeStatus.setText(R.string.not_supported);
|
||||||
@@ -170,8 +180,8 @@ public class MainActivity extends AppCompatActivity implements AdapterView.OnIte
|
|||||||
mDeviceStore.clear();
|
mDeviceStore.clear();
|
||||||
updateItemCount(0);
|
updateItemCount(0);
|
||||||
|
|
||||||
mDeviceListAdapter = new DeviceListAdapter(this, mDeviceStore.getDeviceCursor());
|
mRecyclerAdapter = new DeviceRecyclerAdapter(mCore);
|
||||||
mList.setAdapter(mDeviceListAdapter);
|
mList.setAdapter(mRecyclerAdapter);
|
||||||
|
|
||||||
mBluetoothUtils.askUserToEnableBluetoothIfNeeded();
|
mBluetoothUtils.askUserToEnableBluetoothIfNeeded();
|
||||||
if (mIsBluetoothOn && mIsBluetoothLePresent) {
|
if (mIsBluetoothOn && mIsBluetoothLePresent) {
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package uk.co.alt236.btlescan.ui.main;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import uk.co.alt236.btlescan.R;
|
||||||
|
import uk.co.alt236.btlescan.ui.common.Navigation;
|
||||||
|
import uk.co.alt236.btlescan.ui.common.recyclerview.RecyclerViewBinderCore;
|
||||||
|
import uk.co.alt236.btlescan.ui.main.recyclerview.binder.IBeaconBinder;
|
||||||
|
import uk.co.alt236.btlescan.ui.main.recyclerview.binder.LeDeviceBinder;
|
||||||
|
import uk.co.alt236.btlescan.ui.main.recyclerview.holder.IBeaconHolder;
|
||||||
|
import uk.co.alt236.btlescan.ui.main.recyclerview.holder.LeDeviceHolder;
|
||||||
|
|
||||||
|
/*protected*/ final class RecyclerViewCoreFactory {
|
||||||
|
|
||||||
|
public static RecyclerViewBinderCore create(final Context context, final Navigation navigation) {
|
||||||
|
final RecyclerViewBinderCore core = new RecyclerViewBinderCore();
|
||||||
|
|
||||||
|
core.add(new IBeaconBinder(context, navigation), IBeaconHolder.class, R.layout.list_item_device_ibeacon);
|
||||||
|
core.add(new LeDeviceBinder(context, navigation), LeDeviceHolder.class, R.layout.list_item_device_le);
|
||||||
|
|
||||||
|
return core;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
package uk.co.alt236.btlescan.ui.main.recyclerview.binder;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice;
|
||||||
|
import uk.co.alt236.btlescan.R;
|
||||||
|
import uk.co.alt236.btlescan.ui.main.recyclerview.holder.CommonDeviceHolder;
|
||||||
|
import uk.co.alt236.btlescan.util.Constants;
|
||||||
|
|
||||||
|
/*package*/ class CommonBinding {
|
||||||
|
|
||||||
|
public static void bind(final Context context,
|
||||||
|
final CommonDeviceHolder holder,
|
||||||
|
final BluetoothLeDevice device) {
|
||||||
|
|
||||||
|
final String deviceName = device.getName();
|
||||||
|
final double rssi = device.getRssi();
|
||||||
|
|
||||||
|
if (deviceName != null && deviceName.length() > 0) {
|
||||||
|
holder.getDeviceName().setText(deviceName);
|
||||||
|
} else {
|
||||||
|
holder.getDeviceName().setText(R.string.unknown_device);
|
||||||
|
}
|
||||||
|
|
||||||
|
final String rssiString =
|
||||||
|
context.getString(R.string.formatter_db, String.valueOf(rssi));
|
||||||
|
final String runningAverageRssiString =
|
||||||
|
context.getString(R.string.formatter_db, String.valueOf(device.getRunningAverageRssi()));
|
||||||
|
|
||||||
|
holder.getDeviceLastUpdated().setText(
|
||||||
|
android.text.format.DateFormat.format(
|
||||||
|
Constants.TIME_FORMAT, new java.util.Date(device.getTimestamp())));
|
||||||
|
holder.getDeviceAddress().setText(device.getAddress());
|
||||||
|
holder.getDeviceRssi().setText(rssiString + " / " + runningAverageRssiString);
|
||||||
|
}
|
||||||
|
}
|
||||||
+54
@@ -0,0 +1,54 @@
|
|||||||
|
package uk.co.alt236.btlescan.ui.main.recyclerview.binder;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import uk.co.alt236.bluetoothlelib.device.beacon.ibeacon.IBeaconDevice;
|
||||||
|
import uk.co.alt236.btlescan.R;
|
||||||
|
import uk.co.alt236.btlescan.ui.common.Navigation;
|
||||||
|
import uk.co.alt236.btlescan.ui.common.recyclerview.BaseViewBinder;
|
||||||
|
import uk.co.alt236.btlescan.ui.common.recyclerview.BaseViewHolder;
|
||||||
|
import uk.co.alt236.btlescan.ui.common.recyclerview.RecyclerViewItem;
|
||||||
|
import uk.co.alt236.btlescan.ui.main.recyclerview.holder.IBeaconHolder;
|
||||||
|
import uk.co.alt236.btlescan.ui.main.recyclerview.model.IBeaconItem;
|
||||||
|
import uk.co.alt236.btlescan.util.Constants;
|
||||||
|
|
||||||
|
public class IBeaconBinder extends BaseViewBinder<IBeaconItem> {
|
||||||
|
|
||||||
|
private final Navigation navigation;
|
||||||
|
|
||||||
|
public IBeaconBinder(Context context, Navigation navigation) {
|
||||||
|
super(context);
|
||||||
|
this.navigation = navigation;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void bind(BaseViewHolder<IBeaconItem> holder, IBeaconItem item) {
|
||||||
|
|
||||||
|
final IBeaconHolder actualHolder = (IBeaconHolder) holder;
|
||||||
|
final IBeaconDevice device = item.getDevice();
|
||||||
|
|
||||||
|
final String accuracy = Constants.DOUBLE_TWO_DIGIT_ACCURACY.format(device.getAccuracy());
|
||||||
|
|
||||||
|
actualHolder.getIbeaconMajor().setText(String.valueOf(device.getMajor()));
|
||||||
|
actualHolder.getIbeaconMinor().setText(String.valueOf(device.getMinor()));
|
||||||
|
actualHolder.getIbeaconTxPower().setText(String.valueOf(device.getCalibratedTxPower()));
|
||||||
|
actualHolder.getIbeaconUUID().setText(device.getUUID());
|
||||||
|
actualHolder.getIbeaconDistance().setText(
|
||||||
|
getContext().getString(R.string.formatter_meters, accuracy));
|
||||||
|
actualHolder.getIbeaconDistanceDescriptor().setText(device.getDistanceDescriptor().toString());
|
||||||
|
|
||||||
|
CommonBinding.bind(getContext(), actualHolder, device);
|
||||||
|
actualHolder.getView().setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
navigation.openDetailsActivity(device);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canBind(RecyclerViewItem item) {
|
||||||
|
return item instanceof IBeaconItem;
|
||||||
|
}
|
||||||
|
}
|
||||||
+42
@@ -0,0 +1,42 @@
|
|||||||
|
package uk.co.alt236.btlescan.ui.main.recyclerview.binder;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice;
|
||||||
|
import uk.co.alt236.btlescan.ui.common.Navigation;
|
||||||
|
import uk.co.alt236.btlescan.ui.common.recyclerview.BaseViewBinder;
|
||||||
|
import uk.co.alt236.btlescan.ui.common.recyclerview.BaseViewHolder;
|
||||||
|
import uk.co.alt236.btlescan.ui.common.recyclerview.RecyclerViewItem;
|
||||||
|
import uk.co.alt236.btlescan.ui.main.recyclerview.holder.LeDeviceHolder;
|
||||||
|
import uk.co.alt236.btlescan.ui.main.recyclerview.model.LeDeviceItem;
|
||||||
|
|
||||||
|
public class LeDeviceBinder extends BaseViewBinder<LeDeviceItem> {
|
||||||
|
|
||||||
|
private final Navigation navigation;
|
||||||
|
|
||||||
|
public LeDeviceBinder(Context context, Navigation navigation) {
|
||||||
|
super(context);
|
||||||
|
this.navigation = navigation;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void bind(BaseViewHolder<LeDeviceItem> holder, LeDeviceItem item) {
|
||||||
|
|
||||||
|
final LeDeviceHolder actualHolder = (LeDeviceHolder) holder;
|
||||||
|
final BluetoothLeDevice device = item.getDevice();
|
||||||
|
|
||||||
|
CommonBinding.bind(getContext(), actualHolder, device);
|
||||||
|
actualHolder.getView().setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
navigation.openDetailsActivity(device);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canBind(RecyclerViewItem item) {
|
||||||
|
return item instanceof LeDeviceItem;
|
||||||
|
}
|
||||||
|
}
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
package uk.co.alt236.btlescan.ui.main.recyclerview.holder;
|
||||||
|
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
public interface CommonDeviceHolder {
|
||||||
|
TextView getDeviceName();
|
||||||
|
|
||||||
|
TextView getDeviceAddress();
|
||||||
|
|
||||||
|
TextView getDeviceRssi();
|
||||||
|
|
||||||
|
TextView getDeviceLastUpdated();
|
||||||
|
}
|
||||||
+83
@@ -0,0 +1,83 @@
|
|||||||
|
package uk.co.alt236.btlescan.ui.main.recyclerview.holder;
|
||||||
|
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import uk.co.alt236.btlescan.R;
|
||||||
|
import uk.co.alt236.btlescan.ui.common.recyclerview.BaseViewHolder;
|
||||||
|
import uk.co.alt236.btlescan.ui.main.recyclerview.model.IBeaconItem;
|
||||||
|
|
||||||
|
public class IBeaconHolder extends BaseViewHolder<IBeaconItem> implements CommonDeviceHolder {
|
||||||
|
|
||||||
|
private final TextView ibeaconUUID;
|
||||||
|
private final TextView ibeaconMajor;
|
||||||
|
private final TextView ibeaconMinor;
|
||||||
|
private final TextView ibeaconTxPower;
|
||||||
|
private final TextView ibeaconDistance;
|
||||||
|
private final TextView ibeaconDistanceDescriptor;
|
||||||
|
|
||||||
|
private final TextView deviceName;
|
||||||
|
private final TextView deviceAddress;
|
||||||
|
private final TextView deviceRssi;
|
||||||
|
private final TextView deviceLastUpdated;
|
||||||
|
|
||||||
|
public IBeaconHolder(View itemView) {
|
||||||
|
super(itemView);
|
||||||
|
|
||||||
|
this.deviceAddress = (TextView) itemView.findViewById(R.id.device_address);
|
||||||
|
this.deviceName = (TextView) itemView.findViewById(R.id.device_name);
|
||||||
|
this.deviceRssi = (TextView) itemView.findViewById(R.id.device_rssi);
|
||||||
|
this.deviceLastUpdated = (TextView) itemView.findViewById(R.id.device_last_update);
|
||||||
|
|
||||||
|
this.ibeaconMajor = (TextView) itemView.findViewById(R.id.ibeacon_major);
|
||||||
|
this.ibeaconMinor = (TextView) itemView.findViewById(R.id.ibeacon_minor);
|
||||||
|
this.ibeaconDistance = (TextView) itemView.findViewById(R.id.ibeacon_distance);
|
||||||
|
this.ibeaconUUID = (TextView) itemView.findViewById(R.id.ibeacon_uuid);
|
||||||
|
this.ibeaconTxPower = (TextView) itemView.findViewById(R.id.ibeacon_tx_power);
|
||||||
|
this.ibeaconDistanceDescriptor = (TextView) itemView.findViewById(R.id.ibeacon_distance_descriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TextView getDeviceName() {
|
||||||
|
return deviceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TextView getDeviceAddress() {
|
||||||
|
return deviceAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TextView getDeviceRssi() {
|
||||||
|
return deviceRssi;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TextView getDeviceLastUpdated() {
|
||||||
|
return deviceLastUpdated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextView getIbeaconUUID() {
|
||||||
|
return ibeaconUUID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextView getIbeaconMajor() {
|
||||||
|
return ibeaconMajor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextView getIbeaconMinor() {
|
||||||
|
return ibeaconMinor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextView getIbeaconTxPower() {
|
||||||
|
return ibeaconTxPower;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextView getIbeaconDistance() {
|
||||||
|
return ibeaconDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextView getIbeaconDistanceDescriptor() {
|
||||||
|
return ibeaconDistanceDescriptor;
|
||||||
|
}
|
||||||
|
}
|
||||||
+45
@@ -0,0 +1,45 @@
|
|||||||
|
package uk.co.alt236.btlescan.ui.main.recyclerview.holder;
|
||||||
|
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import uk.co.alt236.btlescan.R;
|
||||||
|
import uk.co.alt236.btlescan.ui.common.recyclerview.BaseViewHolder;
|
||||||
|
import uk.co.alt236.btlescan.ui.main.recyclerview.model.LeDeviceItem;
|
||||||
|
|
||||||
|
public class LeDeviceHolder extends BaseViewHolder<LeDeviceItem> implements CommonDeviceHolder {
|
||||||
|
|
||||||
|
private final TextView deviceName;
|
||||||
|
private final TextView deviceAddress;
|
||||||
|
private final TextView deviceRssi;
|
||||||
|
private final TextView deviceLastUpdated;
|
||||||
|
|
||||||
|
public LeDeviceHolder(View itemView) {
|
||||||
|
super(itemView);
|
||||||
|
|
||||||
|
this.deviceAddress = (TextView) itemView.findViewById(R.id.device_address);
|
||||||
|
this.deviceName = (TextView) itemView.findViewById(R.id.device_name);
|
||||||
|
this.deviceRssi = (TextView) itemView.findViewById(R.id.device_rssi);
|
||||||
|
this.deviceLastUpdated = (TextView) itemView.findViewById(R.id.device_last_update);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TextView getDeviceName() {
|
||||||
|
return deviceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TextView getDeviceAddress() {
|
||||||
|
return deviceAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TextView getDeviceRssi() {
|
||||||
|
return deviceRssi;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TextView getDeviceLastUpdated() {
|
||||||
|
return deviceLastUpdated;
|
||||||
|
}
|
||||||
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
package uk.co.alt236.btlescan.ui.main.recyclerview.model;
|
||||||
|
|
||||||
|
import uk.co.alt236.bluetoothlelib.device.beacon.ibeacon.IBeaconDevice;
|
||||||
|
import uk.co.alt236.btlescan.ui.common.recyclerview.RecyclerViewItem;
|
||||||
|
|
||||||
|
public class IBeaconItem implements RecyclerViewItem {
|
||||||
|
|
||||||
|
private final IBeaconDevice device;
|
||||||
|
|
||||||
|
public IBeaconItem(final IBeaconDevice device) {
|
||||||
|
this.device = device;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IBeaconDevice getDevice() {
|
||||||
|
return device;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
package uk.co.alt236.btlescan.ui.main.recyclerview.model;
|
||||||
|
|
||||||
|
import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice;
|
||||||
|
import uk.co.alt236.btlescan.ui.common.recyclerview.RecyclerViewItem;
|
||||||
|
|
||||||
|
public class LeDeviceItem implements RecyclerViewItem {
|
||||||
|
|
||||||
|
private final BluetoothLeDevice device;
|
||||||
|
|
||||||
|
public LeDeviceItem(final BluetoothLeDevice device) {
|
||||||
|
this.device = device;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BluetoothLeDevice getDevice() {
|
||||||
|
return device;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -96,7 +96,7 @@
|
|||||||
android:layout_alignParentTop="true"
|
android:layout_alignParentTop="true"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<ListView
|
<android.support.v7.widget.RecyclerView
|
||||||
android:id="@android:id/list"
|
android:id="@android:id/list"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"/>
|
android:layout_height="match_parent"/>
|
||||||
|
|||||||
+4
-59
@@ -1,5 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?><!--
|
||||||
<!--
|
|
||||||
Copyright (C) 2013 The Android Open Source Project
|
Copyright (C) 2013 The Android Open Source Project
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@@ -17,6 +16,7 @@
|
|||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/selectableItemBackground"
|
||||||
android:gravity="top"
|
android:gravity="top"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
@@ -26,69 +26,14 @@
|
|||||||
android:layout_height="36dp"
|
android:layout_height="36dp"
|
||||||
android:paddingRight="5dp"
|
android:paddingRight="5dp"
|
||||||
android:paddingTop="5dp"
|
android:paddingTop="5dp"
|
||||||
android:src="@drawable/ic_bluetooth"/>
|
android:src="@drawable/ic_device_ibeacon"/>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<TextView
|
<include layout="@layout/viewpart_list_item_device_common"/>
|
||||||
android:id="@+id/device_name"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textSize="24sp"/>
|
|
||||||
|
|
||||||
<GridLayout
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:columnCount="2">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:paddingRight="5dp"
|
|
||||||
android:text="@string/label_mac"
|
|
||||||
android:textSize="12sp"
|
|
||||||
android:textStyle="bold"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/device_address"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textSize="12sp"
|
|
||||||
android:typeface="monospace"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:paddingRight="5dp"
|
|
||||||
android:text="@string/label_updated"
|
|
||||||
android:textSize="12sp"
|
|
||||||
android:textStyle="bold"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/device_last_update"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:paddingRight="5dp"
|
|
||||||
android:textSize="12sp"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:paddingRight="5dp"
|
|
||||||
android:text="@string/label_rssi"
|
|
||||||
android:textSize="12sp"
|
|
||||||
android:textStyle="bold"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/device_rssi"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:paddingRight="5dp"
|
|
||||||
android:textSize="12sp"/>
|
|
||||||
</GridLayout>
|
|
||||||
|
|
||||||
<GridLayout
|
<GridLayout
|
||||||
android:id="@+id/ibeacon_section"
|
android:id="@+id/ibeacon_section"
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/selectableItemBackground"
|
||||||
|
android:gravity="top"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/device_icon"
|
||||||
|
android:layout_width="36dp"
|
||||||
|
android:layout_height="36dp"
|
||||||
|
android:paddingRight="5dp"
|
||||||
|
android:paddingTop="5dp"
|
||||||
|
android:src="@drawable/ic_bluetooth"/>
|
||||||
|
|
||||||
|
|
||||||
|
<include layout="@layout/viewpart_list_item_device_common"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/device_name"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="24sp"/>
|
||||||
|
|
||||||
|
<GridLayout
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:columnCount="2">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingRight="5dp"
|
||||||
|
android:text="@string/label_mac"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:textStyle="bold"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/device_address"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:typeface="monospace"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingRight="5dp"
|
||||||
|
android:text="@string/label_updated"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:textStyle="bold"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/device_last_update"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingRight="5dp"
|
||||||
|
android:textSize="12sp"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingRight="5dp"
|
||||||
|
android:text="@string/label_rssi"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:textStyle="bold"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/device_rssi"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingRight="5dp"
|
||||||
|
android:textSize="12sp"/>
|
||||||
|
</GridLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
Reference in New Issue
Block a user