Merged PR 2918: Update Xamarin sample for release

Update Xamarin sample for release
This commit is contained in:
Nate Peterson 2017-08-29 21:18:29 +00:00
Родитель e18479b65c
Коммит 4f97e92768
11 изменённых файлов: 678 добавлений и 285 удалений

Просмотреть файл

@ -1,22 +1,30 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.25914.0
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConnectedDevices.Xamarin.Droid.Sample", "ConnectedDevices.Xamarin.Droid.Sample\ConnectedDevices.Xamarin.Droid.Sample.csproj", "{DC3ACE32-65E8-4348-A4E2-B5ED08E5932C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{DC3ACE32-65E8-4348-A4E2-B5ED08E5932C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DC3ACE32-65E8-4348-A4E2-B5ED08E5932C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DC3ACE32-65E8-4348-A4E2-B5ED08E5932C}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{DC3ACE32-65E8-4348-A4E2-B5ED08E5932C}.Debug|Any CPU.ActiveCfg = Debug|x86
{DC3ACE32-65E8-4348-A4E2-B5ED08E5932C}.Debug|Any CPU.Build.0 = Debug|x86
{DC3ACE32-65E8-4348-A4E2-B5ED08E5932C}.Debug|Any CPU.Deploy.0 = Debug|x86
{DC3ACE32-65E8-4348-A4E2-B5ED08E5932C}.Debug|x86.ActiveCfg = Debug|x86
{DC3ACE32-65E8-4348-A4E2-B5ED08E5932C}.Debug|x86.Build.0 = Debug|x86
{DC3ACE32-65E8-4348-A4E2-B5ED08E5932C}.Debug|x86.Deploy.0 = Debug|x86
{DC3ACE32-65E8-4348-A4E2-B5ED08E5932C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DC3ACE32-65E8-4348-A4E2-B5ED08E5932C}.Release|Any CPU.Build.0 = Release|Any CPU
{DC3ACE32-65E8-4348-A4E2-B5ED08E5932C}.Release|Any CPU.Deploy.0 = Release|Any CPU
{DC3ACE32-65E8-4348-A4E2-B5ED08E5932C}.Release|x86.ActiveCfg = Release|x86
{DC3ACE32-65E8-4348-A4E2-B5ED08E5932C}.Release|x86.Build.0 = Release|x86
{DC3ACE32-65E8-4348-A4E2-B5ED08E5932C}.Release|x86.Deploy.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

Просмотреть файл

@ -15,8 +15,8 @@
<AndroidApplication>True</AndroidApplication>
<AndroidResgenFile>Resources\Resource.Designer.cs</AndroidResgenFile>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
<AndroidUseLatestPlatformSdk>True</AndroidUseLatestPlatformSdk>
<TargetFrameworkVersion>v6.0</TargetFrameworkVersion>
<AndroidUseLatestPlatformSdk>false</AndroidUseLatestPlatformSdk>
<TargetFrameworkVersion>v7.1</TargetFrameworkVersion>
<AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
@ -30,14 +30,6 @@
<AndroidUseSharedRuntime>True</AndroidUseSharedRuntime>
<AndroidLinkMode>None</AndroidLinkMode>
<EmbedAssembliesIntoApk>False</EmbedAssembliesIntoApk>
<BundleAssemblies>False</BundleAssemblies>
<AndroidCreatePackagePerAbi>False</AndroidCreatePackagePerAbi>
<AndroidSupportedAbis>armeabi;armeabi-v7a</AndroidSupportedAbis>
<Debugger>.Net (Xamarin)</Debugger>
<AotAssemblies>False</AotAssemblies>
<EnableLLVM>False</EnableLLVM>
<AndroidEnableMultiDex>False</AndroidEnableMultiDex>
<EnableProguard>False</EnableProguard>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>PdbOnly</DebugType>
@ -58,10 +50,40 @@
<AndroidEnableMultiDex>False</AndroidEnableMultiDex>
<EnableProguard>False</EnableProguard>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>True</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>Full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<AndroidUseSharedRuntime>False</AndroidUseSharedRuntime>
<AndroidLinkMode>SdkOnly</AndroidLinkMode>
<EmbedAssembliesIntoApk>True</EmbedAssembliesIntoApk>
<BundleAssemblies>False</BundleAssemblies>
<AndroidCreatePackagePerAbi>False</AndroidCreatePackagePerAbi>
<Debugger>.Net (Xamarin)</Debugger>
<AotAssemblies>False</AotAssemblies>
<EnableLLVM>False</EnableLLVM>
<AndroidEnableMultiDex>False</AndroidEnableMultiDex>
<EnableProguard>False</EnableProguard>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>PdbOnly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.ConnectedDevices.Xamarin.Droid, Version=0.4.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.ConnectedDevices.Xamarin.Droid.0.4.0\lib\MonoAndroid44\Microsoft.ConnectedDevices.Xamarin.Droid.dll</HintPath>
<Private>True</Private>
<Reference Include="Microsoft.ConnectedDevices.Xamarin.Droid">
<HintPath>..\Microsoft.ConnectedDevices.Xamarin.Droid.dll</HintPath>
</Reference>
<Reference Include="Mono.Android" />
<Reference Include="mscorlib" />
@ -73,6 +95,7 @@
<ItemGroup>
<Compile Include="MainActivity.cs" />
<Compile Include="RemoteSystemActivity.cs" />
<Compile Include="Secrets.cs" />
<Compile Include="Resources\Resource.Designer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>

Просмотреть файл

@ -9,62 +9,107 @@
//*********************************************************
using System;
using Android.App;
using Android.Content;
using Android.Widget;
using Android.OS;
using Android.Webkit;
using Microsoft.ConnectedDevices;
using System.Collections.Generic;
using System.Linq;
using Android;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Widget;
using Android.Webkit;
using Microsoft.ConnectedDevices;
using Android.Views;
using Android.Content.PM;
namespace ConnectedDevices.Xamarin.Droid.Sample
{
[Activity(Label = "Connected Devices", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : ListActivity
{
// Use your own app id
// private const string APP_ID = ""; //get an app ID from https://apps.dev.microsoft.com/
// Use your own client id. Get a client ID from https://apps.dev.microsoft.com/
private const string CLIENT_ID = Secrets.CLIENT_ID;
private WebView _webView;
internal Dialog _authDialog;
RemoteSystemAdapter _adapter;
internal Dialog authDialog;
private WebView webView;
private RemoteSystemAdapter adapter;
private RemoteSystemWatcher _remoteSystemWatcher;
private List<RemoteSystemKinds> remoteSystemKind = new List<RemoteSystemKinds> { RemoteSystemKinds.Unknown, RemoteSystemKinds.Desktop, RemoteSystemKinds.Holographic, RemoteSystemKinds.Phone, RemoteSystemKinds.Xbox };
private RemoteSystemDiscoveryType remoteSystemDiscoveryKind = RemoteSystemDiscoveryType.Any;
private RemoteSystemWatcher remoteSystemWatcher;
private Button refreshButton;
private int permissionRequestCode;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
this.SetContentView(Resource.Layout.Main);
Button callButton = FindViewById<Button>(Resource.Id.RefreshButton);
callButton.Click += (object sender, EventArgs e) =>
refreshButton = FindViewById<Button>(Resource.Id.RefreshButton);
refreshButton.Enabled = false;
refreshButton.Click += (object sender, EventArgs e) =>
{
RefreshDevices();
};
if(string.IsNullOrEmpty(APP_ID))
if (string.IsNullOrEmpty(CLIENT_ID))
{
Toast.MakeText(this, "APP_ID not set!", ToastLength.Long).Show();
Toast.MakeText(this, "CLIENT_ID not set!", ToastLength.Long).Show();
}
InitializeAsync();
// Prompt for location permission if it hasn't been granted
if (CheckSelfPermission(Manifest.Permission.AccessCoarseLocation) == Permission.Granted)
{
this.InitializeAsync();
}
else
{
Random rand = new Random();
this.permissionRequestCode = rand.Next(128);
RequestPermissions(new string[] { Manifest.Permission.AccessCoarseLocation }, this.permissionRequestCode);
}
_adapter = new RemoteSystemAdapter(this, new List<RemoteSystem>());
this.ListAdapter = _adapter;
this.adapter = new RemoteSystemAdapter(this, new List<RemoteSystem>());
this.ListAdapter = this.adapter;
}
public override async void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
{
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == this.permissionRequestCode)
{
// Platform handles if no permission granted for bluetooth, no need to do anything special.
this.permissionRequestCode = -1;
this.InitializeAsync();
}
}
protected override void OnListItemClick(ListView l, View v, int position, long id)
{
var detailsActivity = new Intent(this, typeof(RemoteSystemActivity));
RemoteSystem selectedDevice = adapter.GetItem(position);
ConnectedDevicesApplication.SelectedRemoteSystem = selectedDevice;
StartActivity(detailsActivity);
}
internal async void InitializeAsync()
{
Platform.FetchAuthCode += Platform_FetchAuthCode;
var result = await Platform.InitializeAsync(this.ApplicationContext, APP_ID);
var result = await Platform.InitializeAsync(this.ApplicationContext, CLIENT_ID);
if (result == true)
{
Console.WriteLine("Initialized platform successfully");
refreshButton.Enabled = true;
InitializeSpinners();
RefreshDevices();
}
else
@ -73,48 +118,136 @@ namespace ConnectedDevices.Xamarin.Droid.Sample
}
}
private void Platform_FetchAuthCode(string oauthUrl)
{
_authDialog = new Dialog(this);
var linearLayout = new LinearLayout(_authDialog.Context);
_webView = new WebView(_authDialog.Context);
linearLayout.AddView(_webView);
_authDialog.SetContentView(linearLayout);
_webView.SetWebChromeClient(new WebChromeClient());
_webView.Settings.JavaScriptEnabled = true;
_webView.Settings.DomStorageEnabled = true;
_webView.LoadUrl(oauthUrl);
_webView.SetWebViewClient(new MsaWebViewClient(this));
_authDialog.Show();
_authDialog.SetCancelable(true);
}
internal void RefreshDevices()
{
_adapter.Clear();
DiscoverDevices();
adapter.Clear();
DiscoverDevices();
}
private RemoteSystemDiscoveryType StringToDiscoveryType(string str)
{
RemoteSystemDiscoveryType kind = RemoteSystemDiscoveryType.Any;
switch (str)
{
case "All":
kind = RemoteSystemDiscoveryType.Any;
break;
case "Cloud":
kind = RemoteSystemDiscoveryType.Cloud;
break;
case "Proximal":
kind = RemoteSystemDiscoveryType.Proximal;
break;
}
return kind;
}
private List<RemoteSystemKinds> StringToSystemKind(string str)
{
List<RemoteSystemKinds> kinds = new List<RemoteSystemKinds> { RemoteSystemKinds.Unknown };
switch (str)
{
case "All":
kinds = new List<RemoteSystemKinds> { RemoteSystemKinds.Unknown, RemoteSystemKinds.Desktop, RemoteSystemKinds.Holographic, RemoteSystemKinds.Phone, RemoteSystemKinds.Xbox };
break;
case "Unknown":
kinds = new List<RemoteSystemKinds> { RemoteSystemKinds.Unknown };
break;
case "Desktop":
kinds = new List<RemoteSystemKinds> { RemoteSystemKinds.Desktop };
break;
case "Holographic":
kinds = new List<RemoteSystemKinds> { RemoteSystemKinds.Holographic };
break;
case "Phone":
kinds = new List<RemoteSystemKinds> { RemoteSystemKinds.Phone };
break;
case "Xbox":
kinds = new List<RemoteSystemKinds> { RemoteSystemKinds.Xbox };
break;
}
return kinds;
}
private void InitializeSpinners()
{
Spinner discoveryTypeSpinner = FindViewById<Spinner>(Resource.Id.discovery_type_filter_spinner);
discoveryTypeSpinner.ItemSelected += new EventHandler<AdapterView.ItemSelectedEventArgs>(DiscoveryTypeItemSelected);
var discoveryTypeAdapter = ArrayAdapter.CreateFromResource(this, Resource.Array.discovery_type_filter_array, Android.Resource.Layout.SimpleSpinnerItem);
discoveryTypeAdapter.SetDropDownViewResource(Android.Resource.Layout.SimpleSpinnerDropDownItem);
discoveryTypeSpinner.Adapter = discoveryTypeAdapter;
discoveryTypeSpinner.SetSelection(0);
Spinner systemKindSpinner = FindViewById<Spinner>(Resource.Id.system_kind_filter_spinner);
systemKindSpinner.ItemSelected += new EventHandler<AdapterView.ItemSelectedEventArgs>(SystemKindItemSelected);
var systemKindAdapter = ArrayAdapter.CreateFromResource(this, Resource.Array.system_kind_filter_array, Android.Resource.Layout.SimpleSpinnerItem);
systemKindAdapter.SetDropDownViewResource(Android.Resource.Layout.SimpleSpinnerDropDownItem);
systemKindSpinner.Adapter = systemKindAdapter;
systemKindSpinner.SetSelection(0);
}
private void DiscoveryTypeItemSelected(object sender, AdapterView.ItemSelectedEventArgs e)
{
Spinner spinner = (Spinner)sender;
string discoveryTypeStr = spinner.GetItemAtPosition(e.Position).ToString();
remoteSystemDiscoveryKind = StringToDiscoveryType(discoveryTypeStr);
RefreshDevices();
}
private void SystemKindItemSelected(object sender, AdapterView.ItemSelectedEventArgs e)
{
Spinner spinner = (Spinner)sender;
string systemKindStr = spinner.GetItemAtPosition(e.Position).ToString();
remoteSystemKind = StringToSystemKind(systemKindStr);
RefreshDevices();
}
private void Platform_FetchAuthCode(string oauthUrl)
{
authDialog = new Dialog(this);
var linearLayout = new LinearLayout(authDialog.Context);
webView = new WebView(authDialog.Context);
linearLayout.AddView(webView);
authDialog.SetContentView(linearLayout);
webView.SetWebChromeClient(new WebChromeClient());
webView.Settings.JavaScriptEnabled = true;
webView.Settings.DomStorageEnabled = true;
webView.LoadUrl(oauthUrl);
webView.SetWebViewClient(new MsaWebViewClient(this));
authDialog.Show();
authDialog.SetCancelable(true);
}
private void DiscoverDevices()
{
_remoteSystemWatcher = RemoteSystem.CreateWatcher();
if (remoteSystemWatcher != null)
{
remoteSystemWatcher.Stop();
}
_remoteSystemWatcher.RemoteSystemAdded += RemoteSystemWatcherOnRemoteSystemAdded;
_remoteSystemWatcher.RemoteSystemRemoved += RemoteSystemWatcher_RemoteSystemRemoved;
_remoteSystemWatcher.RemoteSystemUpdated += RemoteSystemWatcher_RemoteSystemUpdated;
var filters = new List<IRemoteSystemFilter> { new RemoteSystemKindFilter(remoteSystemKind), new RemoteSystemDiscoveryTypeFilter(remoteSystemDiscoveryKind) };
remoteSystemWatcher = RemoteSystem.CreateWatcher(filters);
_remoteSystemWatcher.Start();
remoteSystemWatcher.RemoteSystemAdded += RemoteSystemWatcherOnRemoteSystemAdded;
remoteSystemWatcher.RemoteSystemRemoved += RemoteSystemWatcher_RemoteSystemRemoved;
remoteSystemWatcher.RemoteSystemUpdated += RemoteSystemWatcher_RemoteSystemUpdated;
remoteSystemWatcher.Start();
}
private void RemoteSystemWatcher_RemoteSystemUpdated(RemoteSystemWatcher watcher, RemoteSystemUpdatedEventArgs args)
{
RunOnUiThread(() =>
{
_adapter.Remove(_adapter.Items.FirstOrDefault(system => system.Id == args.P0.Id));
_adapter.Add(args.P0);
adapter.Remove(adapter.Items.FirstOrDefault(system => system.Id == args.P0.Id));
adapter.Add(args.P0);
}
);
}
@ -122,28 +255,16 @@ namespace ConnectedDevices.Xamarin.Droid.Sample
private void RemoteSystemWatcher_RemoteSystemRemoved(RemoteSystemWatcher watcher, RemoteSystemRemovedEventArgs args)
{
RunOnUiThread(() =>
_adapter.Remove(_adapter.Items.FirstOrDefault(system => system.Id == args.P0))
adapter.Remove(adapter.Items.FirstOrDefault(system => system.Id == args.P0))
);
}
private void RemoteSystemWatcherOnRemoteSystemAdded(RemoteSystemWatcher watcher, RemoteSystemAddedEventArgs args)
{
RunOnUiThread(() => _adapter.Add(args.P0));
RunOnUiThread(() => adapter.Add(args.P0));
}
protected override void OnListItemClick(ListView l, View v, int position, long id)
{
var detailsActivity = new Intent(this, typeof(RemoteSystemActivity));
RemoteSystem selectedDevice = _adapter.GetItem(position);
ConnectedDevicesApplication.SelectedRemoteSystem = selectedDevice;
StartActivity(detailsActivity);
}
}
public class RemoteSystemAdapter : ArrayAdapter<RemoteSystem>
{
private static readonly Dictionary<RemoteSystemKinds, int> RemoteSystemKindImages = new Dictionary<RemoteSystemKinds, int>
@ -170,8 +291,12 @@ namespace ConnectedDevices.Xamarin.Droid.Sample
var item = this.GetItem(position);
View view = convertView;
if (view == null) // no view to re-use, create new
// no view to re-use, create new
if (view == null)
{
view = context.LayoutInflater.Inflate(Resource.Layout.RemoteSystemView, null);
}
view.FindViewById<TextView>(Resource.Id.Text1).Text = item.DisplayName;
view.FindViewById<TextView>(Resource.Id.Text2).Text = item.IsAvailableByProximity ? "Proximal" : "Cloud";
int id = RemoteSystemKindImages.ContainsKey(item.Kind) ? RemoteSystemKindImages[item.Kind] : RemoteSystemKindImages[RemoteSystemKinds.Unknown];
@ -185,10 +310,10 @@ namespace ConnectedDevices.Xamarin.Droid.Sample
{
bool authComplete = false;
private readonly MainActivity _parentActivity;
private readonly MainActivity parentActivity;
public MsaWebViewClient(MainActivity activity)
{
_parentActivity = activity;
this.parentActivity = activity;
}
public override void OnPageFinished(WebView view, string url)
@ -201,7 +326,7 @@ namespace ConnectedDevices.Xamarin.Droid.Sample
var uri = Android.Net.Uri.Parse(url);
string token = uri.GetQueryParameter("code");
_parentActivity._authDialog.Dismiss();
this.parentActivity.authDialog.Dismiss();
Platform.SetAuthCode(token);
}
else if (url.Contains("error=access_denied"))
@ -209,10 +334,9 @@ namespace ConnectedDevices.Xamarin.Droid.Sample
authComplete = true;
Console.WriteLine("Page finished failed with ACCESS_DENIED_HERE");
Intent resultIntent = new Intent();
_parentActivity.SetResult(0, resultIntent);
_parentActivity._authDialog.Dismiss();
this.parentActivity.SetResult(0, resultIntent);
this.parentActivity.authDialog.Dismiss();
}
}
}
internal class ConnectedDevicesApplication
@ -220,4 +344,3 @@ namespace ConnectedDevices.Xamarin.Droid.Sample
public static RemoteSystem SelectedRemoteSystem { get; internal set; }
}
}

