Host-Card Emulation Reader Model - android

From reading the HCE developers guide here HCE Developer's Guide seems it is possible to use an android phone as a reader. I put card information on an NFC tag, and then read it with my phone. I want to have the phone act as the reader. Do you know if this is possible? I have created a sample project with the following lines of code in it:
import android.nfc.cardemulation.HostApduService;
import android.os.Bundle;
public class MyHostAPDUService extends HostApduService{
#Override
public byte[] processCommandApdu(byte[] apdu, Bundle extras) {
...
}
#Override
public void onDeactivated(int reason) {
...
}
}
I don't know where to go next.

I have achieved using the phone as a reader but through a slightly different approach:
Using an activity as the base I created a simple reader application where I sent a select and then some following APDUs to a card
private NfcAdapter mAdapter;
private PendingIntent mPendingIntent;
private String[][] mTechLists;
private IsoDep card;
onCreate(){
...
mAdapter = NfcAdapter.getDefaultAdapter(this);
mPendingIntent = pendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),0);
mTechLists = new String[][]{new String[]{IsoDep.class.getName()},new String[]{IsoDep.class.getName()}};
...
}
onPause(){
mAdapter.disableForegroundDispatch(this);
}
onResume(){
mAdapter.enableForegroundDispatch(this,mPendingIntent,null,mTechLists);
}
onNewIntent(Intent intent){
Tag theTag = (Tag)intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
card = IsoDep.get(theTag);
...
card.connect();
...
byte[] response = card.transceive(apduBytes);
}
I haven't done much more work on this as it was just a proof of concept but I hope it's helpful.

Related

Confusion about some code in an Android Room with a View sample project

I am learning the android room with a view. I've looked through some sample projects and tutorials and there is one thing in this example that I am hung up on and that I do not understand. Here is the code (underneath the code I point out the few lines I'm confused about):
public class NewWordActivity extends AppCompatActivity {
public static final String EXTRA_REPLY = "com.example.android.wordlistsql.REPLY";
private EditText mEditWordView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_new_word);
mEditWordView = findViewById(R.id.edit_word);
final Button button = findViewById(R.id.button_save);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent replyIntent = new Intent();
if (TextUtils.isEmpty(mEditWordView.getText())) {
setResult(RESULT_CANCELED, replyIntent);
} else {
String word = mEditWordView.getText().toString();
replyIntent.putExtra(EXTRA_REPLY, word);
setResult(RESULT_OK, replyIntent);
}
finish();
}
});
}
}
The parts that I am confused about are the second line, the EXTRA_REPLY, and then you can see it used toward the bottom in reply.Intent.putExtra. What is the EXTRA_REPLY pointing to exactly? How would you find it in your own project?
Here is the source of the sample if you need more context: https://codelabs.developers.google.com/codelabs/android-room-with-a-view/#12
This is just a simple key/value pair. Like a HashMap, or a Dictionary.
replyIntent.putExtra(EXTRA_REPLY, word);
This will set the EXTRA_REPLY to word within your Intent so you can read it in whatever Activity is handling your result.
You can also do it with a Bundle, for example when you launch a new Activity.
The key, com.example.android.wordlistsql.REPLY, does not really matter, just make sure that everyone is using the same key.
When you make an intent you can add extra data to it in key-value form. In this example they use the string constant EXTRA_REPLY as the key, and the variable word as the value.
The recipient of the intent would access the data by using intent.getStringExtra(NewWordActivity.EXTRA_REPLY).
It's good practice to define the keys for your intents as constants so that you're less likely to make mistakes when referencing it in other classes.

Can I "bind" an image file to an ImageView?

I have an Android app that contains a users list with an Avatar for each user. The avatar image file is stored as a local .png file in the apps cache folder. From time to time, another service updates the avatar png files with more current ones (but in no regular order), and I would like to have my list of avatar ImageView update with the new .png files as they are saved to disk.
I have tried subclassing ImageView and adding a FileObserver property to it, however, this isn't seeming to be the most effective.
Does anyone have any recommendations on how to "live" bind a .png to an ImageView so that it will updates if/when the image file on disk changes?
I'm not sure if I should be looking into DataBinding or not because this seems overkill to me.
You can register BroadcastReceiver at activity and receive notifications from your service.
Firstly, you need to create an implementation of BroadcastReceiver like this:
public class YourBroadcastReceiver extends BroadcastReceiver {
/**
* Listener interface for received broadcast messages.
*/
public interface YourBroadcastListener {
void receivedBroadcast();
}
/**
* The Intent action that this Receiver should filter for.
*/
public static final String ACTION = "com.your.package.IMAGES_UPDATED";
private final YourBroadcastListener mListener;
public YourBroadcastReceiver(YourBroadcastListener listener) {
mListener = listener;
}
#Override
public void onReceive(Context context, Intent intent) {
if (mListener != null)
mListener.receivedBroadcast();
}
}
Next, you need to register YourBroadcastReceiver in your activity:
public class MainActivity extends Activity implements YourBroadcastListener {
private YourBroadcastReceiver mReceiver;
#Override
protected void onResume() {
super.onResume();
if(mReceiver == null){
mReceiver = new YourBroadcastReceiver(this);
registerReceiver(mReceiver, new IntentFilter(YourBroadcastReceiver.ACTION));
}
}
#Override
protected void onPause() {
super.onPause();
if(mReceiver != null){
unregisterReceiver(mReceiver);
mReceiver = null;
}
}
#Override
public void receivedBroadcast() {
// Received a broadcast notification that the images has changed - reload it
}
}
And the last, your service need to send brodcast notifications to your activity:
Intent i = new Intent("com.your.package.IMAGES_UPDATED");
sendBroadcast(i);
Take a note: your action string need to be unique to avoid collisions with another applications.

