简体   繁体   中英

Android NFC Redirecting intent

When i put an nfc tag close to my mobile phone i want my app to start so i added this into my manifest:

<intent-filter>
    <action android:name="android.nfc.action.TECH_DISCOVERED" />
    <category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data android:name="android.nfc.action.TECH_DISCOVERED" android:resource="@xml/nfc_tech_filter" /> 

This works great.

If a user is not logged in i want the user to log in first before he can transfer the data from the tag so i added this into my onCreate of my measure activity:

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

    this.sessionManager = new SessionManager(this);
    this.sessionManager.login();

    this.setContentView(R.layout.activity_measure);
    this.nfcAdapter = NfcAdapter.getDefaultAdapter(this);
    this.pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);

    IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);

    this.filters = new IntentFilter[] { ndef, };
    this.techLists = new String[][] { new String[] { android.nfc.tech.NfcV.class.getName() } };

    this.textViewYear = (TextView) findViewById(R.id.measure_textview_year);
    this.textViewMonthDay = (TextView) findViewById(R.id.measure_textview_month_day);
    this.textViewTime = (TextView) findViewById(R.id.measure_textview_time);
    this.textViewGlucose = (TextView) findViewById(R.id.measure_textview_glucose);

    new StartReadTask().execute();
}

But after the user is logged in he gets redirected to my main menu because of this implementation:

/**
 * 
 * @param v
 */
@Override
public void onClick(View view) {
    String username = this.textEditUsername.getText().toString();
    String password = this.textEditPassword.getText().toString();

    if(username.trim().length() > 0 && password.trim().length() > 0){
        if(username.equals("test") && password.equals("test")){
            this.sessionManager.createLoginSession("Test-Name", "Test-Email");

            Intent intent = new Intent(this.getApplicationContext(), MainActivity.class);

            this.startActivity(intent);
            this.finish();
        } else {
            this.dialogAlertManager.showAlertDialog(LoginActivity.this, "Login failed..", "Username or Password is incorrect", false);
        }               
    } else {
        this.dialogAlertManager.showAlertDialog(LoginActivity.this, "Login failed..", "Please enter username and password", false);
    }
}  

The 'MainActivity' mentioned here is my main menu. but i want the activity to redirect to my measure activity but i don't know how i can do that. after a "normal" login, without nfc intent, i need the app to redirect to the main menu but with nfc intent i want it to redirect to the measure activity.

Also when the user already is logged in i want the data of the tag to be transferred immediately. now if i want to transfer the data i have to keep the tag close to the phone to start the measure activity and than to put it away and back again to transfer the data.

How can i do both things?

You are doing to many different things in the same code: reading nfc, accessing ui fields, controlling the flows of the activities. (Yes, android sample code often give bad examples)

You need to handle special cases like what is happening when the user just starts to login an then the tag is read. Your only chance to get this right is to separate the different responsibilities in your code.

One thing is sure: you need to store the information when a tag was read. So you can react differently and finally display it when the user has logged in. When there are different Activities involved, you probably need to store the data in some kind of central entity, like a singleton. (Alternative is to always send the information together with the intent when you move from activity to another)

For NFC-reading, there is an example app "NFC-HUNT" from google which I found helpful. The has some special features:

  1. it uses a special activity without UI that reads the NFC-Tag. This way NFC-reading is encapsulated, and the rest of your app has no NFC-Code at all. This Activty (called NFCShimActivity) just ready the Infomation and then creates an Intent to start your normal UI.

  2. Normally, when an Activity is visible and new Intent for this Activity arrives (because NFC-Tag was read), another instance of the Actiity gets opened. Just what you do not want.

Solution is to set android:launchMode="singleTask" in Manifest, and to implement this method in the Activity:

  public void onNewIntent(Intent intent) {...}

I have written a blog entry about the nfc code reading structure, maybe it helps you to make it easier to understand

http://meier-online.com/en/2014/09/nfc-hunt-analysed/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM