com.moto.miletus.application.DeviceListAdapter.java Source code

Java tutorial

Introduction

Here is the source code for com.moto.miletus.application.DeviceListAdapter.java

Source

/*
 * The MIT License (MIT)
 * Copyright (c) 2016 Gustavo Frederico Temple Pedrosa -- gustavof@motorola.com
 * <p>
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 * <p>
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * <p>
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

package com.moto.miletus.application;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.TextView;

import com.google.gson.Gson;
import com.moto.miletus.application.ble.neardevice.NearDeviceHolder;
import com.moto.miletus.application.utils.Strings;
import com.moto.miletus.wrappers.DeviceWrapper;

import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Adapter for the list of devices. For each {@link DeviceWrapper} added to this
 * adapter, a corresponding card will be created. When clicked, the card will launch a new
 * {@link DeviceActivity}.
 */
public class DeviceListAdapter extends RecyclerView.Adapter<DeviceListAdapter.ViewHolder> implements Filterable {

    private static final String TAG = DeviceListAdapter.class.getSimpleName();
    private static List<DeviceWrapper> dataSetOriginal;
    private static List<DeviceWrapper> dataSetFilter;

    /**
     * ViewHolder
     */
    class ViewHolder extends RecyclerView.ViewHolder {

        private final TextView name;
        private final TextView description;
        private final ImageView deviceImage;
        private final ImageView bleImage;

        ViewHolder(final View parentView, final TextView name, final TextView description,
                final ImageView deviceImage, final ImageView bleImage) {
            super(parentView);
            this.name = name;
            this.description = description;
            this.deviceImage = deviceImage;
            this.bleImage = bleImage;

            View.OnClickListener clickListener = new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    try {
                        final DeviceWrapper device = getDataSetFilter().get(getAdapterPosition());
                        Log.i(TAG, "Selecting device: " + device.getDevice().getId());

                        Intent intent = new Intent(v.getContext(), DeviceActivity.class);
                        intent.putExtra(Strings.EXTRA_KEY_DEVICE, device);
                        v.getContext().startActivity(intent);
                    } catch (ArrayIndexOutOfBoundsException e) {
                        Log.i(TAG, "Updating device: " + getAdapterPosition());
                    }
                }
            };

