Shoe Sticker: How to have both condition, 1. upon detect motion display information 2. manually click the sticker to display information

I have a school project on shoe sticker and trying to figure out on how to do it based on the codes on github
The problem I’m facing with is, it is not able to display currentNearableInfo when the sticker is picked up( motion detected) it is only able to display when I manually clicked on the sticker icon. Is it possible that you provide me some guidance to where I have made my mistake or point out where should I make changes.

public class ListNearablesActivity extends BaseActivity {
  
  private static final String TAG = ListNearablesActivity.class.getSimpleName();
  
  public static final String EXTRAS_TARGET_ACTIVITY = "extra sTargetActivity";
  public static final String EXTRAS_NEARABLE = "extrasNearable";
  
  private static final int REQUEST_ENABLE_BT = 1234;
  
  private BeaconManager beaconManager;
  private NearableListAdapter adapter;
  
  @Override protected int getLayoutResId() {
    return R.layout.main;
  }
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    
    //Configure device list
    adapter = new NearableListAdapter(this);
    ListView list = (ListView) findViewById(R.id.device_list);
    list.setAdapter(adapter);
    list.setOnItemClickListener(createOnItemClickListener());
    
    //Initialize Beacon Manager
    beaconManager = new BeaconManager(this);
  }
  
  .
  .
  .
  .
  .
  
  private AdapterView.OnItemClickListener createOnItemClickListener() {
    return new AdapterView.OnItemClickListener() {
      @Override
      public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        if (getIntent().getStringExtra(EXTRAS_TARGET_ACTIVITY) != null) {
          try {
            Class<?> clazz = Class.forName(getIntent().getStringExtra(EXTRAS_TARGET_ACTIVITY));
            Intent intent = new Intent(ListNearablesActivity.this, clazz);
            intent.putExtra(EXTRAS_NEARABLE, adapter.getItem(position));
            startActivity(intent);
          } catch (ClassNotFoundException e) {
            Log.e(TAG, "Finding class by name failed", e);
          }
        }
      }
    };
  }

How about:

@Override public void onNearablesDiscovered(List nearables) {
  for (Nearable nearable : nearables) {
    if (nearable.identifier.equals("54b128ebbc420d35") && nearable.isMoving) {
      // stop scanning to prevent duplicate "clicks"
      beaconManager.stopNearableDiscovery(scanId);
      // do whatever you'd ordinarily do in the onClick listener here
      // ...
    }
  }
}

Hi:
I want to have the onclick button and with sticker when it is moving then perform an action. How do I have the 2 condition

private AdapterView.OnItemClickListener createOnItemClickListener() {
  return new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
      if (getIntent().getStringExtra(EXTRAS_TARGET_ACTIVITY) != null) {
        try {
          Class<?> clazz = Class.forName(getIntent().getStringExtra(EXTRAS_TARGET_ACTIVITY));
          Intent intent = new Intent(ListNearablesActivity.this, clazz);
          intent.putExtra(EXTRAS_NEARABLE, adapter.getItem(position));
          startActivity(intent);
        } catch (ClassNotFoundException e) {
          Log.e(TAG, "Finding class by name failed", e);
        }
      }
    }
  };

Just set up the Nearables scanning the way it’s described in the Quick Start:

… then, use the implementation of the onNearablesDiscovered I’ve posted above, and replace the identifier (it’s the 54b128ebbc420d35 string) of the sticker which you want to trigger the “click” to one of your own.

Finally, replace the “do whatever you’d ordinarily do in the onClick listener here” with your onItemClick code:

if (getIntent().getStringExtra(EXTRAS_TARGET_ACTIVITY) != null) {
try {
Class<?> clazz = Class.forName(getIntent().getStringExtra(EXTRAS_TARGET_ACTIVITY));
Intent intent = new Intent(ListNearablesActivity.this, clazz);
intent.putExtra(EXTRAS_NEARABLE, adapter.getItem(position));
startActivity(intent);
} catch (ClassNotFoundException e) {
Log.e(TAG, "Finding class by name failed", e);
}
}

Hi heypiotr,
After I did this, I got plenty of errors :cry:

