Setting user interface for android BLE scanning project - android

The app displays the scanned BLE devices. The app screen looks like:
PROBLEM
I want the screen to show a button when the app is opened and below the button should be the text box which will display scanned device.
The code snap is as below:
public class MainActivity extends ListActivity {
private static final String LOG_TAG = "BLEScan";
private LeDeviceListAdapter mLeDeviceListAdapter;
private Handler mHandler;
private boolean mScanning;
private BluetoothAdapter mBluetoothAdapter;
private static final int REQUEST_ENABLE_BT = 1;
private static final long SCAN_PERIOD = 10000;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
getActionBar().setTitle(R.string.title_devices);
mHandler = new Handler();
// Use this check to determine whether BLE is supported on the device. Then you can
// selectively disable BLE-related features.
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
finish();
}
// Initializes a Bluetooth adapter. For API level 18 and above, get a reference to
// BluetoothAdapter through BluetoothManager.
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
// Checks if Bluetooth is supported on the device.
if (mBluetoothAdapter == null) {
Toast.makeText(this, R.string.error_bluetooth_not_supported, Toast.LENGTH_SHORT).show();
finish();
return;
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
if (!mScanning) {
menu.findItem(R.id.menu_stop).setVisible(false);
menu.findItem(R.id.menu_scan).setVisible(true);
menu.findItem(R.id.menu_refresh).setActionView(null);
} else {
menu.findItem(R.id.menu_stop).setVisible(true);
menu.findItem(R.id.menu_scan).setVisible(false);
menu.findItem(R.id.menu_refresh).setActionView(
R.layout.actionbar_indeterminate_progress);
}
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_scan:
mLeDeviceListAdapter.clear();
scanLeDevice(true);
break;
case R.id.menu_stop:
scanLeDevice(false);
break;
}
return true;
}
#Override
protected void onResume() {
super.onResume();
// Ensures Bluetooth is enabled on the device. If Bluetooth is not currently enabled,
// fire an intent to display a dialog asking the user to grant permission to enable it.
if (!mBluetoothAdapter.isEnabled()) {
if (!mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
}
// Initializes list view adapter.
mLeDeviceListAdapter = new LeDeviceListAdapter();
setListAdapter(mLeDeviceListAdapter);
scanLeDevice(true);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// User chose not to enable Bluetooth.
if (requestCode == REQUEST_ENABLE_BT && resultCode == Activity.RESULT_CANCELED) {
finish();
return;
}
super.onActivityResult(requestCode, resultCode, data);
}
#Override
protected void onPause() {
super.onPause();
scanLeDevice(false);
mLeDeviceListAdapter.clear();
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
final BluetoothDevice device = mLeDeviceListAdapter.getDevice(position);
if (device == null) return;
}
private void scanLeDevice(final boolean enable) {
if (enable) {
// Stops scanning after a pre-defined scan period.
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
invalidateOptionsMenu();
}
}, SCAN_PERIOD);
mScanning = true;
mBluetoothAdapter.startLeScan(mLeScanCallback);
// int ble_value=TypeManufacturerData.class.;
} else {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
invalidateOptionsMenu();
}
static class ViewHolder {
TextView deviceName;
TextView deviceAd;
TextView deviceRssi;
TextView deviceAddress;
}
class DeviceHolder {
BluetoothDevice device;
String additionalData;
int rssi;
public DeviceHolder(BluetoothDevice device, String additionalData, int rssi) {
this.device = device;
this.additionalData = additionalData;
this.rssi = rssi;
}
}
// Adapter for holding devices found through scanning.
private class LeDeviceListAdapter extends BaseAdapter {
private ArrayList<BluetoothDevice> mLeDevices;
private ArrayList<DeviceHolder> mLeHolders;
private LayoutInflater mInflator;
public LeDeviceListAdapter() {
super();
mLeDevices = new ArrayList<BluetoothDevice>();
mLeHolders = new ArrayList<DeviceHolder>();
mInflator = MainActivity.this.getLayoutInflater();
}
public void addDevice(DeviceHolder deviceHolder) {
if(!mLeDevices.contains(deviceHolder.device)) {
mLeDevices.add(deviceHolder.device);
mLeHolders.add(deviceHolder);
}
}
public BluetoothDevice getDevice(int position) {
return mLeDevices.get(position);
}
public void clear() {
mLeDevices.clear();
mLeHolders.clear();
}
#Override
public int getCount() {
return mLeDevices.size();
}
#Override
public Object getItem(int i) {
return mLeDevices.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder viewHolder;
// General ListView optimization code.
if (view == null) {
view = mInflator.inflate(R.layout.listitem_device, null);
viewHolder = new ViewHolder();
viewHolder.deviceAddress = (TextView) view.findViewById(R.id.device_address);
viewHolder.deviceAd = (TextView) view.findViewById(R.id.device_ad);
viewHolder.deviceRssi = (TextView) view.findViewById(R.id.device_rssi);
viewHolder.deviceName = (TextView) view.findViewById(R.id.device_name);
view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) view.getTag();
}
BluetoothDevice device = mLeDevices.get(i);
DeviceHolder deviceHolder = mLeHolders.get(i);
final String deviceName = device.getName();
if (deviceName != null && deviceName.length() > 0)
viewHolder.deviceName.setText(deviceName);
else
viewHolder.deviceName.setText(R.string.unknown_device);
viewHolder.deviceAddress.setText(device.getAddress());
viewHolder.deviceAd.setText(deviceHolder.additionalData);
viewHolder.deviceRssi.setText("rssi: "+Integer.toString(deviceHolder.rssi));
return view;
}
}
// Device scan callback.
private BluetoothAdapter.LeScanCallback mLeScanCallback =
new BluetoothAdapter.LeScanCallback() {
#Override
public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
String deviceName = device.getName();
StringBuffer b = new StringBuffer();
int byteCtr = 0;
for( int i = 0 ; i < scanRecord.length ; ++i ) {
if( byteCtr > 0 )
b.append( " ");
b.append( Integer.toHexString( ((int)scanRecord[i]) & 0xFF));
++byteCtr;
if( byteCtr == 8 ) {
Log.d( LOG_TAG, new String( b ));
byteCtr = 0;
b = new StringBuffer();
}
}
ArrayList<AdElement> ads = AdParser.parseAdData(scanRecord);
StringBuffer sb = new StringBuffer();
for( int i = 0 ; i < ads.size() ; ++i ) {
AdElement e = ads.get(i);
if( i > 0 )
sb.append(" ; ");
sb.append(e.toString());
}
String additionalData = new String( sb );
Log.d(LOG_TAG, "additionalData: "+additionalData);
DeviceHolder deviceHolder = new DeviceHolder(device,additionalData,rssi);
runOnUiThread(new DeviceAddTask( deviceHolder ) );
}
};
class DeviceAddTask implements Runnable {
DeviceHolder deviceHolder;
public DeviceAddTask( DeviceHolder deviceHolder ) {
this.deviceHolder = deviceHolder;
}
public void run() {
mLeDeviceListAdapter.addDevice(deviceHolder);
mLeDeviceListAdapter.notifyDataSetChanged();
}
}
}
The xml layout is:
listitem_device.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#f44336"
>
<TextView android:id="#+id/device_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="24dp"/>
<TextView android:id="#+id/device_ad"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="12dp"/>
<TextView android:id="#+id/device_rssi"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="12dp"/>
<TextView android:id="#+id/device_address"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="12dp"/>
actionbar_indeterminate_progress.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="56dp"
android:minWidth="56dp"
android:background="#f48fb1">
<ProgressBar android:layout_width="32dp"
android:layout_height="32dp"
android:layout_gravity="center"/>