Просмотреть файл

@ -1,6 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="ConnectedDevices.Xamarin" android:versionCode="2" android:versionName="1.0.2">
<uses-sdk android:minSdkVersion="16" />
<application android:label="ConnectedDevices.Xamarin"></application>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.microsoft.romanapp.xamarin" android:versionCode="2" android:versionName="1.0.2" android:installLocation="auto">
<uses-sdk android:minSdkVersion="19" />
<application android:label="com.microsoft.romanapp.xamarin"></application>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
</manifest>

Просмотреть файл

@ -20,11 +20,19 @@ namespace ConnectedDevices.Xamarin.Droid.Sample
[Activity(Label = "Remote System Details")]
public class RemoteSystemActivity : Activity
{
private const string AppService = ""; // Fill in your app service name
private const string AppIdentifier = ""; // Fill in your app identifier
// Your app service name
private const string AppService = Secrets.AppService;
// Your app identifier
private const string AppIdentifier = Secrets.AppIdentifier;
private string id;
private AppServiceClientConnection appServiceClientConnection;
private AppServiceConnection appServiceConnection;
private TextView launchLog;
private EditText textBox;
private Button pingBtn;
private long messageId = 0;
protected override void OnCreate(Bundle savedInstanceState)
{
@ -35,63 +43,108 @@ namespace ConnectedDevices.Xamarin.Droid.Sample
var remoteSystem = ConnectedDevicesApplication.SelectedRemoteSystem;
if (remoteSystem != null)
{
FindViewById<TextView>(Resource.Id.detailed_name_text).Text = remoteSystem.DisplayName;
FindViewById<TextView>(Resource.Id.detailed_id_text).Text = remoteSystem.Id;
FindViewById<TextView>(Resource.Id.detailed_kind_text).Text = (string)remoteSystem.Kind;
FindViewById<TextView>(Resource.Id.detailed_proximity_text).Text = remoteSystem.IsAvailableByProximity ? "True" : "False";
FindViewById<TextView>(Resource.Id.device_name).Text = remoteSystem.DisplayName;
FindViewById<TextView>(Resource.Id.device_type).Text = (string)remoteSystem.Kind;
SetPingText(this as Activity, string.Empty);
Button launchBtn = FindViewById<Button>(Resource.Id.detailed_launch_button);
launchBtn.Click += delegate
{
EditText textBox = (EditText)FindViewById(Resource.Id.detailed_url_text);
string uri = textBox.Text;
this.launchLog = (TextView)FindViewById(Resource.Id.launch_log);
this.textBox = (EditText)FindViewById(Resource.Id.launch_uri_edit_text);
Console.WriteLine("Launching URI");
this.RemoteLaunchUriAsync(ConnectedDevicesApplication.SelectedRemoteSystem, new Uri(uri));
};
Button connectBtn = FindViewById<Button>(Resource.Id.detailed_connect_button);
connectBtn.Click += delegate
{
Console.WriteLine("Attempting connection to AppService");
this.ConnectAppService(AppService, AppIdentifier, new RemoteSystemConnectionRequest(ConnectedDevicesApplication.SelectedRemoteSystem));
};
Button pingBtn = FindViewById<Button>(Resource.Id.detailed_ping_button);
pingBtn.Click += delegate
{
Console.WriteLine("Sending ping message using AppServices");
this.SendPingMessage();
};
InitializeButtons();
InitializeSpinner();
}
}
private static void SetPingText(Activity activity, string text)
{
activity.FindViewById<TextView>(Resource.Id.detailed_ping_text).Text = text;
activity.FindViewById<TextView>(Resource.Id.ping_value).Text = text;
}
private void InitializeButtons()
{
Button launchBtn = FindViewById<Button>(Resource.Id.launch_uri_btn);
launchBtn.Click += delegate
{
string uri = this.textBox.Text;
Console.WriteLine("Launching URI");
this.RemoteLaunchUriAsync(ConnectedDevicesApplication.SelectedRemoteSystem, new Uri(uri));
};
Button connectBtn = FindViewById<Button>(Resource.Id.open_connection_btn);
connectBtn.Click += delegate
{
Console.WriteLine("Attempting connection to AppService");
this.ConnectAppService(AppService, AppIdentifier, new RemoteSystemConnectionRequest(ConnectedDevicesApplication.SelectedRemoteSystem));
};
this.pingBtn = FindViewById<Button>(Resource.Id.send_ping_btn);
this.pingBtn.Click += delegate
{
Console.WriteLine("Sending ping message using AppServices");
this.SendPingMessage();
};
}
private void InitializeSpinner()
{
Spinner uriSpinner = FindViewById<Spinner>(Resource.Id.launch_uri_spinner);
uriSpinner.ItemSelected += new EventHandler<AdapterView.ItemSelectedEventArgs>(spinner_ItemSelected);
var adapter = ArrayAdapter.CreateFromResource(this, Resource.Array.uri_array, Android.Resource.Layout.SimpleSpinnerItem);
adapter.SetDropDownViewResource(Android.Resource.Layout.SimpleSpinnerDropDownItem);
uriSpinner.Adapter = adapter;
uriSpinner.SetSelection(0);
}
private void spinner_ItemSelected(object sender, AdapterView.ItemSelectedEventArgs e)
{
if (this.textBox == null)
{
return;
}
Spinner spinner = (Spinner)sender;
string url = spinner.GetItemAtPosition(e.Position).ToString();
this.textBox.SetText(url.ToCharArray(), 0, url.Length);
}
private async void RemoteLaunchUriAsync(RemoteSystem remoteSystem, Uri uri)
{
this.LogMessage("Launching URI: " + uri + " on " + remoteSystem.DisplayName);
var launchUriStatus = await RemoteLauncher.LaunchUriAsync(new RemoteSystemConnectionRequest(remoteSystem), uri);
if (launchUriStatus != RemoteLaunchUriStatus.Success)
if (launchUriStatus == RemoteLaunchUriStatus.Success)
{
Console.WriteLine("Failed to Launch!");
this.LogMessage("Launch succeeded");
}
else
{
this.LogMessage("Launch failed due to [" + launchUriStatus.ToString() + "]");
}
}
private async void ConnectAppService(string appService, string appIdentifier, RemoteSystemConnectionRequest connectionRequest)
{
this.appServiceClientConnection = new AppServiceClientConnection(appService, appIdentifier, connectionRequest);
this.appServiceConnection = new AppServiceConnection(appService, appIdentifier, connectionRequest);
this.appServiceConnection.RequestReceived += AppServiceConnectionRequestReceived;
this.id = connectionRequest.RemoteSystem.Id;
try
{
var status = await this.appServiceClientConnection.OpenRemoteAsync();
Console.WriteLine("App Service connection returned with status " + status.ToString());
this.LogMessage("Sending AppServices connection request. Waiting for connection response");
var status = await this.appServiceConnection.OpenRemoteAsync();
if (status == AppServiceConnectionStatus.Success)
{
this.LogMessage("App Service connection successful!");
this.pingBtn.Enabled = true;
}
else
{
this.LogMessage("App Service connection failed, returning status " + status.ToString());
}
}
catch (ConnectedDevicesException e)
{
@ -100,20 +153,51 @@ namespace ConnectedDevices.Xamarin.Droid.Sample
}
}
private Bundle CreatePingMessage()
{
Bundle bundle = new Bundle();
bundle.PutString("Type", "ping");
bundle.PutString("CreationDate", DateTime.Now.ToString(CultureInfo.InvariantCulture));
bundle.PutString("TargetId", this.id);
return bundle;
}
private Bundle CreatePongMessage(Bundle bundle)
{
bundle.PutString("Type", "pong");
return bundle;
}
private async void AppServiceConnectionRequestReceived(AppServiceRequest request)
{
this.LogMessage("Received AppService request. Sending response.");
var status = await request.SendResponseAsync(this.CreatePongMessage(request.Message));
if (status == AppServiceResponseStatus.Success)
{
this.LogMessage("Successfully sent response.");
}
else
{
this.LogMessage("Failed to send response.");
}
}
private async void SendPingMessage()
{
Bundle message = new Bundle();
message.PutString("Type", "ping");
message.PutString("CreationDate", DateTime.Now.ToString(CultureInfo.InvariantCulture));
message.PutString("TargetId", this.id);
long id = ++this.messageId;
try
{
var response = await this.appServiceClientConnection.SendMessageAsync(message);
this.LogMessage("Sending AppServices message [" + id.ToString() + "]. Waiting for ping response");
var response = await this.appServiceConnection.SendMessageAsync(this.CreatePingMessage());
AppServiceResponseStatus status = response.Status;
if (status == AppServiceResponseStatus.Success)
{
this.LogMessage("Received successful AppService response to message [" + id.ToString() + "]");
Bundle bundle = response.Message;
string type = bundle.GetString("Type");
DateTime creationDate = DateTime.Parse(bundle.GetString("CreationDate"));
@ -127,6 +211,10 @@ namespace ConnectedDevices.Xamarin.Droid.Sample
SetPingText(this as Activity, diff.ToString());
});
}
else
{
this.LogMessage("Did not receive successful AppService response");
}
}
catch (ConnectedDevicesException e)
{
@ -134,5 +222,27 @@ namespace ConnectedDevices.Xamarin.Droid.Sample
e.PrintStackTrace();
}
}
private void LogMessage(string message)
{
if (this.launchLog == null)
{
return;
}
Console.WriteLine(message);
String newText = "\n" + message + " [" + this.GetTimeStamp() + "]";
// UI elements can only be modified on the UI thread.
this.RunOnUiThread(() =>
{
this.launchLog.Append(newText);
});
}
private string GetTimeStamp()
{
return DateTime.Now.ToString("HH:mm:ss.fff");
}
}
}