beaconManager.setNearableListener(new BeaconManager.NearableListener() {
  @Override
  public void onNearablesDiscovered(List<Nearable> nearables) {
    for (Nearable nearable : nearables) {
      if (nearable.identifier.equals("065473d63cd9d687") && nearable.isMoving) {
        
        private AdapterView.OnItemClickListener createOnItemClickListener() {
          return new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
              if (getIntent().getStringExtra(EXTRAS_TARGET_ACTIVITY) != null) {
                try {
                  Class<?> clazz = Class.forName(getIntent().getStringExtra(EXTRAS_TARGET_ACTIVITY));
                  Intent intent = new Intent(ListNearablesActivity.this, clazz);
                  intent.putExtra(EXTRAS_NEARABLE, adapter.getItem(position));
                  startActivity(intent);
                } catch (ClassNotFoundException e) {
                  Log.e(TAG, "Finding class by name failed", e);
                }
              }
            }
          };
        }
        
      }
    }
  }
}

You pasted in too much. Use the exact snippet from my previous post.

Hi heypiotr,

If I use the above exact snippet form the previous post, I can only have one condition which is detect motion to display the information, and I’m not able to click to display the information

beaconManager.setNearableListener(new BeaconManager.NearableListener(){
@Override public void onNearablesDiscovered (List nearables){
for (Nearable nearable : nearables) {
if (nearable.identifier.equals(“065473d63cd9d687”) && nearable.isMoving) {
// stop scanning to prevent duplicate "clicks"
beaconManager.stopNearableDiscovery(scanId);
// do whatever you’d ordinarily do in the onClick listener here
// …
if (getIntent().getStringExtra(EXTRAS_TARGET_ACTIVITY) != null) {
try {
Class<?> clazz = Class.forName(getIntent().getStringExtra(EXTRAS_TARGET_ACTIVITY));
Intent intent = new Intent(ListNearablesActivity.this, clazz);
intent.putExtra(EXTRAS_NEARABLE, adapter.getItem(position));
startActivity(intent);
} catch (ClassNotFoundException e) {
Log.e(TAG, “Finding class by name failed”, e);
}
}
}
}
}
});

Errors:
beaconManager.setNearableListener - cannot resolve symbol ‘setNearableListener’
@Override - ‘@Override’ is not applicable to local variable
public void onNearablesDiscovered - variable ‘onNearablesDiscovered’ is never used
List - expression expected
List nearables - cannot resolve symbol ‘nearables’
{ - ; expected
adapter.getItem(position) - cannot resolve symbol position

Hi @heypiotr,

What I have done now is when 1st click on sticker then 2nd upon detect motion it then will display the CurrentNearableInfo() but I want 2 condition either click on the sticker or detect motion to display CurrentNearableInfo().
Also another problem is when I click sticker A, and when sticker B in motion, it will display information of Sticker A. Can you help me with it :cry:

My codes (ListNearablesActivity.java):

package sg.edu.nyp.stickers.activities;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;

import com.estimote.sdk.BeaconManager;
import com.estimote.sdk.Nearable;

import java.util.Collections;
import java.util.List;

import sg.edu.nyp.stickers.R;
import sg.edu.nyp.stickers.adapter.NearableListAdapter;

/*** Displays list of found nearables sorted by RSSI.
* Starts new activity with selected nearable if activity was provided.*/

public class ListNearablesActivity extends BaseActivity {
private static final String TAG = ListNearablesActivity.class.getSimpleName();
public static final String EXTRAS_TARGET_ACTIVITY = "extrasTargetActivity";
public static final String EXTRAS_NEARABLE = "extrasNearable";
private static final int REQUEST_ENABLE_BT = 1234;

private BeaconManager beaconManager;
private NearableListAdapter adapter;
//private Nearable currentNearable;
private String scanId;

@Override
protected int getLayoutResId() {
return R.layout.main;
}

  @Override
  protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);

// Configure device list.
adapter = new NearableListAdapter(this);
ListView list = (ListView) findViewById(R.id.device_list);
list.setAdapter(adapter);
list.setOnItemClickListener(createOnItemClickListener());
//currentNearable = getIntent().getExtras().getParcelable(ListNearablesActivity.EXTRAS_NEARABLE);

//Initialize Beacon Manager
beaconManager = new BeaconManager(this);
}