Related

show bluetooth Le devices on baseAdapter

I have created an adapter to show the scanned devices in my Custom Dialog. The custom dialog appears but even after none of the devices appears.
Whenever I check the logcat there are devices present from Bluetooth Le Scanner.
The code for the custom dialog is below
public class CustomDialog extends Dialog{
private LeDeviceListAdapter mLeDeviceListAdapter;
private BluetoothAdapter mBluetoothAdapter;
private boolean mScanning;
private Handler mHandler;
private AppCompatButton Scan;
private AppCompatButton Stop;
Context mContext;
TextView textStatus;
BluetoothLeScanner mLeScanner;
private static final int REQUEST_ENABLE_BT = 1;
// Stops scanning after 10 seconds.
private static final long SCAN_PERIOD = 10000;
ProgressBar contentLoadingProgressBar;
public CustomDialog(#NonNull Context context) {
super(context);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.custom_dialog);
contentLoadingProgressBar = (ProgressBar) findViewById(R.id.contentLoading);
contentLoadingProgressBar.setVisibility(View.GONE);
textStatus = findViewById(R.id.textStatus);
textStatus.setVisibility(View.GONE);
Scan = (AppCompatButton) findViewById(R.id.scanButton);
Scan.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
contentLoadingProgressBar.setVisibility(View.VISIBLE);
Scan.setVisibility(View.GONE);
textStatus.setVisibility(View.VISIBLE);
BlueteethManager.with(getContext()).scanForPeripherals(10000, blueteethDevices -> {
for (BlueteethDevice device : blueteethDevices) {
if (!TextUtils.isEmpty(device.getBluetoothDevice().getName())) {
mLeDeviceListAdapter.addDevice(device);
mLeDeviceListAdapter.notifyDataSetChanged();
Timber.d("%s - %s", device.getName(), device.getMacAddress());
}
}
contentLoadingProgressBar.setVisibility(View.GONE);
textStatus.setVisibility(View.GONE);
Scan.setVisibility(View.VISIBLE);
});
}
});
final BluetoothManager bluetoothManager =
(BluetoothManager) getContext().getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
}
// Adapter for holding devices found through scanning.
private class LeDeviceListAdapter extends BaseAdapter {
private ArrayList<BlueteethDevice> mLeDevices;
private LayoutInflater mInflator;
public LeDeviceListAdapter() {
super();
mLeDevices = new ArrayList<BlueteethDevice>();
mInflator = getLayoutInflater();
}
public void addDevice(BlueteethDevice device) {
if (!mLeDevices.contains(device)) {
mLeDevices.add(device);
}
}
public void clear() {
mLeDevices.clear();
}
#Override
public int getCount() {
return mLeDevices.size();
}
#Override
public Object getItem(int i) {
return mLeDevices.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
CustomDialog.viewHolder viewHolder;
// General ListView optimization code.
if (view == null) {
view = mInflator.inflate(R.layout.custom_dialog, null);
viewHolder = new CustomDialog.viewHolder();
viewHolder.cardDevice=view.findViewById(R.id.cardDevice);
viewHolder.deviceAddress = (TextView) view.findViewById(R.id.device_address);
viewHolder.deviceName = (TextView) view.findViewById(R.id.device_name);
view.setTag(viewHolder);
} else {
viewHolder = (CustomDialog.viewHolder) view.getTag();
}
BlueteethDevice device = mLeDevices.get(i);
final String deviceName = device.getName();
if (deviceName != null && deviceName.length() > 0)
viewHolder.deviceName.setText(deviceName);
else
viewHolder.deviceName.setText("Unknown Device");
viewHolder.deviceAddress.setText(device.getMacAddress());
viewHolder.deviceAddress.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
device.connect(true, isConnected -> {
Timber.d("Is the peripheral connected? %s", Boolean.toString(isConnected));
if (isConnected){
Toast.makeText(mContext, "BLE device Connected", Toast.LENGTH_SHORT).show();
textStatus.setText("Connected");
textStatus.setVisibility(View.VISIBLE);
Scan.setVisibility(View.GONE);
contentLoadingProgressBar.setVisibility(View.GONE);
}
else {
Toast.makeText(mContext, "Failed to connect", Toast.LENGTH_SHORT).show();
}
});
}
});
return view;
}
}
static class viewHolder {
TextView deviceName;
TextView deviceAddress;
CardView cardDevice;
}
}
I am using a third party library for scanning devices. It works correctly though but didn't get any of the device name or address appears on the custom dialog. does the Layout Inflator cause problems to me or what.

Recyclerview - Clicking on results displayed by search opens incorrect item