Просмотреть файл

@ -28,6 +28,28 @@ namespace ConnectedDevices.Xamarin.Droid.Sample
{
}
public partial class Array
{
// aapt resource value: 0x7f050001
public const int discovery_type_filter_array = 2131034113;
// aapt resource value: 0x7f050002
public const int system_kind_filter_array = 2131034114;
// aapt resource value: 0x7f050000
public const int uri_array = 2131034112;
static Array()
{
global::Android.Runtime.ResourceIdManager.UpdateIdValues();
}
private Array()
{
}
}
public partial class Attribute
{
@ -81,53 +103,77 @@ namespace ConnectedDevices.Xamarin.Droid.Sample
public partial class Id
{
// aapt resource value: 0x7f05000c
public const int Image = 2131034124;
// aapt resource value: 0x7f060014
public const int Image = 2131099668;
// aapt resource value: 0x7f050000
public const int RefreshButton = 2131034112;
// aapt resource value: 0x7f060003
public const int RefreshButton = 2131099651;
// aapt resource value: 0x7f05000d
public const int Text = 2131034125;
// aapt resource value: 0x7f060015
public const int Text = 2131099669;
// aapt resource value: 0x7f05000e
public const int Text1 = 2131034126;
// aapt resource value: 0x7f060016
public const int Text1 = 2131099670;
// aapt resource value: 0x7f05000f
public const int Text2 = 2131034127;
// aapt resource value: 0x7f060017
public const int Text2 = 2131099671;
// aapt resource value: 0x7f05000a
public const int detailed_connect_button = 2131034122;
// aapt resource value: 0x7f060004
public const int device_card = 2131099652;
// aapt resource value: 0x7f050002
public const int detailed_id_text = 2131034114;
// aapt resource value: 0x7f060005
public const int device_name = 2131099653;
// aapt resource value: 0x7f050003
public const int detailed_kind_text = 2131034115;
// aapt resource value: 0x7f060006
public const int device_type = 2131099654;
// aapt resource value: 0x7f050006
public const int detailed_launch_button = 2131034118;
// aapt resource value: 0x7f060001
public const int discovery_type_filter_spinner = 2131099649;
// aapt resource value: 0x7f050001
public const int detailed_name_text = 2131034113;
// aapt resource value: 0x7f060007
public const int feedback_btn = 2131099655;
// aapt resource value: 0x7f05000b
public const int detailed_ping_button = 2131034123;
// aapt resource value: 0x7f060000
public const int filter_layout = 2131099648;
// aapt resource value: 0x7f050008
public const int detailed_ping_text = 2131034120;
// aapt resource value: 0x7f060013
public const int launch_log = 2131099667;
// aapt resource value: 0x7f050004
public const int detailed_proximity_text = 2131034116;
// aapt resource value: 0x7f06000c
public const int launch_uri_btn = 2131099660;
// aapt resource value: 0x7f050005
public const int detailed_url_text = 2131034117;
// aapt resource value: 0x7f06000a
public const int launch_uri_button_layout = 2131099658;
// aapt resource value: 0x7f050009
public const int linearLayout1 = 2131034121;
// aapt resource value: 0x7f060008
public const int launch_uri_card = 2131099656;
// aapt resource value: 0x7f050007
public const int linearLayout2 = 2131034119;
// aapt resource value: 0x7f06000b
public const int launch_uri_edit_text = 2131099659;
// aapt resource value: 0x7f060009
public const int launch_uri_spinner = 2131099657;
// aapt resource value: 0x7f060011
public const int open_connection_btn = 2131099665;
// aapt resource value: 0x7f060010
public const int ping_buttons_layout = 2131099664;
// aapt resource value: 0x7f06000d
public const int ping_card = 2131099661;
// aapt resource value: 0x7f06000e
public const int ping_layout = 2131099662;
// aapt resource value: 0x7f06000f
public const int ping_value = 2131099663;
// aapt resource value: 0x7f060012
public const int send_ping_btn = 2131099666;
// aapt resource value: 0x7f060002
public const int system_kind_filter_spinner = 2131099650;
static Id()
{

Просмотреть файл

@ -3,6 +3,31 @@
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:id="@+id/filter_layout"
android:weightSum="1" >
<Spinner
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight=".5"
android:layout_alignParentLeft="true"
android:id="@+id/discovery_type_filter_spinner" />
<Spinner
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight=".5"
android:layout_alignParentRight="true"
android:layout_below="@+id/discovery_type_filter_spinner"
android:id="@+id/system_kind_filter_spinner" />
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"

Просмотреть файл

@ -1,141 +1,149 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="16dp">
<!-- Dummy view -->
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:focusable="true"
android:focusableInTouchMode="true" />
<ScrollView
android:padding="16dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_height="wrap_content"
android:id="@+id/device_card">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- First Box -->
android:padding="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/device_name"
android:layout_alignParentTop="true"
android:hint="name"
android:textSize="24sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/device_type"
android:hint="type"
android:layout_below="@+id/device_name" />
<Button
android:layout_width="wrap_content"
android:layout_height="45dp"
android:padding="6dp"
android:id="@+id/feedback_btn"
android:enabled="false"
android:textSize="6pt"
android:text="Feedback"
android:layout_alignParentRight="true" />
</RelativeLayout>
</LinearLayout>
<LinearLayout
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/launch_uri_card">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp">
<Spinner
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/launch_uri_spinner" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:background="@drawable/detail_border"
android:orientation="vertical"
android:padding="5dp">
<TextView
android:id="@+id/detailed_name_text"
android:layout_width="match_parent"
android:layout_centerHorizontal="true"
android:layout_below="@+id/launch_uri_spinner"
android:id="@+id/launch_uri_button_layout">
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="25sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Id: "
android:textStyle="bold" />
<TextView
android:id="@+id/detailed_id_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Kind: "
android:textStyle="bold" />
<TextView
android:id="@+id/detailed_kind_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:text="Proximal: "
android:textStyle="bold" />
<TextView
android:id="@+id/detailed_proximity_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
android:inputType="text"
android:text="http://bing.com"
android:id="@+id/launch_uri_edit_text"
android:layout_below="@+id/launch_uri_spinner" />
<Button
android:layout_width="wrap_content"
android:layout_height="60dp"
android:padding="10dp"
android:id="@+id/launch_uri_btn"
android:textSize="8pt"
android:text="Launch URI"
android:layout_below="@+id/launch_uri_edit_text" />
</LinearLayout>
</RelativeLayout>
</LinearLayout>
<LinearLayout
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/ping_card">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:background="@drawable/detail_border"
android:orientation="vertical"
android:padding="5dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Launcher"
android:textSize="25sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="@+id/detailed_url_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:inputType="textUri"
android:text="http://bing.com/" />
<Button
android:id="@+id/detailed_launch_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Launch Uri" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:background="@drawable/detail_border"
android:orientation="vertical"
android:padding="5dp"
android:id="@+id/linearLayout2">
android:id="@+id/ping_layout"
android:layout_centerHorizontal="true">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Ping:"
android:textSize="25sp" />
android:layout_below="@+id/device_name"
android:textSize="18sp" />
<TextView
android:id="@+id/detailed_ping_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="25sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:id="@+id/linearLayout1">
<Button
android:id="@+id/detailed_connect_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Connect" />
<Button
android:id="@+id/detailed_ping_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Send Ping" />
</LinearLayout>
android:id="@+id/ping_value"
android:hint="unknown"
android:layout_below="@+id/device_name"
android:paddingLeft="10dp"
android:textSize="18sp"
android:textStyle="normal|italic"
android:fontFamily="sans-serif" />
</LinearLayout>
</LinearLayout>
</ScrollView>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_below="@+id/ping_layout"
android:id="@+id/ping_buttons_layout">
<Button
android:layout_width="wrap_content"
android:layout_height="60dp"
android:padding="10dp"
android:layout_margin="10dp"
android:id="@+id/open_connection_btn"
android:textSize="8pt"
android:text="Connect"
android:layout_alignParentLeft="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="60dp"
android:padding="10dp"
android:layout_margin="10dp"
android:id="@+id/send_ping_btn"
android:enabled="false"
android:textSize="8pt"
android:text="Send Ping"
android:layout_alignParentRight="true" />
</RelativeLayout>
</RelativeLayout>
</LinearLayout>
<LinearLayout
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<TextView
android:id="@+id/launch_log"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</ScrollView>
</LinearLayout>
</LinearLayout>

Просмотреть файл

@ -1,4 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="ApplicationName">Connected Devices</string>
<string-array name="uri_array">
<item>http://microsoft.com</item>
<item>http://bing.com</item>
<item>http://xbox.com</item>
<item>ms-settings:crossdevice</item>
<item>ms-settings:about</item>
</string-array>
<string-array name="discovery_type_filter_array">
<item>All</item>
<item>Cloud</item>
<item>Proximal</item>
</string-array>
<string-array name="system_kind_filter_array">
<item>All</item>
<item>Desktop</item>
<item>Holographic</item>
<item>Phone</item>
<item>Xbox</item>
</string-array>
</resources>

Просмотреть файл

@ -0,0 +1,22 @@
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
namespace ConnectedDevices.Xamarin.Droid.Sample
{
public class Secrets
{
// Get a client ID from https://apps.dev.microsoft.com/
public const string CLIENT_ID = "";
// Fill in your app service name
public const string AppService = "";
// Fill in your app identifier
public const string AppIdentifier = "";
}
}

Просмотреть файл

@ -1,4 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.ConnectedDevices.Xamarin.Droid" version="0.4.0" targetFramework="monoandroid71" />
<package id="Xamarin.Android.Support.Compat" version="25.1.1" targetFramework="monoandroid71" />
<package id="Xamarin.Android.Support.Core.UI" version="25.1.1" targetFramework="monoandroid71" />
<package id="Xamarin.Android.Support.Core.Utils" version="25.1.1" targetFramework="monoandroid71" />
<package id="Xamarin.Android.Support.Fragment" version="25.1.1" targetFramework="monoandroid71" />
<package id="Xamarin.Android.Support.Media.Compat" version="25.1.1" targetFramework="monoandroid71" />
<package id="Xamarin.Android.Support.v4" version="25.1.1" targetFramework="monoandroid71" />
<package id="Xamarin.Build.Download" version="0.4.2" targetFramework="monoandroid71" />
</packages>