How to launch app using NFC tag on Windows Phone 8? - nfc

I got Windows Phone 8 device, few NDEF formatted NFC tags and I'm wondering, is it possible to implement app launching on my WP8 using these tags? I've read thoroughly this article about URI schemes for launching built-in apps for Windows Phone 8, but I haven't found any link related to actual launching of 3rd party apps. I can launch various settings screens, or browser, email, SMS...
What is more interesting, that there are at least two NFC tags on WP Store that can "write tags for launching apps", I've tried them, but the launching is just not working.
So the question is: is it possible to store on NFC tag information for launching any 3rd party app on WP8? If yes, what is the format of such URI scheme and how to write it to a tag using WP8?

Yes, you can launch any Windows Phone 8 app using an NFC tag. You need to put an NDEF message on the tag that has a LaunchApp record as the first record. Set the platform ID in the payload of the NDEF record to "WindowsPhone" and set the app ID to the hex string at the end of Windows Phone store URL between "{" and "}" For example, for http://www.windowsphone.com/en-us/store/app/stackoverflow-feeds/226fcc72-69ff-4a85-b945-cbb7f5ea00af to "{226fcc72-69ff-4a85-b945-cbb7f5ea00af}".
This library can help to create such NDEF records. Limited documentation from MS is available here.

To launch your app via a NFC tag, you need to Register it for a URI association by adding an extension in the WMAppManifest.xml file, like this:
<Extensions>
<Protocol Name="mynfcapp" NavUriFragment="encodedLaunchUri=%s" TaskID="_default" />
</Extensions>
Then you will need to create a URI mapper that can handle the URI association, like this:
public class AssociationUriMapper : UriMapperBase
{
public override Uri MapUri(Uri uri)
{
string url = HttpUtility.UrlDecode(uri.ToString());
if (url.Contains("mynfcapp:MainPage"))
{
int paramIndex = url.IndexOf("source=") + 7;
string paramValue = url.Substring(paramIndex);
return new Uri("/MainPage.xaml?source=" + paramValue, UriKind.Relative);
}
return uri;
}
}
And here is the code to write the NFC tag that will launch the app:
public partial class MainPage : PhoneApplicationPage
{
private readonly ProximityDevice _proximityDevice;
private long subId = 0;
private long pubId = 0;
public MainPage()
{
InitializeComponent();
_proximityDevice = ProximityDevice.GetDefault();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (_proximityDevice != null)
subId = _proximityDevice.SubscribeForMessage("WriteableTag", OnWriteableTagArrived);
base.OnNavigatedTo(e);
}
private void OnWriteableTagArrived(ProximityDevice sender, ProximityMessage message)
{
var dataWriter = new DataWriter();
dataWriter.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf16LE;
string appLauncher = string.Format(#"mynfcapp:MainPage?source=mynfctest");
dataWriter.WriteString(appLauncher);
pubId = sender.PublishBinaryMessage("WindowsUri:WriteTag", dataWriter.DetachBuffer());
}
}

Related

Using libVLCsharp to stream pw protected IP Camera Video but video not playing

I am trying to construct a UI for Onvif complaint devices. I've been beating my head against the wall for sometime now. I believe I have the custom URI correctly constructed. According to the ONVIF Programmers Guide we need to Get Profiles, GetStreamURI, Request Streaming. http://www.openipcam.com/files/ONVIF/ONVIF_WG-APG-Application_Programmer's_Guide.pdf
Using Wireshark I believe I see HTTP packets being sent (showing the appropriate requests), and what I believe are appropriate responses. The final GetStreamURI gets a successful response from the camera. Then when I try to call _mp.Play I see a few packets over HTTP and a few TCP packets back back from the camera. After this communication stops.
using System;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using LibVLCSharp.Shared;
using LibVLCSharp;
using System.ServiceModel.Channels;
using Lib_vlc_CSharp_Onvif.OnvifDevice;
using System.ServiceModel;
using Lib_vlc_CSharp_Onvif.OnvifMedia;
namespace Lib_vlc_CSharp_Onvif
{
public partial class Form1 : Form
{
public LibVLC _libVLC;
public LibVLCSharp.Shared.MediaPlayer _mp;
public LibVLCSharp.Shared.Media media;
//ToDO... make screen size adjustable
public System.Drawing.Size VidSize;
public System.Drawing.Size FormSize;
public System.Drawing.Point OldVidLoc;
//Create Onvif Media Profiles through service references
OnvifMedia.Media2Client Onvif_media;
OnvifMedia.MediaProfile[] profiles;
//Custom URI variable
UriBuilder deviceUri;
public Form1()
{
InitializeComponent();
//LibVLCSharp Specific
Core.Initialize();
this.KeyPreview = true;
//Just controlling the size. TODO: Imp controls
VidSize = videoView.Size;
FormSize = this.Size;
OldVidLoc = videoView.Location;
//Vlc Specific
//Set up the Vlc Lib and then connect the Form1 media window player to the media player of the library.
//videoVew is vlcsharp item in Form1.
_libVLC = new LibVLC();
_mp = new MediaPlayer(_libVLC);
videoView.MediaPlayer = _mp;
}
private void button1_Click(object sender, EventArgs e)
{
//Set up device to get profiles (Onvif Specific)
//Required a custom URI and binding.
deviceUri = new UriBuilder("Http:/onvif/device_service");
System.ServiceModel.Channels.Binding binding;
HttpTransportBindingElement httpTransport = new HttpTransportBindingElement();
httpTransport.AuthenticationScheme = System.Net.AuthenticationSchemes.Digest;
binding = new CustomBinding(new TextMessageEncodingBindingElement(MessageVersion.Soap12, Encoding.UTF8), httpTransport);
//Assign IP Address to device URI. TODO: This eventually will be pulled from user entered value in an text box.
deviceUri.Host = "xxx.xxx.x.x";
DeviceClient Onvif_Device = new DeviceClient(binding, new EndpointAddress(deviceUri.ToString()));
OnvifDevice.Service[] service = Onvif_Device.GetServices(false);
//Check if they contain media and that we have made contact TODO wrap in a try catch block
OnvifDevice.Service xmedia = service.FirstOrDefault(s => s.Namespace == "http://www.onvif.org/ver20/media/wsdl");
if (xmedia != null)
{
Onvif_media = new Media2Client(binding, new EndpointAddress(deviceUri.ToString()));
Onvif_media.ClientCredentials.HttpDigest.ClientCredential.UserName = "admin";
Onvif_media.ClientCredentials.HttpDigest.ClientCredential.Password = "admin";
Onvif_media.ClientCredentials.HttpDigest.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
//Get camera Profiles.
profiles = Onvif_media.GetProfiles(null, null);
if (profiles != null)
{
foreach (var p in profiles)
{
listBox.Items.Add(p.Name);
//Profiles listed in box match profiles setup on camera.
}
}
}
//Eventually add a selection option on the list box.
//listBox.SelectedINdexChanged += OnSelectionChanged
//If we have profiles build a custom URI to past to the vlc boject
if (profiles != null)
{
//Building URI to pass to VLCSharp VideoView Item.
//https://www.onvif.org/ver20/media/wsdl/media.wsdl
//GetSreamUri and define RtspUnicast.
//http://www.openipcam.com/files/ONVIF/ONVIF_WG-APG-Application_Programmer's_Guide.pdf on page 57&58
UriBuilder local_uri = new UriBuilder(Onvif_media.GetStreamUri("RtspUnicast", profiles[0].token));
//ToDO: Build list box to allow user to switch between profiles. Just past main profile for now.
local_uri.Host = deviceUri.Host;
local_uri.Port = deviceUri.Port;
local_uri.Scheme = "rtsp";
//List full URI info.
infoBox.Text = local_uri.Host + local_uri.Port + local_uri.Path;
//Past it to VideoView and start playing video.
_mp.Play(new Media(_libVLC, local_uri.Uri));
}
}
}
}
Update: I believe my issue is the URI I have built requires validation. When I take this URI and put it into a web browser I get a 401 Error. I'm not sure why I don't see this error on wire-shark. I assign the user name and password into URI object but when I check "IsWellFormedURIString" I get an "invalid Port Error."
Did you try --rtsp-user and --rtsp-pwd ? you could also set the RTSP password with the dialog API.
If that doesn't work, please share your full logs.
You should be able to copy/paste the URL from Onvif Device Manager right into VLC and see it play (provided that you entered the correct credentials). If it doesn't, that's already an issue on its own.
You can still assign the Password and Username password.
MyUri.UserName = MyName
MyUri.Password = password
You run into problems when your password has characters like "#"
While I haven't figured out a workaround on this, for the time being keeping the password simple like "MyPassword" instead of "MyPassword#1234" will allow you to use the URI with the name and password built into the string.

Xamarin.UWP local notification not working

I have implemented a code to send Local Notifications for a particular date and time on Android and iOS platform.And, My code is working for Android and iOS platform.In Android,I am using AlarmManager.
and in iOS, UILocationNotification for sending notifications. But , I didn't find any solution for the UWP platform to implement the Local Notification feature
using Dependency Service as i got for Android and iOS platform. Is there any solution for sending local notifications for particular
date and time for all the platforms including "UWP"(mandatory) in Xamarin.forms????
Xamarin.UWP local notification not working
If you want to make Local notification fore Xamarin.Forms, please refer this document. But it has not implement UWP platform. So we need implement schedule notification within uwp and use dependency service to call it. And I have implement a simple you could refer.
interface
public interface INotificationManager
{
int ScheduleNotification(string title, string message,DateTime scheduledTime);
}
Implement
public class UWPNotificationManager : INotificationManager
{
int messageId = -1;
public int ScheduleNotification(string title, string message,DateTime scheduledTime)
{
messageId++;
string TOAST = $#"<toast>
<visual>
<binding template='ToastGeneric'>
<text>{title}</text>
<text>{message}</text>
</binding>
</visual>
<audio src =""ms-winsoundevent:Notification.Mail"" loop=""true""/>
</toast>";
Windows.Data.Xml.Dom.XmlDocument xml = new Windows.Data.Xml.Dom.XmlDocument();
xml.LoadXml(TOAST);
ScheduledToastNotification toast = new ScheduledToastNotification(xml, scheduledTime);
toast.Id = "IdTostone" + messageId.ToString();
toast.Tag = "NotificationOne";
toast.Group = nameof(UWPNotificationManager);
ToastNotificationManager.CreateToastNotifier().AddToSchedule(toast);
return messageId;
}
}
Usage
private void OnScheduleClick(object sender, EventArgs e)
{
notificationNumber++;
string title = $"Local Notification #{notificationNumber}";
string message = $"You have now received {notificationNumber} notifications!";
notificationManager.ScheduleNotification(title, message,DateTime.Now + TimeSpan.FromSeconds(3));
}
Try to use
ToastNotificationManager.CreateToastNotifier().Show(toast);

Push Notification using Amazon SNS – Device id

Developing the mobile app using the Xamarin Forms. For push notification we are using Amazon Simple Notification Service(SNS).
Xamarin.Andriod :
1. While installing the app we have used the below code snippet to register the device id into the Amazon SNS in OnCreate method of MainActivity. It works fine
using (Intent intent = new Intent("com.google.android.c2dm.intent.REGISTER"))
{
string senders = AmazonUtils.GoogleConsoleProjectId;
intent.SetPackage("com.google.android.gsf");
intent.PutExtra("app", PendingIntent.GetBroadcast(this, 0, new Intent(), 0));
intent.PutExtra("sender", senders);
this.StartService(intent);
}
Every time when app opens checking the corresponding device id is registered in the Amazon SNS. Due to this app takes additional 4 secs to check this process and after that page is loading.
Do we need to check the device is register or not for every time when the app opens ?. Is this standard for the push notification ?.
Regards,
Cheran
Install Xam.Plugins.Settings.
It will add a helper class called Settings
In this class you should add:
private const string IsRegisteredKey = "registered_key";
private static readonly bool IsRegisteredDefault = false;
//Then adding this property
public static bool IsRegistered
{
get
{
return AppSettings.GetValueOrDefault(IsRegisteredKey, IsRegisteredDefault);
}
set
{
AppSettings.AddOrUpdateValue(IsRegisteredKey, value);
}
}
Then in your code call this property, like this:
using YourProjectNameSpace.Droid.Helper
....
if(!Settings.IsRegistered)
{
using (Intent intent = new Intent("com.google.android.c2dm.intent.REGISTER"))
{
string senders = AmazonUtils.GoogleConsoleProjectId;
intent.SetPackage("com.google.android.gsf");
intent.PutExtra("app", PendingIntent.GetBroadcast(this, 0, new Intent(), 0));
intent.PutExtra("sender", senders);
this.StartService(intent);
}
Settings.IsRegistered = true;
}

Create a Share button on Windows Phone 8, 8.1 and 10 (Mobile)

How can I create a Share button (that share a defined mesage to another player contact) as the below image on Windows Phone 8, 8.1 and 10 (Mobile):
To create this script to share on Android Device I use the following code:
public class ShareScript : MonoBehaviour {
string subject = "Subject";
string body = "Body";
public void OnAndroidTextSharingClick()
{
StartCoroutine(ShareAndroidText());
}
IEnumerator ShareAndroidText()
{
yield return new WaitForEndOfFrame();
//execute the below lines if being run on a Android device
#if UNITY_ANDROID
//Reference of AndroidJavaClass class for intent
AndroidJavaClass intentClass = new AndroidJavaClass ("android.content.Intent");
//Reference of AndroidJavaObject class for intent
AndroidJavaObject intentObject = new AndroidJavaObject ("android.content.Intent");
//call setAction method of the Intent object created
intentObject.Call<AndroidJavaObject>("setAction", intentClass.GetStatic<string>("ACTION_SEND"));
//set the type of sharing that is happening
intentObject.Call<AndroidJavaObject>("setType", "text/plain");
//add data to be passed to the other activity i.e., the data to be sent
intentObject.Call<AndroidJavaObject>("putExtra", intentClass.GetStatic<string>("EXTRA_SUBJECT"), subject);
//intentObject.Call<AndroidJavaObject>("putExtra", intentClass.GetStatic<string>("EXTRA_TITLE"), "Text Sharing ");
intentObject.Call<AndroidJavaObject>("putExtra", intentClass.GetStatic<string>("EXTRA_TEXT"), body);
//get the current activity
AndroidJavaClass unity = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");
AndroidJavaObject currentActivity = unity.GetStatic<AndroidJavaObject>("currentActivity");
//start the activity by sending the intent data
AndroidJavaObject jChooser = intentClass.CallStatic<AndroidJavaObject>("createChooser", intentObject, "Share Via");
currentActivity.Call("startActivity", jChooser);
#endif
}
}
Call DataTransferManager.ShowShareUI to show the sharing pane.
Handle the DataTransferManager.DataRequested event to provide the data when the user choses to share.
private void DataRequested(DataTransferManager sender, DataRequestedEventArgs e)
{
DataRequest request = e.Request;
request.Data.Properties.Title = "Share Text Example";
request.Data.Properties.Description = "An example of how to share text.";
request.Data.SetText("Hello World!");
}
See the Share data docs on MSDN for more info.
In Unity you can call these in an #if NETFX_CORE block so it runs only when using the Windows Runtime and not Mono. See Windows Store Apps: WinRT API in C# scripts. If you target Windows 10 then there are plug-ins at https://github.com/microsoft/unityplugins which include sharing. For earlier targets there are commercial plugins.

Launch Cordova Windows App with Parameters

Am finding hard to launch Cordova Windows App, from another native Windows App.
Using Protocol invocation, I am passing few parameters to Cordova Windows App, to see if the Cordova app identifies those parameters from the Windows Native App.
Is there anyway to pass Parameters from native Windows App to Cordova App, so that Cordova App identifies the parameters as arguments?
In native windows 8 store app I am using app protocol association to send parameters one app to another app. like
in sender app:
mainpage.xaml.cs on button click
var url = "apptest:?" + name;
Uri uri = new Uri(url);
await Launcher.LaunchUriAsync(uri);
in received app
Package.appxmanifest:
Declarations --> available declarations add --> protocol --> name = apptest
app.xaml.cs
protected override void OnActivated(IActivatedEventArgs args)
{
if (args.Kind == ActivationKind.Protocol)
{
ProtocolActivatedEventArgs protocolArgs = args as ProtocolActivatedEventArgs;
var rootFrame = new Frame();
rootFrame.Navigate(typeof(MainPage), protocolArgs);
Window.Current.Content = rootFrame;
}
Window.Current.Activate();
}
mainpage.xaml.cs
protected override void OnNavigatedTo(NavigationEventArgs e)
{
ProtocolActivatedEventArgs pa = e.Parameter as ProtocolActivatedEventArgs;
if(pa != null)enter code here
{
string qS = pa.Uri.Query;
if (!string.IsNullOrEmpty(qS))
{
Txt_name.Text = qS;
}
}
}
in this way i will take the data from sender app.
Same like is there any way to receive data from windows 10 native app to cordova app. it is very hard to find the solution. not able to find the exact piece of code.

Resources