I'm having a recyclerview to display a list of notes from room database. I've also added search functionality. Currently, I'm having 4 notes in MainActivity (this activity displays notes). On searching, if I get resultant list having more than 2 notes, on clicking them it displays correct notes.But, if resultant has 1 or 2 notes, it always displays the first 2 in list, not the notes filtered by search.
Here's my code:
Model class Note:
#Entity(tableName = TABLE_NAME)
public class Note implements Serializable{
#Nullable
private int Color;
#PrimaryKey(autoGenerate = true)
private long id;
/** Not-null value. */
private String Desc;
private String Time;
// KEEP FIELDS - put your custom fields here
// KEEP FIELDS END
public Note() {
}
public Note(String Desc, String Time) {
this.Desc = Desc;
this.Time = Time;
}
public int getColor() {
return Color;
}
public void setColor(int color) {
Color = color;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
/** Not-null value. */
public String getDesc() {
return Desc;
}
/** Not-null value; ensure this value is available before it is saved to the database. */
public void setDesc(String Desc) {
this.Desc = Desc;
}
public String getTime() {
return Time;
}
public void setTime(String Time) {
this.Time = Time;
}
NotesAdapter:
public class NotesAdapter extends RecyclerView.Adapter<NotesAdapter.MyViewHolder> {
public List<Note> list;
private Context context;
private List<Note> filteredList = new ArrayList<>();
private ClickListener clickListener;
public List<Note> selectednotes_list = new ArrayList<>();
private String TAG = NotesAdapter.class.getSimpleName();
class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView mNoteDesc;
public TextView mNoteTime;
public RelativeLayout mcontainer;
public MyViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
mNoteTime = itemView.findViewById(R.id.note_time);
mNoteDesc = itemView.findViewById(R.id.note_desc);
mcontainer = itemView.findViewById(R.id.note_container);
}
#Override
public void onClick(View v) {
Log.d(TAG, "onClick: ");
clickListener.onClick(v,this.getLayoutPosition());
}
/*
#Override
public void onClick(View v) {
Log.d(TAG, "onClick: ");
clickListener.onClick(v,getLayoutPosition());
//clickListener.onClick(filteredList.get(getAdapterPosition()));
}
*/
}
public NotesAdapter(List<Note> list, Context context,List<Note> selectednotes_list) {
this.list = list;
this.filteredList = list;
this.context = context;
this.selectednotes_list = selectednotes_list;
this.clickListener = (ClickListener) context;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.noteview,null,false);
return new MyViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int position) {
holder.mNoteTime.setText(list.get(position).getTime());
holder.mcontainer.setBackgroundColor(Utils.getRandomMaterialColor(context, "50to300"));
holder.mNoteDesc.setText(list.get(position).getDesc());
// Change background color on select
if (selectednotes_list.size() > 0) {
if (selectednotes_list.contains(list.get(position)))
holder.mcontainer.setBackgroundColor(ContextCompat.getColor(context, R.color.colorSecondary));
}
}
#Override
public int getItemCount() {
return list.size();
}
public void filterList(List<Note> filter) {
this.list = filter;
notifyDataSetChanged();
}
}
MainActivity:
public class MainActivity extends AppCompatActivity implements ClickListener{
private StaggeredGridLayoutManager gridLayoutManager;
private RecyclerView recyclerView;
private List<Note> noteList, multiSelectList;
public NotesAdapter notesAdapter;
private Notedatabase notedatabase;
private String TAG = MainActivity.class.getSimpleName();
private FloatingActionButton maddbtn;
private int position;
private SearchView mSearchView;
private boolean isMultiSelect = false;
private Menu context_menu;
private ActionMode mActionMode;
private CoordinatorLayout mCoordinatorLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
displayList();
/*
notesList.addAll(noteList);
List<Note> notesList = getNotes();
notesAdapter = new NotesAdapter(notesList,MainActivity.this);
recyclerView.setAdapter(notesAdapter);
*/
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu,menu);
// Searchable config with searchview
SearchManager manager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
mSearchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
mSearchView.setSearchableInfo(manager.getSearchableInfo(getComponentName()));
mSearchView.setMaxWidth(Integer.MAX_VALUE);
// Set Listener
mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
// filter when query is submitted
Log.d(TAG, "onQueryTextSubmit: " + query);
notesAdapter.filterList(filter(query,noteList));
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
// filter progressively as query changes
Log.d(TAG, "onQueryTextChange: " + newText);
notesAdapter.filterList(filter(newText,noteList));
return false;
}
});
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId() == R.id.action_search) {
// search action
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onBackPressed() {
// close searchview
if(!mSearchView.isIconified()) {
mSearchView.setIconified(true);
return;
}
super.onBackPressed();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == REQUEST_CODE) {
if (resultCode == 1) {
Log.d(TAG, "Request code is 1");
noteList.add((Note) data.getSerializableExtra("note"));
notesAdapter.notifyDataSetChanged();
}
else if(resultCode == 2) {
Log.d(TAG, "Request code 2, update return");
noteList.set(position, (Note) data.getSerializableExtra("note"));
notesAdapter.notifyDataSetChanged();
}
else if(resultCode == 3) {
Log.d(TAG, "Request code 3, delete return");
Log.d(TAG, "Deleting this from list:" + (Note) data.getSerializableExtra("note"));
noteList.remove(MainActivity.this.position);
notesAdapter.notifyItemRemoved(MainActivity.this.position);
}
}
}
private void displayList() {
notedatabase = Notedatabase.getInstance(MainActivity.this);
new RetrieveTask(this).execute();
}
private void initViews() {
recyclerView = findViewById(R.id.recyclerview);
gridLayoutManager = new StaggeredGridLayoutManager(2,1);
mCoordinatorLayout = findViewById(R.id.coordinatorLayout);
recyclerView.setLayoutManager(gridLayoutManager);
noteList = new ArrayList<>();
multiSelectList = new ArrayList<>();
notesAdapter = new NotesAdapter(noteList,MainActivity.this,multiSelectList);
recyclerView.setAdapter(notesAdapter);
maddbtn = findViewById(R.id.add_fab);
maddbtn.setOnClickListener(v -> {
Intent intent = new Intent(MainActivity.this,NoteActivity.class);
startActivityForResult(intent,REQUEST_CODE);
});
}
#Override
public void onClick(View view, int pos) {
/*
Log.d(TAG, "Recylerview item onClick: ");
MainActivity.this.position = pos;
Intent intent = new Intent(MainActivity.this,NoteActivity.class);
intent.putExtra("note",noteList.get(position));
Log.d(TAG, "list.get(position): " + noteList.get(pos).getDesc());
startActivityForResult(intent,REQUEST_CODE);
*/
}
#Override
public void onClick(Note note) {
/*
Log.d(TAG, "onClick with args as note1");
Intent intent = new Intent(MainActivity.this,NoteActivity.class);
intent.putExtra("note",note);
startActivityForResult(intent,REQUEST_CODE);*/
}
#Override
public void onLongClick(View view, int pos) {
/* Log.d(TAG, "onLongClick ");
if(!isMultiSelect) {
multiSelectList = new ArrayList<Note>();
isMultiSelect = true;
if(mActionMode == null) {
mActionMode = startActionMode(mActionModeCallback);
}
}
multi_select(pos);*/
}
private void multi_select(int pos) {
if(mActionMode != null) {
if(multiSelectList.contains(noteList.get(pos))) {
Log.d(TAG, "multi_select removed: " + multiSelectList.contains(noteList.get(pos)));
multiSelectList.remove(noteList.get(pos));
}
else {
Log.d(TAG, "multi_select added: " + multiSelectList.contains(noteList.get(pos)));
multiSelectList.add(noteList.get(pos));
}
if(multiSelectList.size() > 0) mActionMode.setTitle("" + multiSelectList.size() + " selected");
else mActionMode.setTitle("");
refreshAdapter();
}
}
private void refreshAdapter() {
notesAdapter.selectednotes_list = multiSelectList;
notesAdapter.list = noteList;
notesAdapter.notifyDataSetChanged();
}
class RetrieveTask extends AsyncTask<Void,Void,List<Note>>{
private WeakReference<MainActivity> weakReference;
public RetrieveTask(MainActivity mainActivity) {
weakReference = new WeakReference<>(mainActivity);
}
#Override
protected List<Note> doInBackground(Void... voids) {
if(weakReference.get()!=null)
return weakReference.get().notedatabase.getNoteDao().getNotes();
else
return null;
}
#Override
protected void onPostExecute(List<Note> notes) {
if(notes!=null & notes.size()>0) {
weakReference.get().noteList = notes;
//weakReference.get().noteList.addAll(weakReference.get().getNotes());
Log.d(TAG, "Result: " + notes);
weakReference.get().notesAdapter = new NotesAdapter(notes,weakReference.get(),multiSelectList);
/*
// Randomly set note background
for(Note n:notes) {
n.setColor(getRandomMaterialColor(MainActivity.this,"500"));
}
*/ weakReference.get().recyclerView.addOnItemTouchListener(new RecyclerTouchListener(recyclerView, getApplicationContext(), new ClickListener() {
#Override
public void onClick(View view, int pos) {
if (isMultiSelect)
multi_select(pos);
else {
Log.d(TAG, "Recylerview item onClick: ");
MainActivity.this.position = pos;
Intent intent = new Intent(MainActivity.this, NoteActivity.class);
intent.putExtra("note", noteList.get(position));
Log.d(TAG, "list.get(position): " + weakReference.get().noteList.get(position).getDesc());
startActivityForResult(intent, REQUEST_CODE);
}
}
#Override
public void onClick(Note note) {
Log.d(TAG, "onClick with args as note");
Intent intent = new Intent(MainActivity.this, NoteActivity.class);
intent.putExtra("note", note);
startActivityForResult(intent, REQUEST_CODE);
}
#Override
public void onLongClick(View view, int pos) {
Log.d(TAG, "onLongClick ");
if(!isMultiSelect) {
multiSelectList = new ArrayList<Note>();
isMultiSelect = true;
if(mActionMode == null) {
mActionMode = startActionMode(mActionModeCallback);
}
}
multi_select(pos);
}
}));
weakReference.get().recyclerView.setAdapter(weakReference.get().notesAdapter);
weakReference.get().notesAdapter.notifyDataSetChanged();
}
else{
displayErrorMsg();
}
}
}
private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
//Prepare the menu
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.contextual_action,menu);
context_menu = menu;
return true;
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
//mode.getCustomView().setBackgroundColor(getApplicationContext().getResources().getColor(android.R.color.white));
return false;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.action_delete:
// display alert dialog
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setMessage("Delete " + multiSelectList.size() + " notes?");
builder.setCancelable(true);
builder.setPositiveButton(R.string.alert_yes,(dialog, which) -> {
// Deleting notes
for (int i = 0; i < multiSelectList.size(); i++) {
Log.d(TAG, "Deleting: " + multiSelectList.get(i));
notedatabase.getNoteDao().deleteNotes(multiSelectList.get(i));
noteList.remove(multiSelectList.get(i));
}
// Display Snackbar
displaySnackbar(mCoordinatorLayout,R.string.delete_success);
dialog.cancel();
// Refresh adapter
refreshAdapter();
// dismiss the contextual action bar
if(mActionMode!=null) mActionMode.finish();
});
builder.setNegativeButton(R.string.alert_no,(dialog, which) -> {
dialog.cancel();
if(mActionMode!=null) mActionMode.finish();
});
builder.setOnCancelListener(dialog1 -> {
Log.d(TAG, "onCancelListener: ");
if(mActionMode!=null) mActionMode.finish();
});
AlertDialog dialog = builder.create();
dialog.show();
return true;
default:
return false;
}
}
#Override
public void onDestroyActionMode(ActionMode mode) {
mActionMode = null;
isMultiSelect = false;
multiSelectList = new ArrayList<Note>();
refreshAdapter();
}
};
#Override
protected void onDestroy() {
notedatabase.cleanUp();
super.onDestroy();
}
private void displayErrorMsg() {
Toast.makeText(MainActivity.this,R.string.failure_display,Toast.LENGTH_SHORT).show();
}
}
Any help is widely appreciated!!
Please! Badly stuck here
Found it out!
I was not storing the result of filter, instead I was directly calling it in filterList.
noteList = filter(newText, noteList);
notesAdapter.filterList(noteList);
The above lines did it for me!

