I'm developing windows phone 8 application. In which I have to share the application's download link on Facebook and Twitter.
Before publishing the application on to the windows phone store, How could I know the download link of the application.
Because we have to implement the share functionality before publishing the application.
I'm looking forward for your responses.
Thanks & Regards,
Suresh
Basically your application download link format is as follow :
http://windowsphone.com/s?appid=<ApplicationId>
with <ApplicationId> is value of ProductID attribute of App element in WMAppManifest.xml file. That ProductID in WMAppManifest.xml will be overridden when you submit the Apps to Marketplace, so avoid hardcoding it. This post demonstrates how to get <ApplicationId> from manifest file as well as how to share it using Microsoft.Phone.Tasks.ShareLinkTask.
UPDATE :
To summarize, create a helper class to read ApplicationID from WMAppManifest.xml file :
public class DeepLinkHelper
{
private const string AppManifestName = "WMAppManifest.xml";
private const string AppNodeName = "App";
private const string AppProductIDAttributeName = "ProductID";
public static string BuildApplicationDeepLink()
{
var applicationId = Guid.Parse(GetManifestAttributeValue(AppProductIDAttributeName));
return BuildApplicationDeepLink(applicationId.ToString());
}
public static string BuildApplicationDeepLink(string applicationId)
{
return #"http://windowsphone.com/s?appid=" + applicationId;
}
public static string GetManifestAttributeValue(string attributeName)
{
var xmlReaderSettings = new XmlReaderSettings
{
XmlResolver = new XmlXapResolver()
};
using (var xmlReader = XmlReader.Create(AppManifestName, xmlReaderSettings))
{
xmlReader.ReadToDescendant(AppNodeName);
if (!xmlReader.IsStartElement())
{
throw new FormatException(AppManifestName + " is missing " + AppNodeName);
}
return xmlReader.GetAttribute(attributeName);
}
}
}
Then you can get/share download link this way :
new Microsoft.Phone.Tasks.ShareLinkTask()
{
Title = "My Application Deep Link",
Message = "My Application Deep Link",
LinkUri = new Uri(DeepLinkHelper.BuildApplicationDeepLink())
}.Show();
Credit to Pedro Lamas for all above codes.
Related
I have several accounts configured in Outlook. Now I am trying to get the StoreID of an Outlook mailItem. For example if I select a message from the inbox folder of an account, let's say, account1, I want to get its StoreID, and if I select a message from the inbox folder of another Outlook account, let's say, account2, I want to get the its corresponding StoreID.
I have created an extension method to get the StoreID:
public static string GetStoreID(this Outlook.MailItem omi)
{
Outlook.Folder folder = null;
Outlook.Store store = null;
string storeID = null;
try
{
folder = (Outlook.Folder)omi.Parent;
store = folder.Store;
storeID = store.StoreID;
}
catch (Exception ex)
{
Log.Error("GetStoreID: An error occurred while getting mail item storeID. " + ex.ToString());
}
finally
{
folder = null;
store = null;
}
return storeID;
}
Is it correct or is there any other way which is better?
Your method is fine. Or you can make it even faster - simply retrieve the PR_STORE_ENTRYID MAPI property (DASL name "http://schemas.microsoft.com/mapi/proptag/0x0FFB0102") using MailItem.PropertyAccessor.GetProperty and convert it to a string using MailItem.PropertyAccessor.BinaryToString.
Your code works, so it appears you are asking for any other approach you could take to get the StoreID string.
Whether one approach is "better" than any other approach is purely subjective and entirely context specific.
Another way you could do this, would be to instead get the StoreID from the Explorer object (rather than the MailItem). If you have an "Explorer Wrapper" class in your add-in, you could have something like the following for your backing-fields and constructor:
private Outlook.Explorer _myExplorer;
private Outlook.Folder _myFolder;
private Outlook.Store _myStore;
private string _myStoreID;
public OutlookExplorerWrapper(Outlook.Explorer explorer)
{
_myExplorer = explorer;
_myFolder = (Outlook.Folder)_myExplorer.CurrentFolder;
_myStore = _myFolder.Store;
_myStoreID = _myStore.StoreID;
}
I'm setting up an open id login for Google en Microsoft and use the IdentityModel.OidcClient. I've been able to make it work for Microsoft, but the Google login doesn't return any tokens (they are all null). I followed [this tutorial][1]. To make the Microsoft login work, I needed to add ProviderInformation.UserInfoEndpoint to the OidcClientOptions. This was not mentioned in the tutorial.
I hoped the same trick would arrange things for Google too, but it didn't. So now I'm stuck with the Google login and I don't see what's missing. I hope someone else can give me that last push in the back.
One thing I noticed and find quite strange: if I add the client secret to my OidcClientOptions, I don't get a token back for the Microsoft login. If I remove it, all tokens (identity token, acces token etc) are returned.
This is the code I used to create the OidcClient object with all the options:
private OidcClient CreateOidcClient(string authorityUrl, string clientId, string scope, string redirectUrl, string issuerName, string tokenEndpoint, string authorizeEndpoint, string userInfoEndPoint, string? clientSecret = null)
{
var options = new OidcClientOptions
{
Authority = authorityUrl,
ClientId = clientId,
ClientSecret = clientSecret,
Scope = scope,
RedirectUri = redirectUrl,
Browser = new WebAuthenticatorBrowser(),
ProviderInformation = new ProviderInformation
{
IssuerName = issuerName,
KeySet = new JsonWebKeySet(),
TokenEndpoint = tokenEndpoint,
AuthorizeEndpoint = authorizeEndpoint,
UserInfoEndpoint = userInfoEndPoint,
}
};
var oidcClient = new OidcClient(options);
return oidcClient;
}
This is the code I use when you click the "Sign in with Google" button:
private async Task GoogleLogIn()
{
OidcClient oidcClient = CreateOidcClient(
GoogleConfiguration.AuthorizeUrl,
GoogleConfiguration.ClientId,
GoogleConfiguration.Scope,
GoogleConfiguration.RedirectUrl,
GoogleConfiguration.IssuerName,
GoogleConfiguration.TokenEndpoint,
GoogleConfiguration.AuthorizeEndpoint,
GoogleConfiguration.UserInfoEndpoint,
GoogleConfiguration.ClientSecret
);
LoginResult loginResult = await oidcClient.LoginAsync(new LoginRequest());
}
And finally the GoogleConfiguration:
public static class GoogleConfiguration
{
public static readonly string AuthorizeUrl = "https://accounts.google.com/o/oauth2/v2/auth";
public static readonly string ClientId = "XXXXXXXXX";
public static readonly string Scope = "openid profile email";
public static readonly string RedirectUrl = "XXXXXXXXX:/oauth2redirect";
public static readonly string IssuerName = "accounts.google.com";
public static readonly string TokenEndpoint = "https://www.googleapis.com/oauth2/v3/certs";
public static readonly string AuthorizeEndpoint = "https://accounts.google.com/o/oauth2/v2/auth";
public static readonly string UserInfoEndpoint = "https://openidconnect.googleapis.com/v1/userinfo";
public static readonly string ClientSecret = "XXXXXXXXX";
}
This is the WebAuthenticationCallbackActivity class:
[Activity(NoHistory = true, LaunchMode = LaunchMode.SingleTask)] // or SingleTop?
[IntentFilter(new[] { Intent.ActionView },
Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable },
DataScheme = "data_scheme_microsoft")]
[IntentFilter(new[] { Intent.ActionView },
Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable },
DataScheme = "data_scheme_google")]
public class WebAuthenticationCallbackActivity : Xamarin.Essentials.WebAuthenticatorCallbackActivity
{
}
I receive following unclear error when the loginResult gets returned:
Error redeeming code: Not Found / no description
Any help is very much appreciated! If you need additional information, just let me know.
[1]: https://mallibone.com/post/xamarin-oidc
I am not an expert, but lately succeeded in making the same sample code work against Google.
Along the way, I have got:
Error redeeming code: Unauthorized / Unauthorized
But then I realised that I am setting client secret that I had got from a different identity provider but Google. Google does not give a client secret when you create a client ID, does it?
I fixed it and now am able to get tokens.
I finally figured it out: some credentials had been changed while I was working on this project. I didn’t notice because the old and new credentials looked very very very similar. A simple copy & paste did the trick.
I created a custom repository per https://aspnetboilerplate.com/Pages/Documents/Articles/Using-Stored-Procedures,-User-Defined-Functions-and-Views/index.html for my asp.net zero project. Everything works great when I test with the Swagger API test application and from my angular client. I then tried to write automated tests for the API using asp.net zero testing framework I get
System.AggregateException : One or more errors occurred. (The CommandType 'StoredProcedure' is invalid.)
---- System.ArgumentException : The CommandType 'StoredProcedure' is invalid."
It seems like the testing framework is using SQLLite for the DB Context. I am not sure how to work around this.
TEST THAT IS FAILING
[Fact]
public void Should_Get_All_StaticItems()
{
LoginAsTenant("Default", "admin");
//Act
**var types = _ptStaticDataTypeAppService.Get(new PTGetPTStaticDataTypeInput());**
//Assert
types.Result.Count.ShouldBe(_totalItems);
}
APP SERVICE METHOD
[AbpAuthorize(AppPermissions.Pages_Administration_PT_StaticDataType)]
public class PTStaticDataTypeAppService : PieceTrackerAppServiceBase, IPTStaticDataTypeAppService
{
IPTStaticDataTypeRepository _ptStaticDataRepository;
public PTStaticDataTypeAppService(IPTStaticDataTypeRepository ptStaticDataTypeRepository)
{
_ptStaticDataRepository = ptStaticDataTypeRepository;
}
public async Task<List<PTGetPTStaticDataTypeForViewDto>> Get(PTGetPTStaticDataTypeInput input)
{
return await _ptStaticDataRepository.Get(input);
}
REPOSITORY
public class PTStaticDataTypeRepository : PieceTrackerRepositoryBase<PTStaticDataType, long>, IPTStaticDataTypeRepository
{
private readonly IActiveTransactionProvider _transactionProvider;
public PTStaticDataTypeRepository(IDbContextProvider<PieceTrackerDbContext> dbContextProvider, IActiveTransactionProvider transactionProvider)
: base(dbContextProvider)
{
_transactionProvider = transactionProvider;
}
public async Task<List<PTGetPTStaticDataTypeForViewDto>> Get(PTGetPTStaticDataTypeInput input)
{
var data = new List<PTGetPTStaticDataTypeForViewDto>();
var cn = Context.Database.GetDbConnection();
if (cn.State != ConnectionState.Open)
await cn.OpenAsync();
using (var cmd = cn.CreateCommand())
{
cmd.CommandText = "usp_GetPTStaticDataType";
**cmd.CommandType = CommandType.StoredProcedure;**
The testing framework uses an in memory SQL Lite DB to pass thru the SQL commands. So I created a workaround in my custom repository.
private DbConnection GetSqlConnection()
{
const string TESTINGDB = "memory";
const string PTCONNSTRING = "Server=(local); Database=PieceTrackerDb; Trusted_Connection=True;";
var cn = Context.Database.GetDbConnection();
if (cn.ConnectionString.Contains(TESTINGDB))
{
cn = new SqlConnection(PTCONNSTRING);
}
var logMsg = "PTStaticDataTypeRepository.Get Connection String = " + cn.ConnectionString;
Console.WriteLine(logMsg);
return cn;
}
I am trying to implement MVVM pattern in my xamarin mobile project.
I have following files for MVVM
LoginView
LoginViewModel
BaseViewModel
Following is my LoginViewModel
public class LoginViewModel : BaseViewModel
{
private bool isLoginIndicator= false;
private string etUserName;
private string etPassword;
public LoginViewModel()
{
OnLogin = new Command(doLogin , ()=>!LoginIndicator);
MessagingCenter.Subscribe<IMessage, EventType>(this, RestApi.UI_EVENT, (sender, eventType) =>
{
LoginIndicator = false;
if (eventType.status)
{
Application.Current.MainPage.DisplayAlert(AppResources.success, "Login done", "Ok");
}
else
{
Application.Current.MainPage.DisplayAlert(AppResources.failed, eventType.errorMessage, "Ok");
}
});
}
public bool LoginIndicator
{
get { return isLoginIndicator; }
set
{
isLoginIndicator = value;
OnPropertyChanged("LoginIndicator");
OnLogin.ChangeCanExecute();
}
}
public string UserName
{
get { return etUserName; }
set
{
etUserName = value;
OnPropertyChanged("UserName");
}
}
public string Password
{
get { return etPassword; }
set
{
etPassword = value;
OnPropertyChanged("Password");
}
}
public Command OnLogin { get; }
void doLogin()
{
LoginIndicator = true;
UserRequest user = new UserRequest();
user.userName = etUserName;
user.password = etPassword;
user.companyId = "CEE";
user.appVersion = Constants.getAppVersion();
user.osVersion = Constants.getOSVersion();
user.deviceId = Constants.getDeviceModel() + " " + Constants.getDevicePlatform();
new RestApi().userLogin(JsonConvert.SerializeObject(user));
}
}
This class usually makes a webservice call when OnLogin command gets fired from Button and broadcast the Message using MessageCenter
Now i want to navigate to my MainPage which is master page once the user is logged in successfully hence i need to navigate to master page when eventType.status is true inside the Message Subscriber
but i don't know how can i properly navigate to other pages according to MVVM pattern.
i tried to search on net and i found there are ready made frameworks available like MVVMCross and MVVMLight etc. But i do not want to use those dependecies and willing to implement navigation some other way if anyone can suggest
MVVM says nothing about navigation, so basically every option will be fine.
The only thing against code like:
Application.Current.MainPage = new MyFirstPageAfterLogin();
Is that you now have a reference to a page from your ViewModel, which should not be what you want. That is why MVVM frameworks tend to implement a concept called ViewModel-to-ViewModelnavigation. With that, you can specify a ViewModel that you want to navigate to. Depending on the framework (or how they implemented it), they have you register a coupling first or use a naming convention. For instance; I like to use FreshMvvm, which does this by naming convention.
So when I want to navigate to the PageAfterLoginPage, I create a PageAfterLoginPageModel. From my ViewModel (or PageModel in Xamarin naming) I can now navigate to the PageModel, instead of making a hard reference to the page. This way, Page and PageModel are separated and I can easily swap out the View if I wanted to.
So, either use an already existing framework, or peek into their Github repo to see how they do it if you insist on doing it yourself.
With the latest tools do a File / New Project / CrossPlatform / Master-Detail. The master-detail template is all MVVM, without using any 3rd party frameworks. There are permutatations of native and forms. Great for learning and exploring.
Healy in Tampa.
I try to create an app that allows the user to register himself for my service.
The problem is that it is very important that i can limit each user to a very single account
i figured out I could probably do this with the Phone unique id and the windows live id
i also figured out how to get These within the app , but now my problem is how to get them to me!
Can anyone help me on how to send the phone id with the desired username to my email address ?
Thank you
EDIT
I use this code to get the needed values
public static class ExtendedPropertyHelper
{
private static readonly int ANIDLength = 32;
private static readonly int ANIDOffset = 2;
public static string GetManufacturer()
{
string result = string.Empty;
object manufacturer;
if (DeviceExtendedProperties.TryGetValue("DeviceManufacturer", out manufacturer))
result = manufacturer.ToString();
return result;
}
//Note: to get a result requires ID_CAP_IDENTITY_DEVICE
// to be added to the capabilities of the WMAppManifest
// this will then warn users in marketplace
public static byte[] GetDeviceUniqueID()
{
byte[] result = null;
object uniqueId;
if (DeviceExtendedProperties.TryGetValue("DeviceUniqueId", out uniqueId))
result = (byte[])uniqueId;
return result;
}
// NOTE: to get a result requires ID_CAP_IDENTITY_USER
// to be added to the capabilities of the WMAppManifest
// this will then warn users in marketplace
public static string GetWindowsLiveAnonymousID()
{
string result = string.Empty;
object anid;
if (UserExtendedProperties.TryGetValue("ANID", out anid))
{
if (anid != null && anid.ToString().Length >= (ANIDLength + ANIDOffset))
{
result = anid.ToString().Substring(ANIDOffset, ANIDLength);
}
}
return result;
}
}
Now i need to store thes in variables ( what i cant really get to work ) and then send them to my php script which extracts them
in addition to this i need to ask the user to enter his email address and include this in the POST too ,
can you help?
You can get DeviceExtendedProperties.DeviceUniqueId from Microsoft.Phone.Info namespace.
Don't forget to declare in WMAppManifest.xml
like this:
<Capabilities>
<Capability Name="ID_CAP_IDENTITY_DEVICE"/>
<Capability Name="ID_CAP_IDENTITY_USER"/>
</Capabilities>
Link to msdn here
Then, you can send this id to your e-mail:
var emailComposeTask = new EmailComposeTask
{
To = "your-email#domiain.com",
Subject = "Test Message using EmailComposeTask",
Body = deviceId
};
emailComposeTask.Show();
But this will open an-email client, and I don't thik that user will be so kind to send you an email. So, you'd better send a POST request to your server
private void Button_Click(object sender, RoutedEventArgs e)
{
//collect all data you need:
var deviceId = Convert.ToBase64String(ExtendedPropertyHelper.GetDeviceUniqueID());
var userName = ExtendedPropertyHelper.GetWindowsLiveAnonymousID();
var manufatcurer = ExtendedPropertyHelper.GetManufacturer();
//create request string
//[see the explanation on MSDN][2]
var requestUrl = string
.Format("http://myPageUrlAddress.com/script.aspx?deviceid={0}&user={1}&manufacturer={2}",
deviceId, userName, manufatcurer);
System.Uri myUri = new System.Uri(requestUrl);
//create a request instance
HttpWebRequest myRequest = (HttpWebRequest)HttpWebRequest.Create(myUri);
myRequest.Method = "POST";
myRequest.ContentType = "application/x-www-form-urlencoded";
//and it will be sent.
//Also you need to create GetRequestStreamCallback method to
//handle server responce.
myRequest.BeginGetRequestStream(new
AsyncCallback(GetRequestStreamCallback), myRequest);
}
//this method is empty. You can show tha dialog box about successful sending.
public void GetRequestStreamCallback(IAsyncResult result) { ; }
What about e-mail - just create a TextBox on the same Page, and save user input to a variable.
If "my service" is a web service, then you could use the web service instead of the mail system.
In either case you can use Convert.ToBase64String(phoneId) to convert the phone id to a string.
To send strings via mail from WP7 you need to use EmailComposeTask.