@Override
protected void onDestroy() {
beaconManager.disconnect();
super.onDestroy();
}

 @Override
  protected void onStart() {
  super.onStart();

     // Check if device supports Bluetooth Low Energy.
     if (!beaconManager.hasBluetooth()) {
      Toast.makeText(this, "Device does not have Bluetooth Low Energy", Toast.LENGTH_LONG).show();
      return;
     }

// If Bluetooth is not enabled, let user enable it.
if (!beaconManager.isBluetoothEnabled()) {
  Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
  startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
} else {
  connectToService();
}
}

       @Override
       protected void onStop() {
         beaconManager.disconnect();
         super.onStop();
        }

   @Override
   protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_ENABLE_BT) {
       if (resultCode == Activity.RESULT_OK) {
         connectToService();
       } else {
         Toast.makeText(this, "Bluetooth not enabled", Toast.LENGTH_LONG).show();
         toolbar.setSubtitle("Bluetooth not enabled");
      }
     }
super.onActivityResult(requestCode, resultCode, data);
 }

    private void connectToService() {
     toolbar.setSubtitle("Scanning...");
     adapter.replaceWith(Collections.<Nearable>emptyList());

   beaconManager.setNearableListener(new BeaconManager.NearableListener() {
       @Override
       public void onNearablesDiscovered(List<Nearable> nearables) {
         toolbar.setSubtitle("Found nearables: " + nearables.size());
          adapter.replaceWith(nearables);
       } //for override
      });  //for beaconManager.setNearable

        beaconManager.connect(new BeaconManager.ServiceReadyCallback() {
         @Override
         public void onServiceReady() {
           scanId = beaconManager.startNearableDiscovery();
         } //for onServiceReady
        }); //for .connect
     } //for private void connectToService

This is the part (below) where I make changes: (sorry not able to bold the codes)

  private AdapterView.OnItemClickListener createOnItemClickListener() {
     return new AdapterView.OnItemClickListener() {
       @Override
       public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {
          if (getIntent().getStringExtra(EXTRAS_TARGET_ACTIVITY) != null){
           beaconManager.setNearableListener(new BeaconManager.NearableListener() {
              @Override
              public void onNearablesDiscovered(List<Nearable> nearables) {
                for (Nearable nearable : nearables) {
                  if (nearable.identifier.equals("065473d63cd9d687") && nearable.isMoving) {
                     try {
                      Class<?> clazz =     Class.forName(getIntent().getStringExtra(EXTRAS_TARGET_ACTIVITY));
                      Intent intent = new Intent(ListNearablesActivity.this, clazz);
                      intent.putExtra(EXTRAS_NEARABLE, adapter.getItem(position));
                      startActivity(intent);
                    } //close for try
                     catch (ClassNotFoundException e) {
                      Log.e(TAG, "Finding class by name failed", e);
                    } //close for catch (ClassNotFoundException e)
                  }
                }
               }
           });
           } //close for getintent.getStringExtra()
          } //close for public void onitemclick
           };   //close for return new adapterview
        }  //close for private adapter



      }

Hi @heypiotr,
did you see my last reply ?

Yes, sorry for the wait. I’ll get back to you with an example later this week.

Hi @heypiotr,

I have solve the issue!!, this are the codes:

package sg.edu.nyp.stickers.activities;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;

import com.estimote.sdk.BeaconManager;
import com.estimote.sdk.Nearable;

import java.util.Collections;
import java.util.List;

import sg.edu.nyp.stickers.R;
import sg.edu.nyp.stickers.adapter.NearableListAdapter;

/**
 * Displays list of found nearables sorted by RSSI.
 * Starts new activity with selected nearable if activity was provided.
 */
public class ListNearablesActivity extends BaseActivity {

  private static final String TAG = ListNearablesActivity.class.getSimpleName();

  public static final String EXTRAS_TARGET_ACTIVITY = "extrasTargetActivity";
  public static final String EXTRAS_NEARABLE = "extrasNearable";

  private static final int REQUEST_ENABLE_BT = 1234;

  private BeaconManager beaconManager;
  private NearableListAdapter adapter;
  //private Nearable currentNearable;
  private String scanId;

  @Override
  protected int getLayoutResId() {
    return R.layout.main;
  }

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Configure device list.
    adapter = new NearableListAdapter(this);
    ListView list = (ListView) findViewById(R.id.device_list);
    list.setAdapter(adapter);
    list.setOnItemClickListener(createOnItemClickListener());
    //currentNearable = getIntent().getExtras().getParcelable(ListNearablesActivity.EXTRAS_NEARABLE);

    //Initialize Beacon Manager
    beaconManager = new BeaconManager(this);
  }

  @Override
  protected void onDestroy() {
    beaconManager.disconnect();
    super.onDestroy();
  }

  @Override
  protected void onStart() {
    super.onStart();

    // Check if device supports Bluetooth Low Energy.
    if (!beaconManager.hasBluetooth()) {
      Toast.makeText(this, "Device does not have Bluetooth Low Energy", Toast.LENGTH_LONG).show();
      return;
    }

    // If Bluetooth is not enabled, let user enable it.
    if (!beaconManager.isBluetoothEnabled()) {
      Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
      startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
    } else {
      connectToService();
    }
  }

  @Override
  protected void onStop() {
    beaconManager.disconnect();
    super.onStop();
  }

  @Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_ENABLE_BT) {
      if (resultCode == Activity.RESULT_OK) {
        connectToService();
      } else {
        Toast.makeText(this, "Bluetooth not enabled", Toast.LENGTH_LONG).show();
        toolbar.setSubtitle("Bluetooth not enabled");
      }
    }
    super.onActivityResult(requestCode, resultCode, data);
  }

  private void connectToService() {
    toolbar.setSubtitle("Scanning...");
    adapter.replaceWith(Collections.<Nearable>emptyList());

  beaconManager.setNearableListener(new BeaconManager.NearableListener() {
      @Override
      public void onNearablesDiscovered(List<Nearable> nearables) {
        toolbar.setSubtitle("Found nearables: " + nearables.size());
        adapter.replaceWith(nearables);
        for (Nearable nearable : nearables) {
          if (nearable.isMoving) {
            try {
              Class<?> clazz = Class.forName(getIntent().getStringExtra(EXTRAS_TARGET_ACTIVITY));
              Intent intent = new Intent(ListNearablesActivity.this, clazz);
              intent.putExtra(EXTRAS_NEARABLE, **adapter.getItem(nearables.indexOf(nearable))**);
              startActivity(intent);
            } //close for try
            catch (ClassNotFoundException e) {
              Log.e(TAG, "Finding class by name failed", e);
            } //close for catch (ClassNotFoundException e)
          }
        }
      } //for override
    });  //for beaconManager.setNearable

      beaconManager.connect(new BeaconManager.ServiceReadyCallback() {
        @Override
        public void onServiceReady() {
          scanId = beaconManager.startNearableDiscovery();
        } //for onServiceReady
      }); //for .connect
  } //for private void connectToService

 private AdapterView.OnItemClickListener createOnItemClickListener() {
    return new AdapterView.OnItemClickListener() {
      @Override
      public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {
        if (getIntent().getStringExtra(EXTRAS_TARGET_ACTIVITY) != null){
                  try {
                    Class<?> clazz = Class.forName(getIntent().getStringExtra(EXTRAS_TARGET_ACTIVITY));
                    Intent intent = new Intent(ListNearablesActivity.this, clazz);
                    intent.putExtra(EXTRAS_NEARABLE, adapter.getItem(position));
                    startActivity(intent);
                  } //close for try
                  catch (ClassNotFoundException e) {
                    Log.e(TAG, "Finding class by name failed", e);
                  } //close for catch (ClassNotFoundException e)
              //  }
          //  }
        //  });
        } //close for getintent.getStringExtra()
      } //close for public void onitemclick
    };   //close for return new adapterview
  }  //close for private adapter



}

The bold part is where I made my changes

1 Like