RecyclerView shows nothing

I'm new in this android world. I'm currently working on android project i.e., music player but i got stopped at one point since my recycler view doesn't display anything which is supposed to be a list of songs.
I even checked my logcat but cannot figured out whether the data is binding or not.Any kind of help will be grateful.
SongListAdapter.java
public class SongListAdapter extends RecyclerView.Adapter<SongListAdapter.MyViewHolder> {
ArrayList<SongDetailsJDO> mSongDetailsJDOs;
LayoutInflater mLayoutInflater;
Context mContext;
private static final String TAG = "SongListAdapter";
private boolean mIsSongPlaying = false;
private String mCurrentSongId = "-1";
public SongListAdapter(Context context, ArrayList<SongDetailsJDO> pSongDetailsJDOs) {
mContext = context;
mLayoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mSongDetailsJDOs = pSongDetailsJDOs;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View lView = mLayoutInflater.inflate(R.layout.recycler_view_item, parent, false);
return new MyViewHolder(lView);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
Uri lUri = null;
if (mSongDetailsJDOs.get(position).getAlbumId() != null && !mSongDetailsJDOs.get(position).getAlbumId().equals("")) {
lUri = ContentUris.withAppendedId(Uri.parse("content://media/external/audio/albumart"), Long.parseLong(mSongDetailsJDOs.get(position).getAlbumId()));
Picasso.with(mContext).load(lUri).resize(100, 100).placeholder(R.drawable.placeholder).into(holder.albumImageIV);
} else
holder.albumImageIV.setImageResource(R.drawable.placeholder);
String lTrackName = mSongDetailsJDOs.get(position).getTitle();
if (lTrackName != null)
holder.trackNameTV.setText(lTrackName.trim());
else
holder.trackNameTV.setText("<Unknown>");
String lAlbumName = mSongDetailsJDOs.get(position).getAlbumName();
if (lAlbumName != null)
holder.albumAndArtistDetailsTV.setText(lAlbumName.trim());
else
holder.albumAndArtistDetailsTV.setText("<Unknown>");
if (mSongDetailsJDOs.get(position).getFavouriteStatus() == 1)
holder.favouriteIV.setImageResource(R.drawable.fav);
else
holder.favouriteIV.setImageResource(R.drawable.fav_u);
// TODO: #holder.animationDrawable use it change Visibility and start (Animation)
if (mIsSongPlaying && mSongDetailsJDOs.get(position).getSongId().equals(mCurrentSongId)) {
holder.eqIv.setVisibility(View.VISIBLE);
holder.animationDrawable = (AnimationDrawable) holder.eqIv.getBackground();
holder.animationDrawable.start();
} else {
holder.eqIv.setVisibility(View.INVISIBLE);
}
}
#Override
public int getItemCount() {
if (mSongDetailsJDOs != null)
return mSongDetailsJDOs.size();
else
return 0;
}
/**
* Called when data is being updated in DB
*/
public void favChanged(int pPosition, int pFavStatus) {
mSongDetailsJDOs.get(pPosition).setFavouriteStatus(pFavStatus);
notifyItemChanged(pPosition);
}
/**
* View Holder class for Rec view
*/
class MyViewHolder extends RecyclerView.ViewHolder {
ImageView albumImageIV;
TextView trackNameTV;
TextView albumAndArtistDetailsTV;
ImageView favouriteIV;
ImageView eqIv;
AnimationDrawable animationDrawable;
MyViewHolder(View itemView) {
super(itemView);
albumImageIV = (ImageView) itemView.findViewById(R.id.album_artwork_iv);
trackNameTV = (TextView) itemView.findViewById(R.id.title_name_tv);
albumAndArtistDetailsTV = (TextView) itemView.findViewById(R.id.artist_author_name_tv);
favouriteIV = (ImageView) itemView.findViewById(R.id.fav_iv);
eqIv = (ImageView) itemView.findViewById(R.id.eq_iv);
}
}
/**
* Swap the data with the new JDO list
*
* #param pSongDetailsJDOs
*/
public void swapData(ArrayList<SongDetailsJDO> pSongDetailsJDOs) {
mSongDetailsJDOs = pSongDetailsJDOs;
notifyDataSetChanged();
}
/**
* Returns the list of currently loaded JDO's
* #return
*/
public List<SongDetailsJDO> getData() {
return mSongDetailsJDOs;
}
/**
* Gets the #{#link SongDetailsJDO} object at the specified position
* #param pPosition
* #return the {#link SongDetailsJDO} object
*/
public SongDetailsJDO getItemAtPosition(int pPosition) {
return mSongDetailsJDOs.get(pPosition);
}
/**
* Update Song Play status
* #param pStatus the status weather is playing or not
* #param lSongId the song id the playing song
*/
public void updateSongPlayStatus(boolean pStatus, String lSongId) {
mIsSongPlaying = pStatus;
mCurrentSongId = lSongId;
notifyDataSetChanged();
}
}
SongListActivity.java
public class SongsListActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor>, SharedPreferences.OnSharedPreferenceChangeListener {
private RecyclerView mRecyclerView;
private SongListAdapter mAdapter;
private ArrayList<SongDetailsJDO> mSongDetailsJDOs;
private TextView mNoSongTV;
private static final int LOADER_ID = 101;
private int REQUEST_CODE = 102;
private static final String TAG = "SongsListActivity";
private SharedPreferences mSharedPreferences;
private SharedPreferences.Editor mPrefEditor;
private SharedPreferences.OnSharedPreferenceChangeListener mOnSharedPreferenceChangeListener;
private FirebaseAnalytics mFirebaseAnalytics;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.activity_main);
mRecyclerView = (RecyclerView) findViewById(R.id.rec_view);
mRecyclerView.setLayoutManager(new LinearLayoutManager(SongsListActivity.this));
mNoSongTV = (TextView) findViewById(R.id.no_song_tv);
mSongDetailsJDOs = new ArrayList<>();
mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
mPrefEditor = mSharedPreferences.edit();
mSharedPreferences.registerOnSharedPreferenceChangeListener(this);
FirebaseApp.initializeApp(this);
mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);
loadData();
}
private void loadData() {
FirebaseCrash.report(new Exception("OMG An Exception"));
boolean lIsAppLoadingFirstTime = mSharedPreferences.getBoolean(getString(R.string.is_app_loading_first_time), true);
if (lIsAppLoadingFirstTime) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 0);
} else {
mPrefEditor.putBoolean(getString(R.string.is_app_loading_first_time), false);
mPrefEditor.apply();
new LoadDataToDbBackground().execute();
// TODO: Create Loader here
}
} else {
loadDataToRecyclerView();
if (mSharedPreferences.getBoolean(getString(R.string.is_song_playing), false)) {
// TODO: Create Loader here
SongDetailsJDO lJDO = getSongJDO(mSharedPreferences.getString(getString(R.string.song_id), ""));
startActivityForResult(new Intent(SongsListActivity.this, PlayerActivity.class)
.putExtra(getString(R.string.song_jdo), lJDO), REQUEST_CODE);
}
}
}
private class LoadDataToDbBackground extends AsyncTask<Void, Integer, Void> {
ProgressDialog mProgressDialog;
#Override
protected void onPreExecute() {
mProgressDialog = new ProgressDialog(SongsListActivity.this);
mProgressDialog.setMessage("Please Wait");
mProgressDialog.setTitle("Loading");
mProgressDialog.show();
super.onPreExecute();
}
#Override
protected void onPostExecute(Void aVoid) {
mProgressDialog.dismiss();
super.onPostExecute(aVoid);
}
#Override
protected Void doInBackground(Void... params) {
CommonHelper lHelper = new CommonHelper();
lHelper.loadSongToDB(SongsListActivity.this);
runOnUiThread(new Runnable() {
#Override
public void run() {
loadDataToRecyclerView();
}
});
return null;
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if (requestCode == 0) {
boolean lGranted = true;
for (int lResult : grantResults) {
if (lResult == PackageManager.PERMISSION_DENIED)
lGranted = false;
}
if (lGranted)
loadData();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE) {
if (data != null && data.getExtras() != null && resultCode == PlayerActivity.RESULT_CODE) {
//if data changed reload the recyclerView
if (data.getBooleanExtra(getString(R.string.is_data_changed), false)) {
mSongDetailsJDOs = new SongDetailTable(this).getAllSongs();
mAdapter.swapData(mSongDetailsJDOs);
}
}
}
// updateCurrentSongIndication();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater lMenuInflater = getMenuInflater();
lMenuInflater.inflate(R.menu.menu_song_list, menu);
SearchManager lSearchManager = (SearchManager) getSystemService(SEARCH_SERVICE);
SearchView lSearchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
lSearchView.setSearchableInfo(lSearchManager.getSearchableInfo(getComponentName()));
lSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
filterRecView(newText);
return true;
}
});
return true;
}
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return new CursorLoader(this, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, MediaStore.Audio.Media.TITLE + " ASC");
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
ArrayList<SongDetailsJDO> lSongDetailsNew = new ArrayList<>();
if (data.moveToFirst()) {
do {
lSongDetailsNew.add(new SongDetailsJDO(data.getString(data.getColumnIndex(MediaStore.Audio.Media.TITLE)),
data.getString(data.getColumnIndex(MediaStore.Audio.Media.ALBUM)),
data.getString(data.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID)),
data.getString(data.getColumnIndex(MediaStore.Audio.Media._ID)),
data.getInt(data.getColumnIndex(MediaStore.Audio.Media.DURATION)), 0));
} while (data.moveToNext());
}
compareDataAndMakeChangesToDB(lSongDetailsNew);
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
}
#Override
protected void onResume() {
super.onResume();
}
#Override
public void onWindowFocusChanged(boolean hasFocus) {
Log.d(TAG, "onWindowFocusChanged: ");
updateCurrentSongIndication();
}
private void updateCurrentSongIndication() {
if (mSharedPreferences.getBoolean(getString(R.string.is_song_playing), false)) {
mAdapter.updateSongPlayStatus(true, mSharedPreferences.getString(getString(R.string.song_id), ""));
mRecyclerView.smoothScrollToPosition(getPositionOfSongId(mSharedPreferences.getString(getString(R.string.song_id), "")));
} else {
if(mAdapter!=null)
mAdapter.updateSongPlayStatus(false, "-1");
}
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
updateCurrentSongIndication();
}
private void compareDataAndMakeChangesToDB(ArrayList<SongDetailsJDO> pSongDetailsNew) {
Log.d(TAG, "compareDataAndMakeChangesToDB: Called ============");
ArrayList<String> lSongIdsToBeDeleted = new ArrayList<>();
for (SongDetailsJDO lSongDetailsJDO : mSongDetailsJDOs) {
lSongIdsToBeDeleted.add(lSongDetailsJDO.getSongId());
}
ArrayList<SongDetailsJDO> lNewSongsToBeAdded = new ArrayList<>();
for (SongDetailsJDO lSongDetailsJDO : pSongDetailsNew) {
if (lSongIdsToBeDeleted.contains(lSongDetailsJDO.getSongId())) {
lSongIdsToBeDeleted.remove(lSongDetailsJDO.getSongId());
} else
lNewSongsToBeAdded.add(lSongDetailsJDO);
}
if (lSongIdsToBeDeleted.size() > 0 || lNewSongsToBeAdded.size() > 0) {
SongDetailTable lSongDetailTable = new SongDetailTable(this);
lSongDetailTable.removeSongsForIds(lSongIdsToBeDeleted);
lSongDetailTable.insertSongs(lNewSongsToBeAdded);
loadDataToRecyclerView();
//
// SongPlayerService lSongPlayerService = SongPlayerService.getRunningInstance();
// if (lSongPlayerService != null)
// lSongPlayerService.dataChanged();
}
}
public void onFavClick(View pView) {
//Firebase Logging
Bundle lBundle = new Bundle();
lBundle.putString(FirebaseAnalytics.Param.ITEM_CATEGORY,"Favourite Clicked");
mFirebaseAnalytics.logEvent(FirebaseAnalytics.Event.VIEW_ITEM,lBundle);
int lPosition = mRecyclerView.getChildLayoutPosition((View) pView.getParent());
SongDetailsJDO lSongDetailsJDO = mAdapter.getItemAtPosition(lPosition);
String lSongId = lSongDetailsJDO.getSongId();
SongDetailTable lSongDetailTable = new SongDetailTable(this);
int lNewFavStatus = lSongDetailsJDO.getFavouriteStatus() == 0 ? 1 : 0;
lSongDetailTable.setFavouriteStatus(lSongId, lNewFavStatus);
mAdapter.favChanged(lPosition, lNewFavStatus);
SongPlayerService mSongPlayerService = SongPlayerService.getRunningInstance();
if (mSongPlayerService != null)
mSongPlayerService.favChanged(lPosition, lNewFavStatus);
}
public void onRowClick(View pView) {
int lPosition = mRecyclerView.getChildLayoutPosition(pView);
SongDetailsJDO lJDO = mAdapter.getItemAtPosition(lPosition);
startActivityForResult(new Intent(SongsListActivity.this, PlayerActivity.class)
.putExtra(getString(R.string.song_jdo), lJDO), REQUEST_CODE);
overridePendingTransition(R.anim.from_right, R.anim.scale_down);
}
private SongDetailsJDO getSongJDO(String pSongId) {
SongDetailsJDO lJDO = null;
for (SongDetailsJDO lSongDetailsJDO : mSongDetailsJDOs) {
if (lSongDetailsJDO.getSongId().equals(pSongId)) {
lJDO = lSongDetailsJDO;
break;
}
}
return lJDO;
}
private void filterRecView(String pText) {
if (pText != null) {
if (pText.equals("")) {
mAdapter.swapData(mSongDetailsJDOs);
toggleVisibilityForNoResult(mSongDetailsJDOs.size(), pText);
} else {
ArrayList<SongDetailsJDO> lSongDetailsJDOs = new ArrayList<>();
pText = pText.toLowerCase();
for (SongDetailsJDO lDetailsJDO : mSongDetailsJDOs) {
if (lDetailsJDO.getTitle().toLowerCase().contains(pText) || lDetailsJDO.getAlbumName() != null && lDetailsJDO.getAlbumName().toLowerCase().contains(pText))
lSongDetailsJDOs.add(lDetailsJDO);
}
toggleVisibilityForNoResult(lSongDetailsJDOs.size(), pText);
mAdapter.swapData(lSongDetailsJDOs);
}
}
}
public void toggleVisibilityForNoResult(int pNumberOfSongs, String query) {
if (pNumberOfSongs == 0) {
mNoSongTV.setVisibility(View.VISIBLE);
mNoSongTV.setText(getString(R.string.nosong) + " " + query);
} else
mNoSongTV.setVisibility(View.INVISIBLE);
}
public void loadDataToRecyclerView() {
//Loading data to RecyclerView
mSongDetailsJDOs = new SongDetailTable(this).getAllSongs();
mAdapter = new SongListAdapter(SongsListActivity.this, mSongDetailsJDOs);
mRecyclerView.setAdapter(mAdapter);
}
public int getPositionOfSongId(String pSongId) {
int lPostion = -1;
for (int i = 0; i < mSongDetailsJDOs.size(); i++) {
if (mSongDetailsJDOs.get(i).getSongId().equals(pSongId)) {
lPostion = i;
break;
}
}
return lPostion;
}
}
Looking at your problem its not possible to tell exact cause of an issue.
But still i will give some hint over issue.
Check your code inside
mSongDetailsJDOs.size(); what is size of the list, it should be > 0. If not then check inside your activity how you are passing list.
#Override
public int getItemCount() {
if (mSongDetailsJDOs != null)
return mSongDetailsJDOs.size();
else
return 0;
}
If above list is > 0 then check it inside onBindViewHolder() that you are getting position one by one and try to render one item a time.
let me know if above works for you.