            parentView.setOnClickListener(clickListener);
        }
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        // create a new view
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.listitem_device, parent, false);
        return new ViewHolder(v, (TextView) v.findViewById(R.id.device_title),
                (TextView) v.findViewById(R.id.device_description), (ImageView) v.findViewById(R.id.device_picture),
                (ImageView) v.findViewById(R.id.ble_picture));
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        DeviceWrapper data = getDataSetFilter().get(position);
        holder.name.setText(data.getDevice().getName().replace(com.moto.miletus.utils.Strings.mSearchName, ""));

        if (data.getBleDevice() != null) {
            holder.deviceImage.setImageResource(R.drawable.ic_bluetooth_enabled);
            holder.description.setText(R.string.ble);
        } else if (data.getMqttInfo() != null) {
            holder.deviceImage.setImageResource(R.drawable.mqtt);
            holder.description.setText(R.string.cloud);
        } else if (data.getNsdServiceInfo() != null) {
            holder.deviceImage.setImageResource(R.drawable.ic_wifi_enabled);
            holder.description.setText(R.string.wifi);
        }

        if (compare(data) == 1) {
            holder.bleImage.setVisibility(View.INVISIBLE);
        } else {
            holder.bleImage.setVisibility(View.VISIBLE);
        }
    }

    /**
     * getDataSetOriginal
     *
     * @return List<DeviceWrapper>
     */
    public static synchronized List<DeviceWrapper> getDataSetOriginal() {
        if (dataSetOriginal == null) {
            dataSetOriginal = new ArrayList<>();
        }
        return dataSetOriginal;
    }

    /**
     * getDataSetFilter
     *
     * @return List<DeviceWrapper>
     */
    private static synchronized List<DeviceWrapper> getDataSetFilter() {
        if (dataSetFilter == null) {
            dataSetFilter = new ArrayList<>();
        }
        return dataSetFilter;
    }

    /**
     * setDataSetFilter
     *
     * @param dataSetFilter List<DeviceWrapper>
     */
    private static synchronized void setDataSetFilter(final List<DeviceWrapper> dataSetFilter) {
        DeviceListAdapter.dataSetFilter = dataSetFilter;
    }

    /**
     * compare
     *
     * @param device DeviceWrapper
     * @return int
     */
    private static int compare(final DeviceWrapper device) {
        if (NearDeviceHolder.getNearDevice() == null) {
            return 1;
        } else if (device.getBleDevice() != null && device.getBleDevice().getAddress()
                .equalsIgnoreCase(NearDeviceHolder.getNearDevice().getAddress())) {
            return -1;
        } else {
            return 1;
        }
    }

    @Override
    public int getItemCount() {
        return getDataSetFilter().size();
    }

    /**
     * clear
     */
    void clear() {
        Log.i(TAG, "Clear");

        if (!getDataSetOriginal().isEmpty()) {
            getDataSetOriginal().clear();
        }

        if (!getDataSetFilter().isEmpty()) {
            getDataSetFilter().clear();
        }

        notifyDataSetChanged();
    }

    /**
     * add
     *
     * @param device Device
     */
    void add(DeviceWrapper device) {
        getDataSetOriginal().add(device);
        getDataSetFilter().add(device);
        notifyItemInserted(getDataSetFilter().size() - 1);
    }

    /*
     * remove
     *
     * @param device Device
     */
    /*public void remove(final DeviceWrapper device) {
    for (Iterator<DeviceWrapper> it = getDataSetOriginal().iterator(); it.hasNext(); ) {
        DeviceWrapper pair = it.next();
        if (pair.getDevice().getId().equalsIgnoreCase(device.getDevice().getId())) {
            it.remove();
            notifyItemRemoved(getDataSetOriginal().size() - 1);
            break;
        }
    }
    }*/

    /**
     * contains
     *
     * @param device Device
     * @return Device
     */
    DeviceWrapper contains(final DeviceWrapper device) {
        for (final DeviceWrapper deviceWrapper : getDataSetFilter()) {
            if (device.getMqttInfo() != null && deviceWrapper.getMqttInfo() != null
                    && deviceWrapper.getDevice().getName().equalsIgnoreCase(device.getDevice().getName())) {
                return deviceWrapper;
            } else if (device.getMqttInfo() == null && deviceWrapper.getMqttInfo() == null
                    && deviceWrapper.getBleDevice() != null && device.getBleDevice() != null && deviceWrapper
                            .getBleDevice().getAddress().equalsIgnoreCase(device.getBleDevice().getAddress())) {
                return deviceWrapper;
            } else if (deviceWrapper.getDevice().getName().equalsIgnoreCase(device.getDevice().getName())
                    && deviceWrapper.getMqttInfo() == null && device.getMqttInfo() == null
                    && deviceWrapper.getBleDevice() == null && device.getBleDevice() == null) {
                return deviceWrapper;
            }
        }
        return null;
    }

    /**
     * getStringSet
     *
     * @return Set<String>
     */
    private Set<String> getStringSet() {
        final Set<String> devices = new HashSet<>();
        for (final DeviceWrapper device : getDataSetOriginal()) {
            device.setDate(new Date().getTime());
            String string = new Gson().toJson(device);
            devices.add(string);
        }
        return devices;
    }

    /**
     * storeDevices
     */
    void storeDevices(final Context context) {
        final SharedPreferences sp = context.getSharedPreferences(Strings.STORED_DEVICES, 0);
        final SharedPreferences.Editor editor = sp.edit();
        editor.clear();
        editor.putStringSet(Strings.STORED_DEVICES, getStringSet());
        editor.apply();
    }

    /**
     * loadDevices
     *
     * @param context Context
     * @return Set<String>
     */
    Set<String> loadDevices(final Context context) {
        final SharedPreferences sp = context.getSharedPreferences(Strings.STORED_DEVICES, 0);
        return sp.getStringSet(Strings.STORED_DEVICES, new HashSet<String>());
    }

    @Override
    public Filter getFilter() {
        return new Filter() {
            @Override
            protected FilterResults performFiltering(final CharSequence constraint) {
                final FilterResults results = new FilterResults();
                final List<DeviceWrapper> dataSetFilter = new ArrayList<>();

                if (constraint.length() == 0) {
                    dataSetFilter.addAll(getDataSetOriginal());
                } else {
                    for (final DeviceWrapper device : getDataSetOriginal()) {
                        if (StringUtils.containsIgnoreCase(device.getDevice().getName(), constraint.toString())) {
                            dataSetFilter.add(device);
                        }
                    }
                }

                results.values = dataSetFilter;
                results.count = dataSetFilter.size();
                return results;
            }

            @Override
            protected void publishResults(final CharSequence constraint, final FilterResults results) {
                if (results.values instanceof List) {
                    getDataSetFilter().clear();
                    setDataSetFilter((List<DeviceWrapper>) results.values);
                    sort();
                }
            }
        };
    }

    /**
     * sort
     */
    void sort() {
        if (getDataSetFilter().size() > 1) {
            Collections.sort(getDataSetFilter(), getComparator());
        }

        notifyDataSetChanged();
    }

    /**
     * getComparator
     *
     * @return Comparator
     */
    private Comparator<DeviceWrapper> getComparator() {
        return new Comparator<DeviceWrapper>() {
            @Override
            public int compare(DeviceWrapper pair1, DeviceWrapper pair2) {
                return DeviceListAdapter.compare(pair1);
            }
        };
    }

}