I wanted to know if there is a way to get a event/notification in your application when the device's screen is locked by the user.
Currently, When the user is in login screen and submits the login detail and locks the screen. the login process (Request is sent to the server and response is received for that) is getting completed. I wanted to cancel the request at that particular instance.
Is there a way to accomplish this ?
Yes, there is a signal you can connect to the slot and get the update when lock state changes. Take a look at DeviceLockState. This is an example:
mHomeScreen = new bb::platform::HomeScreen(this);
bool res = connect(mHomeScreen, SIGNAL(lockStateChanged(bb::platform::DeviceLockState::Type)),
this, SLOT(onLockStateChanged(bb::platform::DeviceLockState::Type)));
And your slot:
void YourApp::onLockStateChanged(bb::platform::DeviceLockState::Type state) {
if (state == bb::platform::DeviceLockState::ScreenLocked) {
qDebug() << "Device locked";
}
}
You may also find DeviceLockState::PasswordLocked state interesting .
Related
I have a bot with the following conversation scenario:
Send text to LUIS
LUIS intent calls context.Call(...) to launch a Dialog
This dialog terminates, save some info in the userData:
private static async Task storeBotData(IDialogContext context, BotData userData)
{
Activity activity = (Activity)context.Activity;
StateClient sc = activity.GetStateClient();
await sc.BotState.SetUserDataAsync(activity.ChannelId, activity.From.Id, userData);
}
And after it call another dialog, again with context.Call(...).
Then the last dialog runs and terminates.
My problem is that when updating the user data at the end of the first dialog (step 3), I have the following exception in the Bot Framework Channel Emulator:
`Exception: The data is changed [File of type 'text/plain']`...
What happens here ? I think that when a dialog terminates, it call setUserData by itself, but I don't understand why I can't update userData anywhere in the code...
I have tried to catch the exception, but nothing is catched.. But I know that the userData is updated, because when I try to retrieve it back, it is updated...
Any help is welcome :)
Thanks
Botframework restores/saves state of conversation after each act of activity, so under the covers typical flow looks like the following:
[23:15:40] <- GET 200 getUserData
[23:15:47] <- GET 200 getConversationData
[23:15:47] <- GET 200 getPrivateConversationData
...
[23:16:42] <- POST 200 setConversationData
[23:16:42] <- POST 200 setUserData
[23:16:42] <- POST 200 setPrivateConversationData
As it is mentioned here : These botData objects will fail to be stored if another instance of your bot has changed the object already. So in your case the exception occurs at the termination of dialog, when framework calls setUserData by himself and figures out that the BotData has been changed already (by your explicit call of BotState.SetUserDataAsync). I suppose that's why you were not able to catch the exception.
Solution:
I used the following code and it fixed the issue:
private static void storeBotData(IDialogContext context, BotData userData)
{
var data = context.UserData;
data.SetValue("field_name", false);
}
The reason it works is that we modify the object of UserData but allow botFramework to "commit" it himself, so there is no conflict
I agree with #Artem (this solved my issue too, thanks!). I would just add the following guideline.
Use
var data = context.UserData;
data.SetValue("field_name", false);
whenever you have a IDialogContext object available, so you let the Bot Framework commit changes.
Use instead
StateClient sc = activity.GetStateClient();
await sc.BotState.SetUserDataAsync(activity.ChannelId, activity.From.Id, userData);
when you don't have an IDialogContext object, e.g. in the MessageController class.
Can i use Parse.com Unity plugin to schedule push notification to the user once an action is done.
i.e) Notify the user in 1 hour that his building has been built.(as in coc an example)
I don't think Push Notifications is what you are looking for here, instead I think you want Local Notifications. With Local Notifications, you schedule a notification to appear at a specified time (you usually schedule the notification when the player leaves the app, as you wouldn't normally want the notification to appear as they are playing it).
For example, you would do the following (not tested):
public void OnApplicationPause(bool isPaused)
{
// If paused, then in background
if (isPaused)
{
LocalNotification notification = new LocalNotification();
notification.alertAction = "App Name";
notification.alertBody = "The building is complete";
notification.hasAction = true;
notification.applicationIconBadgeNumber = 1; // Set's the badge count
notification.fireDate = dateBuildingWillBeFinished;
NotificationServices.ScheduleLocalNotification(notification);
}
else // Entered the app
{
// Clear notifications
NotificationServices.CancelAllLocalNotifications();
NotificationServices.ClearLocalNotifications();
}
}
Push Notifications are generally used to send messages to all players, or a group of players (such as players in the UK) to notify them of something, like a sale that is going on for in app purchases. Local Notifications are user specific, and can act more as reminders, such as your building has been completed or you haven't visited your town in a week etc.
We are trying to test push notifications, using the latest code from the documentation How to: Set Up a Notification Channel for Windows Phone
public HttpNotificationChannel myChannel;
public void CreatingANotificationChannel()
{
myChannel = HttpNotificationChannel.Find("MyChannel");
if (myChannel == null)
{
myChannel = new HttpNotificationChannel("MyChannel","www.contoso.com");
// An application is expected to send its notification channel URI to its corresponding web service each time it launches.
// The notification channel URI is not guaranteed to be the same as the last time the application ran.
myChannel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(myChannel_ChannelUriUpdated);
myChannel.Open();
}
else // Found an existing notification channel.
{
// The URI that the application sends to its web service.
Debug.WriteLine("Notification channel URI:" + myChannel.ChannelUri.ToString());
}
myChannel.HttpNotificationReceived += new EventHandler<HttpNotificationEventArgs>(myChannel_HttpNotificationReceived);
myChannel.ShellToastNotificationReceived += new EventHandler<NotificationEventArgs>(myChannel_ShellToastNotificationReceived);
myChannel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>(myChannel_ErrorOccurred);
}
If HttpNotificationChannel.Find() returns null, it opens a new channel, but the ChannelUriUpdated event is never triggered.
If HttpNotificationChannel.Find() returns a channel, the ChannelUri property is null. The sample code crashes here because it assumes the ChannelUri property to be not null.
In neither case is the ErrorOccurred event triggered.
How can i solve this problem? This problem is because of microsoft server or any thing else?
Thnks in advance
EDIT
Waiting for replay,after ten days i am suffering of null uri problem
Can any one tell me how can i solve this problem some time MSPN server give chanalk uri ans some time not i mean some time it give null reference Exception.
What Microsoft doing?
If I don't go wrong, www.contoso.com it's a example URI to demonstrate that you need to put your own server URL address, but in my experience, I never use in that way. I prefer just to put
myChannel = new HttpNotificationChannel("MyChannel");
Look this example (it's in Spanish) but the codes are very clear of what you need to do to set the push notification client and service.
I hope I helped you.
You are testing in what mobile are Emulator,
Do you have developer account subscription for windows phone development,
Had you Developer unlocked your mobile,
Noorul.
I think the problem is that you are using the HttpNotificationChannel constructor of the authenticated web service, according to the documentation.
Instead, you should use the constructor that takes only one parameter, as you can check in this example
/// Holds the push channel that is created or found.
HttpNotificationChannel pushChannel;
// The name of our push channel.
string channelName = "ToastSampleChannel";
// Try to find the push channel.
pushChannel = HttpNotificationChannel.Find(channelName);
// If the channel was not found, then create a new connection to the push service.
if (pushChannel == null)
{
pushChannel = new HttpNotificationChannel(channelName);
...
}
Hope it helps
As far as I have understood, if you register a periodic task to deal with your WP7 live tiles, it will not update more than once every half hour. However, I would like to update the data the background agent works on every time the user exits the app.
My scenario is that I have a live tile displaying the first entry in a planner - and depending on what the user does within the app, that planner might get its entries deleted or have a new one up front. To have the live tile present outdated info is not very appealing.
Is this possible - and if so, how to?
I dont know if this is what you are looking for.
My app updates livetiles when the user exits the app. But then I have had problems such as, if the user does not open the app for few days then it does not get updated.
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
ShellTile PrimaryTile = ShellTile.ActiveTiles.First();
StandardTileData tile = new StandardTileData();
if (PrimaryTile != null)
{
tile.BackTitle = resMan.GetString("liveTileTitle");
tile.BackBackgroundImage = new Uri("/Background.png", UriKind.Relative);
if (pCycMan.GetStartDate() == pCycMan.GetDefaultDate())
{
tile.Title = resMan.GetString("liveTileNotTrackingStatus");
}
else
{
tile.Title = App.m_liveTileText;
}
PrimaryTile.Update(tile);
}
}
When data is entered, it ultimately needs to be saved remotely on a server. I do want the app to work if there is no data connection at the time also, so I need to save everything locally on the phone too. The app can then sync with the server when it gets a connection.
This brings up a little issue. I'm used to saving everything on the server and then getting the records back with id's generated from the server for them. If there is no connection, the app will save locally to the phone but not the server. When syncing with the server, I don't see a way for the phone to know when a record comes back which locally record it's associated with. There isn't enough unique data to figure this out.
What is the best way to handle this?
One way I've been thinking is to change the id of the records to a GUID and let the phone set the id. This way, all records will have an id locally, and when saving to the server, it should still be a unique id.
I'd like to know what other people have been doing, and what works and what doesn't from experience.
This is how we done with a first windows phone 7 app finished few days ago with my friend.
It might not be the best solution but 'till additional refactoring it works just fine.
It's an application for a web app like a mint.com called slamarica.
If we have feature like save transaction, we first check if we have connection to internet.
// Check if application is in online or in offline mode
if (NetworkDetector.IsOnline)
{
// Save through REST API
_transactionBl.AddTransaction(_currentTransaction);
}
else
{
// Save to phone database
SaveTransactionToPhone(_currentTransaction);
}
If transaction is successfully saved via REST, it responses with transaction object and than we save it to local database. If REST save failed we save data to local database.
private void OnTransactionSaveCompleted(bool isSuccessful, string message, Transaction savedTransaction)
{
MessageBox.Show(message);
if(isSuccessful)
{
// save new transaction to local database
DatabaseBl.Save(savedTransaction);
// save to observable collection Transactions in MainViewModel
App.ViewModel.Transactions.Add(App.ViewModel.TransactionToTransactionViewModel(savedTransaction));
App.ViewModel.SortTransactionList();
// Go back to Transaction List
NavigationService.GoBack();
}
else
{
// if REST is failed save unsent transaction to Phone database
SaveTransactionToPhone(_currentTransaction);
// save to observable collection Transactions in MainViewModel
App.ViewModel.Transactions.Add(App.ViewModel.TransactionToTransactionViewModel(_currentTransaction));
App.ViewModel.SortTransactionList();
}
}
Every Transaction object has IsInSync property. It is set to false by default until we got confirmation from REST API that it's saved successful on the server.
User has ability to refresh transactions. User can click on a button Refresh to fetch new data from the server. We do the syncing in the background like this:
private void RefreshTransactions(object sender, RoutedEventArgs e)
{
if (NetworkDetector.IsOnline)
{
var notSyncTransactions = DatabaseBl.GetData<Transaction>().Where(x => x.IsInSync == false).ToList();
if(notSyncTransactions.Count > 0)
{
// we must Sync all transactions
_isAllInSync = true;
_transactionSyncCount = notSyncTransactions.Count;
_transactionBl.AddTransactionCompleted += OnSyncTransactionCompleted;
if (_progress == null)
{
_progress = new ProgressIndicator();
}
foreach (var notSyncTransaction in notSyncTransactions)
{
_transactionBl.AddTransaction(notSyncTransaction);
}
_progress.Show();
}
else
{
// just refresh transactions
DoTransactionRefresh();
}
}
else
{
MessageBox.Show(ApplicationStrings.NETWORK_OFFLINE);
}
}
private void DoTransactionRefresh()
{
if (_progress == null)
{
_progress = new ProgressIndicator();
}
// after all data is sent do full reload
App.ViewModel.LoadMore = true;
App.ViewModel.ShowButton = false;
ApplicationBl<Transaction>.GetDataLoadingCompleted += OnTransactionsRefreshCompleted;
ApplicationBl<Transaction>.GetData(0, 10);
_progress.Show();
}
OnTransactionRefreshCompleted we delete all transaction data in local database and get the latest 10 transactions. We don't need all the data, and this way user have synced data. He can always load more data by taping load more at the end of transaction list. It's something similar like those twitter apps.
private void OnTransactionsRefreshCompleted(object entities)
{
if (entities is IList<Transaction>)
{
// save transactions
var transactions = (IList<Transaction>)entities;
DatabaseBl.TruncateTable<Transaction>();
DatabaseBl.Save(transactions);
((MainViewModel) DataContext).Transactions.Clear();
//reset offset
_offset = 1;
//update list with new transactions
App.ViewModel.LoadDataForTransactions(transactions);
App.ViewModel.LoadMore = false;
App.ViewModel.ShowButton = true;
}
if (entities == null)
{
App.ViewModel.ShowButton = false;
App.ViewModel.LoadMore = false;
}
// hide progress
_progress.Hide();
// remove event handler
ApplicationBl<Transaction>.GetDataLoadingCompleted -= OnTransactionsRefreshCompleted;
}
Caveat - I haven't tried this with windows phone development but use of GUID identities is something I usually do when faced with similar situations - eg creating records when I only have a one-way connection to the database - such as via a message bus or queue.
It works fine, albeit with a minor penalty in record sizes, and can also cause less performant indexes. I suggest you just give it a shot.