How to send character from android phone to arduino through Bluetooth?

Currently I am using an Arduino nano to receive data and transmit it to android phone through Bluetooth. I want to set some button on my smart phone, and then after I pressed it, it will transmit a character to arduino.
I have tested my arduino that if I give certain command in serial monitor , it will give me the analog read signal.
I wanna ask how can I transmit a character(like "E") from my phone to arduino?
The following code is associated to bluetooth connection. What else can I add to achieve my goal?
Bluetooth code in arduino
public class Homescreen extends Activity {
private Button mBtnSearch;
private Button mBtnConnect;
private ListView mLstDevices;
private BluetoothAdapter mBTAdapter;
private static final int BT_ENABLE_REQUEST = 10; // This is the code we use for BT Enable
private static final int SETTINGS = 20;
private UUID mDeviceUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); // Standard SPP UUID
// (http://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#createInsecureRfcommSocketToServiceRecord%28java.util.UUID%29)
private int mBufferSize = 50000; //Default
public static final String DEVICE_EXTRA = "com.blueserial.SOCKET";
public static final String DEVICE_UUID = "com.blueserial.uuid";
private static final String DEVICE_LIST = "com.blueserial.devicelist";
private static final String DEVICE_LIST_SELECTED = "com.blueserial.devicelistselected";
public static final String BUFFER_SIZE = "com.blueserial.buffersize";
private static final String TAG = "BlueTest5-Homescreen";
public String isECG;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_homescreen);
ActivityHelper.initialize(this); //This is to ensure that the rotation persists across activities and not just this one
Log.d(TAG, "Created");
Intent i = getIntent();
if (i.hasExtra("isECG")){
isECG = i.getStringExtra("isECG");
}
TextView tv1 = (TextView)findViewById(R.id.tv1);
tv1.setText(isECG);
mBtnSearch = (Button) findViewById(R.id.btnSearch);
mBtnConnect = (Button) findViewById(R.id.btnConnect);
mLstDevices = (ListView) findViewById(R.id.lstDevices);
Button btBack = (Button) findViewById(R.id.btBack);
btBack.setOnClickListener(new Button.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setClass(Homescreen.this, StartScreen.class);
startActivity(intent);
}
});
/*
*Check if there is a savedInstanceState. If yes, that means the onCreate was probably triggered by a configuration change
*like screen rotate etc. If that's the case then populate all the views that are necessary here
*/
if (savedInstanceState != null) {
ArrayList<BluetoothDevice> list = savedInstanceState.getParcelableArrayList(DEVICE_LIST);
if(list!=null){
initList(list);
MyAdapter adapter = (MyAdapter)mLstDevices.getAdapter();
int selectedIndex = savedInstanceState.getInt(DEVICE_LIST_SELECTED);
if(selectedIndex != -1){
adapter.setSelectedIndex(selectedIndex);
mBtnConnect.setEnabled(true);
}
} else {
initList(new ArrayList<BluetoothDevice>());
}
} else {
initList(new ArrayList<BluetoothDevice>());
}
mBtnSearch.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
mBTAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBTAdapter == null) {
Toast.makeText(getApplicationContext(), "Bluetooth not found", Toast.LENGTH_SHORT).show();
} else if (!mBTAdapter.isEnabled()) {
Intent enableBT = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBT, BT_ENABLE_REQUEST);
} else {
new SearchDevices().execute();
}
}
});
mBtnConnect.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
BluetoothDevice device = ((MyAdapter) (mLstDevices.getAdapter())).getSelectedItem();
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
intent.putExtra(DEVICE_EXTRA, device);
intent.putExtra(DEVICE_UUID, mDeviceUUID.toString());
intent.putExtra(BUFFER_SIZE, mBufferSize);
intent.putExtra("isECG", isECG);
intent.setClass(Homescreen.this, MainActivity.class);
startActivity(intent);
}
});
}
/**
* Called when the screen rotates. If this isn't handled, data already generated is no longer available
*/
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
MyAdapter adapter = (MyAdapter) (mLstDevices.getAdapter());
ArrayList<BluetoothDevice> list = (ArrayList<BluetoothDevice>) adapter.getEntireList();
if (list != null) {
outState.putParcelableArrayList(DEVICE_LIST, list);
int selectedIndex = adapter.selectedIndex;
outState.putInt(DEVICE_LIST_SELECTED, selectedIndex);
}
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
}
#Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case BT_ENABLE_REQUEST:
if (resultCode == RESULT_OK) {
msg("Bluetooth Enabled successfully");
new SearchDevices().execute();
} else {
msg("Bluetooth couldn't be enabled");
}
break;
case SETTINGS: //If the settings have been updated
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
String uuid = prefs.getString("prefUuid", "Null");
mDeviceUUID = UUID.fromString(uuid);
Log.d(TAG, "UUID: " + uuid);
String bufSize = prefs.getString("prefTextBuffer", "Null");
mBufferSize = Integer.parseInt(bufSize);
String orientation = prefs.getString("prefOrientation", "Null");
Log.d(TAG, "Orientation: " + orientation);
if (orientation.equals("Landscape")) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
} else if (orientation.equals("Portrait")) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
} else if (orientation.equals("Auto")) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
}
break;
default:
break;
}
super.onActivityResult(requestCode, resultCode, data);
}
/**
* Quick way to call the Toast
* #param str
*/
private void msg(String str) {
Toast.makeText(getApplicationContext(), str, Toast.LENGTH_SHORT).show();
}
/**
* Initialize the List adapter
* #param objects
*/
private void initList(List<BluetoothDevice> objects) {
final MyAdapter adapter = new MyAdapter(getApplicationContext(), R.layout.list_item, R.id.lstContent, objects);
mLstDevices.setAdapter(adapter);
mLstDevices.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
adapter.setSelectedIndex(position);
mBtnConnect.setEnabled(true);
}
});
}
/**
* Searches for paired devices. Doesn't do a scan! Only devices which are paired through Settings->Bluetooth
* will show up with this. I didn't see any need to re-build the wheel over here
* #author ryder
*
*/
private class SearchDevices extends AsyncTask<Void, Void, List<BluetoothDevice>> {
#Override
protected List<BluetoothDevice> doInBackground(Void... params) {
Set<BluetoothDevice> pairedDevices = mBTAdapter.getBondedDevices();
List<BluetoothDevice> listDevices = new ArrayList<BluetoothDevice>();
for (BluetoothDevice device : pairedDevices) {
listDevices.add(device);
}
return listDevices;
}
#Override
protected void onPostExecute(List<BluetoothDevice> listDevices) {
super.onPostExecute(listDevices);
if (listDevices.size() > 0) {
MyAdapter adapter = (MyAdapter) mLstDevices.getAdapter();
adapter.replaceItems(listDevices);
} else {
msg("No paired devices found, please pair your serial BT device and try again");
}
}
}
/**
* Custom adapter to show the current devices in the list. This is a bit of an overkill for this
* project, but I figured it would be good learning
* Most of the code is lifted from somewhere but I can't find the link anymore
* #author ryder
*
*/
private class MyAdapter extends ArrayAdapter<BluetoothDevice> {
private int selectedIndex;
private Context context;
private int selectedColor = Color.parseColor("#abcdef");
private List<BluetoothDevice> myList;
public MyAdapter(Context ctx, int resource, int textViewResourceId, List<BluetoothDevice> objects) {
super(ctx, resource, textViewResourceId, objects);
context = ctx;
myList = objects;
selectedIndex = -1;
}
public void setSelectedIndex(int position) {
selectedIndex = position;
notifyDataSetChanged();
}
public BluetoothDevice getSelectedItem() {
return myList.get(selectedIndex);
}
#Override
public int getCount() {
return myList.size();
}
#Override
public BluetoothDevice getItem(int position) {
return myList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
private class ViewHolder {
TextView tv;
}
public void replaceItems(List<BluetoothDevice> list) {
myList = list;
notifyDataSetChanged();
}
public List<BluetoothDevice> getEntireList() {
return myList;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
ViewHolder holder;
if (convertView == null) {
vi = LayoutInflater.from(context).inflate(R.layout.list_item, null);
holder = new ViewHolder();
holder.tv = (TextView) vi.findViewById(R.id.lstContent);
vi.setTag(holder);
} else {
holder = (ViewHolder) vi.getTag();
}
if (selectedIndex != -1 && position == selectedIndex) {
holder.tv.setBackgroundColor(selectedColor);
} else {
holder.tv.setBackgroundColor(Color.WHITE);
}
BluetoothDevice device = myList.get(position);
holder.tv.setText(device.getName() + "\n " + device.getAddress());
return vi;
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.homescreen, menu);
return true;
}
}
in my android code I have these global variables:
BluetoothAdapter mBluetoothAdapter;
BluetoothSocket mmSocket;
BluetoothDevice mmDevice;
OutputStream mmOutputStream;
InputStream mmInputStream;
And then I get my paired bluetooth devices in a similar way to what you did:
#Override
protected List<BluetoothDevice> doInBackground(Void... params) {
Set<BluetoothDevice> pairedDevices = mBTAdapter.getBondedDevices();
List<BluetoothDevice> listDevices = new ArrayList<BluetoothDevice>();
for (BluetoothDevice device : pairedDevices) {
listDevices.add(device);
}
return listDevices;
}
Then when I select the correct bluetooth device, I set it equal to mmDevice:
mmDevice = device;
Then I use this method to open a bluetooth connection:
void openBT() throws IOException{
UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb"); //Standard SerialPortService ID
mmSocket = mmDevice.createRfcommSocketToServiceRecord(uuid);
mmSocket.connect();
mmOutputStream = mmSocket.getOutputStream();
mmInputStream = mmSocket.getInputStream();
//Optional
System.out.println("Bluetooth Opened");
Toast.makeText(getApplicationContext(), "Bluetooth Opened", Toast.LENGTH_SHORT).show();
}
The mmOutputStream sends data to the bluetooth module and the mmInputStream reads the incoming data from the bluetooth module. I have this method to send data to the bluetooth module:
void sendData(String m) throws IOException{
String msg = m;
mmOutputStream.write(msg.getBytes());
System.out.println("Data Sent");
}
This converts a string to bytes and sends it to the Arduino. On the Arduino side, you can either say
if(bluetooth.available())
{
char c = bluetooth.read();
Serial.println(c);
}
If you are just reading a single char or say:
if(bluetooth.available())
{
int data = bluetooth.parseInt();
Serial.println(data);
}
To read an integer value that you sent over bluetooth. Hope this helps. If you need anything, don't hesitate to ask.

