SDK

Scannables

This functionality will allow your app to present content after they have scanned a NFC Tag or QR Code (we use QR Codes whenever the device does not support NFC). This could be extremely useful if you looking to extend physical objects with engaging content pretty much the same way you do when sending a notification.

Before you can start using this functionality you will need to create one or more tags in our dashboard. This is covered in our guides located here.

For this functionality you'll need to add the following to your /app/build.gradle file:

1
2
3
4
dependencies {
	...more dependencies
	compile 'com.google.android.gms:play-services-vision:11.2.2'
}

Then let's add the following to your AndroidManifest.xml file:

1
2
3
4
5
6
7
<activity
	android:name="re.notifica.ui.ScannableActivity"
	android:configChanges="keyboardHidden|orientation|screenSize"
	android:hardwareAccelerated="true">
</activity>

<meta-data android:name="com.google.android.gms.vision.DEPENDENCIES" android:value="barcode" />

In most cases you will want to start scanning a tag whenever the user opens your app and clicks a button in your UI. This would be done from one your app's activities or fragments like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public class MyScanningActivity extends ActionBarBaseActivity implements Notificare.OnNotificareReadyListener {


	private static final int SCANNABLE_REQUEST_CODE = 9001;

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

		setContentView(R.layout.activity_main);

		Notificare.shared().addNotificareReadyListener(this);
		... more code

	}


	@Override
	protected void onDestroy() {
		super.onDestroy();
		Notificare.shared().removeNotificareReadyListener(this);
	}

	@Override
	public void onNotificareReady(NotificareApplicationInfo notificareApplicationInfo) {

		myButton.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View view) {

				Notificare.shared().startScannableActivity(this, SCANNABLE_REQUEST_CODE);

			}

		}


	...more code
}

Starting this built-in activity whenever a user clicks a button will be enough to start a scanning session. If the user's device supports NFC that activity will show a text indicating that the user should tap the tag. If by any chance the device does not support NFC or NFC is not enabled, the activity will fallback to scanning Qr Codes and present the built-in camera.

Once the user taps a NFC tag or scans a Qr Code, your app will be responsible for handling the results. In that activity you would then implement the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public class MyScanningActivity extends ActionBarBaseActivity implements Notificare.OnNotificareReadyListener {


	private static final int SCANNABLE_REQUEST_CODE = 9001;

	...more code

	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (requestCode == SCANNABLE_REQUEST_CODE) {
			if (resultCode == CommonStatusCodes.SUCCESS) {
				if (data != null) {
					NotificareScannable scannable = Notificare.shared().extractScannableFromActivityResult(data);
					if (scannable != null) {
						if (scannable.getNotification() != null) {
							Notificare.shared().openNotification(this, scannable.getNotification());
						} else {
							Log.i(TAG, "scannable with type " + scannable.getType());
						}
					} else {
						Toast.makeText(this, "scannable not found", Toast.LENGTH_LONG).show();
					}
				} else {
					Toast.makeText(this, "scan did not return any results", Toast.LENGTH_LONG).show();
				}
			} else if (resultCode == CommonStatusCodes.CANCELED) {
				Toast.makeText(this, "scan was canceled", Toast.LENGTH_LONG).show();
			} else {
				Log.w(TAG, "error result: " + resultCode);
			}
		} else {
			super.onActivityResult(requestCode, resultCode, data);
		}
	}


	...more code

}

The code above would make sure that errors were handled correctly as well as it would present the content scanned to the user.

In Android devices with support for NFC, tags can also be scanned even when your app is not being used. This means that you will need to add some extra configurations if you would like your app to respond to NFC tags scanned when it is is inactive or in the background.

To signal Android that your app can handle these tags, you need to declare the following in any of your activities:

1
2
3
4
5
6
7
<activity android:name=".MyActivity">
	<intent-filter>
		<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
		<category android:name="android.intent.category.DEFAULT"/>
		<data android:scheme="com.mydomain" />
	</intent-filter>
</activity>

And then in that activity you'll want to handle the results of the scanning session. To do that, add the following code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
public class MyActivity extends ActionBarBaseActivity implements Notificare.OnNotificareReadyListener {


	private static final int SCANNABLE_REQUEST_CODE = 9001;

	...more code

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

		setContentView(R.layout.activity_my);

		...more code

		//Let's handle the intent
		handleIntent(getIntent());
	}


	protected void handleIntent(Intent intent) {
		Uri data = intent.getData();
		if (data != null && intent.getAction() != null && intent.getAction().equals(NfcAdapter.ACTION_NDEF_DISCOVERED)) {
			Notificare.shared().fetchScannable(data.toString(), new NotificareCallback<NotificareScannable>() {

				@Override
				public void onSuccess(NotificareScannable notificareScannable) {
					if (notificareScannable != null) {
						if (notificareScannable.getNotification() != null) {
							Notificare.shared().openNotification(MainActivity.this, notificareScannable.getNotification());
						} else {
							Toast.makeText(MainActivity.this, "scannable found", Toast.LENGTH_LONG).show();
						}
					}
				}

				@Override
				public void onError(NotificareError notificareError) {
					Toast.makeText(MainActivity.this, "scannable not found", Toast.LENGTH_LONG).show();
				}
			});
		} else {
			//Handle unidentifiable data
		}
	}


	...more code

}

This will make sure that as soon as the NFC tag is scanned your app will be able to handle results and present the content accordingly.