NFC p2p tag interception

I am building an Android app using Eclipse and Android SDK.
I would like to implement an NFC p2p function in my app in the sense that when you place the 2 phones back to back, both send a string and receive a string automatically. This would of course happen in a separate activity. I have managed to send a custom tag (String) but have been unable to intercept it and use it afterwards in the app code. How can i do this?
This is what i have so far.
public class MainActivity extends Activity {
public NfcAdapter mAdapter;
PendingIntent mPendingIntent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAdapter = NfcAdapter.getDefaultAdapter(this);
NdefRecord rec = NdefRecord.createUri("www.stackoverflow.com");
NdefMessage ndef = new NdefMessage(rec);
mAdapter.setNdefPushMessage(ndef, this);
}
I have spent a lot of time trying to find and understand solutions to intercept the tag. Unsuccessfully.
Thank you for your help.

How to use Activities within fragments in Navigation Drawer

I am having an issue with using activities in fragments.
I have two activities , activity one will send data to two using intents.
Activity one is basically nfc scan part and tag information is sent using intents, Activity two will receive and display the info.
I am trying to put activities in fragments and use with navigation drawer UI.
How do i achieve this?
Activity 1 Code :
public class Activity2 extends Activity {
private NfcAdapter mAdapter;
private PendingIntent mPendingIntent;
private IntentFilter[] mFilters;
private String[][] mTechLists;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mAdapter = NfcAdapter.getDefaultAdapter(this);
mPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
mFilters = null;
mTechLists = null;
Intent intent = getIntent();
String action = intent.getAction();
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action))
{
onNewIntent(intent);
}
}
#Override
protected void onResume() {
super.onResume();
mAdapter.enableForegroundDispatch(this, mPendingIntent, mFilters, mTechLists);
}
#Override
public void onPause() {
super.onPause();
mAdapter.disableForegroundDispatch(this);
}
#Override
public void onNewIntent(Intent intent) {
Log.i("Foreground dispatch", "Discovered tag with intent: " + intent);
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
startnfcread(tag);
}
private void startnfcread(Tag tag){
try {
NfcV nfcv = NfcV.get(tag);
if(nfcv != null){
nfcv.connect();
Intent newActivity = new Intent(this, Activity2.class);
newActivity.putExtra("TagID", tag.getId());
startActivity(newActivity);
nfcv.close();
}
} catch (Exception e) {
Log.e("NFC error", e.toString());
Toast.makeText(this, "NFC failed", Toast.LENGTH_SHORT).show();
}
}
Activity 2:
public class Activity2 extends Activity {
private String displayID = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.results);
TextView resultIdView = (TextView) findViewById(R.id.Tag_id);
Bundle extras = getIntent().getExtras();
if(extras !=null)
{
byte[] TagID = extras.getByteArray("TagID");
displayID = toHex(TagID);
resultIdView.setText(displayID);
}
}
}
I have taken the navigation drawer example from http://www.androidhive.info/2013/11/android-sliding-menu-using-navigation-drawer/.
There is a main drawer activity and different fragments, how can i use the activity with these fragments. When i scan nfc tag from activity 1 it will send tag id to activity 2 and display tag id.
Same concept how do use with fragments, like from fragment1 scan tag happens and displays the tag id in fragment 2.
kumar
You should read some basic docs and guides about how to deal with Fragments.
Fragments ahve pretty similar lifecycle callback to Activities, so you should be able to convert your code quickly - according to its complexity.
Briefly. Create an Activity which will server as a container for you fragments (just basic Activity with some simple layout). Then in this Activity use FragmentManager to add your Fragments to it. You can be adding or removing Fragments from you Activities on the fly, or just showing/hiding them, that is completely up to you. Google has some nice examples and guides which should server you well to start.
Communication among Fragments could be once again done with Intents (see getArguments()), custom interfaces, you can use an event Bus (see Otto),...I would start with Intents..
You can pass a Bundle to a fragment.
Bundle b = new Bundle();
b.putExtra("TagID", tag.getId());
FragmentVedioView fv = new FragmentVedioView();
fv.setArguments(b);
SFM.beginTransaction().replace(id, fv, "FragmentVedioView").commit();

Intent's intended class can't read extended information from said intent

I am trying to send information from my main activity class to another class in my app package. The information is used to update an AlertDialog automatically. Here is the code I've been working with:
//This is in MainActivity.class
//Tests to see if SyncDialog will update itself with new intents.
public void testLoop() {
int n = 0;
Intent intent = new Intent(this, SyncDialog.class);
while (n != 10) {
intent.putExtra(TEST_NUMBER, n);
n++;
}
}
//This is in SyncDialog.class
//This method should get the int value from MainActivity
protected void onNewIntent(Intent intent) {
int n = intent.getIntExtra(TEST_NUMBER, 0);
showNextDialog(n);
}
TEST_NUMBER is defined as a public constant at the top of MainActivity, and I even tried importing MainActivity into SyncDialog.class.
Is there any way to fix this?
You will have to make it a static constant if you want to access it in the way you are attempting. In MainActivity:
public static String TEST_NUMBER = "test";
and in SyncDialog:
intent.getExtra(MainActivity.TEST_NUMBER, 0)

Categories

Resources