PullToRefreshAttacher.OnRefreshListener cannot be resolved to a type

am building an open source project, here is its link
http://slidese.github.io/slidese/2013/11/25/update_listview_item.html
I've imported all library projects which it is using into eclipse. All are fine except PullToRefresh library. it is giving me the error "PullToRefreshAttacher.OnRefreshListener cannot be resolved to a type" where fragment implements it
2nd error is at
mPullToRefreshAttacher.addRefreshableView(mListview, this);
it says "The method addRefreshableView(View, ViewDelegate) in the type PullToRefreshAttacher is not applicable for the arguments (ListView, ContentFragment)"
3rd error is at
#Override
public void onRefreshStarted(View view) {
Intent intent = new Intent(getActivity(), DownloaderService.class);
intent.putExtra(DownloaderService.EXTRA_USER_INITIATED, true);
getActivity().startService(intent);
}
It is asking me to remove override annotation. here is complete code of fragment.
public class ContentFragment extends Fragment implements PullToRefreshAttacher.OnRefreshListener {
private final String TAG = "ContentFragment";
public static final String CONTENT_MODE = "content_mode";
public static final int MODE_ADFREE = 0;
public static final int MODE_PREMIUM = 1;
private StartActivity mListener;
private PullToRefreshAttacher mPullToRefreshAttacher;
private UpdaterAsyncTask mUpdater;
private int mScrollState = OnScrollListener.SCROLL_STATE_IDLE;
ListView mListview;
Button mPlayButton;
ContentAdapter mAdapter;
int mMode;
Map<String, UpdateHolder> mUpdates = new HashMap<String, UpdateHolder>();
public ContentFragment() {
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (StartActivity) activity;
Log.d(TAG, "Attached podcast list fragment");
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must be the StartActivity");
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_content, null);
mListview = (ListView) view.findViewById(android.R.id.list);
mListview.setEmptyView(view.findViewById(R.id.empty_list_view));
mListview.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
mListview.setMultiChoiceModeListener(new MultiChoiceModeListener() {
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
#Override
public void onDestroyActionMode(ActionMode mode) {
}
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.contextual_menu_content, menu);
return true;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
if (item.getItemId() == R.id.action_delete) {
SparseBooleanArray checked = mListview.getCheckedItemPositions();
Content[] params = new Content[checked.size()];
int index = 0;
int first = mListview.getFirstVisiblePosition();
int last = mListview.getLastVisiblePosition();
for (int i = 0; i < mListview.getCount(); i++) {
if (checked.get(i)) {
params[index++] = (Content)mListview.getItemAtPosition(i);
if (i >= first && i <= last) {
View view = mListview.getChildAt(i-first);
Animation animation = AnimationUtils.loadAnimation(getActivity(), android.R.anim.slide_out_right);
animation.setDuration(200);
//animation.setFillAfter(true);
animation.setStartOffset(100 * (index) );
view.startAnimation(animation);
}
}
}
new AsyncTask<Content, Void, Void>() {
#Override
protected Void doInBackground(Content... params) {
for (Content content : params) {
File file = Utils.getFilepath(content.getFilename());
file.delete();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
mAdapter.notifyDataSetChanged();
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
mode.finish();
return true;
}
return false;
}
#Override
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
}
});
mListview.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View view, int position, long id) {
Content content = mAdapter.getItem(position);
mListener.showContentDetails(content);
}
});
mListview.setOnScrollListener(new OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
mScrollState = scrollState;
}
#TargetApi(Build.VERSION_CODES.JELLY_BEAN)
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
});
mPullToRefreshAttacher = ((StartActivity) getActivity()).getPullToRefreshAttacher();
mPullToRefreshAttacher.addRefreshableView(mListview, this);
mMode = getArguments().getInt(CONTENT_MODE);
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
#Override
public void onPause() {
super.onPause();
if (mUpdater != null)
mUpdater.stop();
}
#Override
public void onResume() {
super.onResume();
updateAdapter();
mUpdater = new UpdaterAsyncTask();
mUpdater.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void)null);
}
public void refresh() {
updateAdapter();
}
public void replaceCurrentlyPlayingContent() {
GlobalContext.INSTANCE.replaceCurrentlyPLayingContent(mAdapter.getObjects(), mListener.getCurrentTrack());
}
private void updateAdapter() {
Log.d(TAG, "updateAdapter");
//new FetchContentAsyncTask(mMode).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
final String mp3 = mListener.getSavedStateMp3();
final boolean isPlaying = mListener.getSavedStateIsPlaying();
final boolean isPaused = mListener.getSavedStateIsPaused();
List<Content> listOfContent = GlobalContext.INSTANCE.getCachedContent(mMode, mp3, isPlaying, isPaused);
mAdapter = new ContentAdapter(getActivity(), R.layout.list_item_card, listOfContent);
mListview.setAdapter(mAdapter);
}
#Override
public void onRefreshStarted(View view) {
Intent intent = new Intent(getActivity(), DownloaderService.class);
intent.putExtra(DownloaderService.EXTRA_USER_INITIATED, true);
getActivity().startService(intent);
}
private class UpdaterAsyncTask extends AsyncTask<Void, Void, Void> {
boolean isRunning = true;
public void stop() {
isRunning = false;
}
#Override
protected Void doInBackground(Void... params) {
while (isRunning) {
/*
Map<String, UpdateHolder> map = gatherMetadata();
publishProgress(map);
*/
updateCurrentAdapterContent();
publishProgress();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onProgressUpdate(Void... params) {
super.onProgressUpdate();
if (mScrollState == OnScrollListener.SCROLL_STATE_IDLE) {
// http://stackoverflow.com/questions/2123083/android-listview-refresh-single-row
int start = mListview.getFirstVisiblePosition();
for(int i = start, j = mListview.getLastVisiblePosition(); i<=j; i++) {
View view = mListview.getChildAt(i-start);
if (((Content)mListview.getItemAtPosition(i)).dirty) {
Log.v(TAG, "Content is dirty");
mListview.getAdapter().getView(i, view, mListview);
}
}
}
}
}
private void updateCurrentAdapterContent() {
List<Content> listOfContent = mAdapter.getObjects();
Map<String, UpdateHolder> map = new HashMap<String, UpdateHolder>();
DownloadManager.Query q = new DownloadManager.Query();
q.setFilterByStatus(DownloadManager.STATUS_PENDING | DownloadManager.STATUS_RUNNING);
try {
Cursor cursor = ContentDownloadManager.INSTANCE.query(q);
while (cursor.moveToNext()) {
//long id = cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_ID));
String uri = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_URI));
int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
int downloaded = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
int total = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
float progress = (float)downloaded/(float)total;
UpdateHolder holder = new UpdateHolder();
holder.progress = progress;
holder.status = status;
map.put(uri, holder);
}
cursor.close();
final Content currentContent = mListener.getCurrentTrack();
final boolean isPlaying = mListener.isPlaying();
final boolean isPaused = mListener.isPaused();
for (Content content : listOfContent) {
// First update any download progress we might have for this specific content item
UpdateHolder holder = map.get(content.mp3);
if (holder != null) {
if (content.downloadProgress != holder.progress) {
content.downloadProgress = holder.progress;
content.dirty = true;
}
if (content.downloadStatus != holder.status) {
content.downloadStatus = holder.status;
content.dirty = true;
}
}
else {
if (content.downloadProgress != 0f) {
content.downloadProgress = 0f;
content.dirty = true;
}
if (content.downloadStatus != -1) {
content.downloadStatus = -1;
content.dirty = true;
}
}
// Update with elapsed (to be done)
// File exists?
File file = Utils.getFilepath(content.getFilename());
if (content.exists != file.exists()) {
content.exists = file.exists();
content.dirty = true;
}
// Is this the currently playing content
if (currentContent != null && content.mp3.equals(currentContent.mp3)) {
if (content.isPlaying != isPlaying) {
content.isPlaying = isPlaying;
content.dirty = true;
}
if (content.isPaused != isPaused) {
content.isPaused = isPaused;
content.dirty = true;
}
}
else {
if (content.isPlaying != false) {
content.isPlaying = false;
content.dirty = true;
}
if (content.isPaused != false) {
content.isPaused = false;
content.dirty = true;
}
}
if (content.dirty) {
DatabaseManager.getInstance().createOrUpdateContent(content);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public class UpdateHolder {
public String mp3;
public int status;
public boolean played;
public float progress;
public boolean exists = false;
public boolean isPlaying = false;
public boolean isPaused = false;
//public int elapsed;
//public int duration;
}
}
I couldn't find the issue in it. I'm stuck here for last 40 hours. Please help. Thank you!
Maybe you are using old version of the library. I found that PullToRefreshAttacher doesn't contain OnRefreshListener. (https://github.com/chrisbanes/ActionBar-PullToRefresh/blob/master/library/src/main/java/uk/co/senab/actionbarpulltorefresh/library/PullToRefreshAttacher.java)
Try to import uk.co.senab.actionbarpulltorefresh.library.listeners.OnRefreshListener; and use it instead of PullToRefreshAttacher.OnRefreshListener.

Categories

Resources