Is updating LiveTile on Application_Deactivated a good practice? - windows-phone-7

I have not used Background Agents for updating LiveTiles. I update the tile on exiting of the app and on Application_Deactivated.
private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{
CycleManager pCycMan = CycleManager.Instance;
pCycMan.WriteToIsolatedStorage();
ResourceManager resMan = new ResourceManager("xxx.AppResources", Assembly.GetExecutingAssembly());
ShellTile PrimaryTile = ShellTile.ActiveTiles.First();
StandardTileData tile = new StandardTileData();
try
{
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 = m_liveTileText;
}
PrimaryTile.Update(tile);
}
}
catch(Exception)
{
}
}
Is is a good practice to do so? The app is published and I have received a StackTrace with a COMException. It shows that the exception is raised on execution of Microsoft.Phone.Shell.ShellTile.Update after the XXX.App.Application_Deactivated
Does anyone know of this exception or faced such situations? It would be really helpful if someone could guide me on this.

When the Application_Deactivated event is raised, you have 10 seconds to finish your task.
After that, your application will be terminated.
So maybe the crash happened because your code took more than 10 seconds to complete.

I used to update the livetile in the Application_Deactivated, however this caused issues with resuming, so I removed that feature.
Someone else found the same issue and updates in a different area:
http://www.japf.fr/2012/12/updating-the-live-tiles-when-the-exits-wp8-weirdness/

Related

How to check internet connection continuously in Xamarin.Android Native?

My application is completely based on internet and it does not work without it, when the internet is not available or it is slow my application is getting stopped unfortunately.
I tried to implement try, catch but it is not helping me out as it is not throwing any exception, then I thought that I have to check the internet connectivity continuously till the app is running and stop any activity from performing and set a popup to connect to the internet.
I am able to get the popup whenever I call a method which has the following code inside it,
ConnectivityManager connectivityManager = (ConnectivityManager)GetSystemService(ConnectivityService);
NetworkInfo networkInfo = connectivityManager.ActiveNetworkInfo;
if (networkInfo == null)
{
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.SetTitle("Network");
alert.SetMessage("Please turn of your Wifi or Mobile Data From Settings");
alert.SetPositiveButton("OK", (senderAlert, args) => {
Intent intent = new Intent(Android.Provider.Settings.ActionSettings);
StartActivity(intent);
});
alert.SetNegativeButton("Cancel", (senderAlert, args) => {
Toast.MakeText(this, "Cancelled!", ToastLength.Short).Show();
Finish();
});
Dialog dialog = alert.Create();
dialog.Show();
But I am unable to get the connection checked continuously, So Can some one Please help me to complete get this functionality in my application.
You need to use a BroadcastReceiver to monitor network changes.
[BroadcastReceiver(Enabled = true)]
[IntentFilter(new[] { "android.net.conn.CONNECTIVITY_CHANGE" })]
[Android.Runtime.Preserve(AllMembers = true)]
public class ConnectivityChangeBroadcastReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
if (intent.Action != ConnectivityManager.ConnectivityAction)
return;
//Check if is connected and raise a custom event or store
//the current in a static global variable
}
}
}
In Android 7.0, you need to remove IntentFilter from the class and register the receiver.
var receiver = new ConnectivityChangeBroadcastReceiver();
Application.Context.RegisterReceiver(receiver, new IntentFilter(ConnectivityManager.ConnectivityAction));
Another option is to use the ConnectivityPlugin https://github.com/jamesmontemagno/ConnectivityPlugin , which is easier to use.
CrossConnectivity.Current.ConnectivityChanged += HandleConnectivityChanged;
void HandleConnectivityChanged (object sender, ConnectivityChangedEventArgs e)
{
// You can check the network status in
//e.IsConnected
}
Note that The ACCESS_NETWORK_STATE and ACCESS_WIFI_STATE permissions are required.

App.OnResume error in Xamarin forms on Android and IOS devices

We are using xamarin forms. After an Android or IOS device resumes from background, we are making a REST call in .net that is being triggered by a timer. The first attempt on IOS returns a "The Descriptor is not a socket" error and the Android returns a "Connection refused" error. The same code works fine in Windows. Future attempts (every few seconds) in all 3 platforms work fine. Has anyone seen this and have a fix?
Code
//app on resume event
protected async override void OnResume()
{
// Handle when your app resumes
if (MainPage is RootPage)
{
RootPage mainPage = MainPage as RootPage;
if (mainPage.Detail is NavigationPage)
{
NavigationPage nvPage = mainPage.Detail as NavigationPage;
if(nvPage.CurrentPage is ThingsPage)
{
ThingsPage thPage = nvPage.CurrentPage as ThingsPage;
thPage.TurnOnTimer();
}
}
}
}
//code on the page
public void TurnOnTimer()
{
if (viewModel != null)
{
viewModel.ContinueTimer = true;
viewModel.StartAnotherTimer();
}
}
//code in view model
public async void StartAnotherTimer()
{
while (ContinueTimer)
{
try
{
DevicesUpdate devicesUpdate = await DataSource.GetDevices(LocationID, ControllerID, lastDevicesUpdateReceivedAt);
}
catch (Exception ex)
{
}
// Update the UI (because of async/await magic, this is still in the UI thread!)
if (ContinueTimer)
{
await Task.Delay(TimeSpan.FromSeconds(3));
}
}
}
public static async Task<DevicesUpdate> GetDevices(Guid locationID, Guid controllerID, DateTime lastUpdateReceivedAt)
{
DevicesUpdate devicesUpdate = await GetLastUpdatedDevices(controllerID, lastUpdateReceivedAt);
}
//code in view model
public static async Task<DevicesUpdate> GetLastUpdatedDevices(Guid controllerID,
DateTime lastUpdate)
{
System.Net.Http.HttpClient client = new System.Net.Http.HttpClient();
string url = string.Format("http://appname.azurewebsites.net/api/devices?controllerid={1}&lastUpdate={2}"
, Constants.WebServerURL, controllerID, lastUpdate);
System.Net.Http.HttpResponseMessage response = await client.GetAsync(new Uri(url));
string result = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
DevicesUpdate devices = JSONHelper.Deserialize<DevicesUpdate>(result);
return devices;
}
else
{
if (response.ReasonPhrase == "UserException")
{
throw new UserException(result);
}
else
{
//throw error because the response from rest api is not a success
throw new System.Net.Http.HttpRequestException(result);
}
}
}
You might have a few things happening here that's causing problems.
GetDevices doesn't return anything. (I hope you just left out the return for brevity sake)
You are never setting ContinueTimer to false.
What iOS version are you on? In later versions, you HAVE to use HTTPS or explicitly allow non-secure connections. This shouldn't be a problem because Azure has ssl.
If you plan on running this in the background, you need to register your app as a background process.
If you don't plan on running this in the background, you might have issues with previous attempts being ran (or still trying to execute, or just have failed) and then calling more.
What is the reason for calling the 3 second timer for the network calls? What if the call takes more than 3 seconds (then you are making duplicate calls even though the first might succeed).
If you want to make your network calls more robust, check out this Blog Post by Rob Gibbons about resilient network calls.
First thing I would do is remove it from the timer because it seems like the underlying sockets are having issues cross-thread.

Launching a background agent from within the app

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);
}
}

How to call webservice methods in Windows Phone 7?

For connecting to webservices i wrote the following code.
WebClient wc = new WebClient();
wc.DownloadStringAsync(new Uri("http://www.Webservices.asmx"));
wc.DownloadStringCompleted += new DownloadStringCompletedEventHandler(wc_DownloadStringCompleted);
void wc_DownloadStringCompleted(object sender,DownloadStringCompletedEventArgs e)
{
Debug.WriteLine("Web service says: " + e.Result);
using (var reader = new StringReader(e.Result))
{
String str = reader.ReadToEnd();
}
}
by using above code Get the string result.But i want get the result in HTMLVisulaizer then i know the what are the methods having that webservice.then i can easily access the particular method.
Please tell me how to call a web service method in Windows phone 7?in webservice i am having 5 webmethods.how to get that and how to call the Particular webmenthod.
Please tell me thanks in advance.
#venkateswara Are you talking about obtaining a list of known WebReference methods so you know which one to call in you code? Do you not see the this of known method calls when you add the WebReference to your WP7 project? Since you will be developing the WP7 app in VS I can't see the reason you would want to do this. Even if you don't own the webservice yourself, you will need to connect to it from VS in order to add the reference to your project.
Below is the screen in VS2010 where a WebReference is added. The Operations are listed on the right.
Once added you can use the ObjectBrowser to understand how the methods should be called.
Please let me know if I have missed something from your question.
#Jason James
The first step:
You must add referent Services ,like Jason James has very detailed instructions .
step 2 :
You can open App.xaml.cs , in Functions Apps
public Apps()
{
// Global handler for uncaught exceptions.
UnhandledException += Application_UnhandledException;
// Show graphics profiling information while debugging.
if (System.Diagnostics.Debugger.IsAttached)
{
// Display the current frame rate counters.
Application.Current.Host.Settings.EnableFrameRateCounter = true;
// Show the areas of the app that are being redrawn in each frame.
//Application.Current.Host.Settings.EnableRedrawRegions = true;
// Enable non-production analysis visualization mode,
// which shows areas of a page that are being GPU accelerated with a colored overlay.
//Application.Current.Host.Settings.EnableCacheVisualization = true;
}
// You can declare objects here that you will use
//Examlpe: NameservicesReferent.(Function that returns services) = new NameservicesReferent.(Function that returns services)();
Ws_Function = new Nameservices.ServiceSoapClient();
}
step 3:
in Mainpage.xaml.cs
GlobalVariables.Ws_advertise.getLinkAdvertiseIndexCompleted += new EventHandler<advertise.getLinkAdvertiseIndexCompletedEventArgs>(Ws_advertise_getLinkAdvertiseIndexCompleted);
GlobalVariables.***NameWedservise***.getLinkAdvertiseIndexAsync("**parameters to be passed**");
step 4:
void Ws_advertise_getLinkAdvertiseIndexCompleted(object sender, advertise.getLinkAdvertiseIndexCompletedEventArgs e)
{
//function returns the results to you, the example here is an array
string[] array = null;
try
{
array = e.result;
if(array != null)
}
cath(exception ex)
{
}
finally
{
array = null;
GlobalVariables.Ws_advertise.getLinkAdvertiseIndexCompleted -= new EventHandler<advertise.getLinkAdvertiseIndexCompletedEventArgs>(Ws_advertise_getLinkAdvertiseIndexCompleted);
}
}

NotSupportedException when adding entity via odata on windows phone

I'm using the odata client generator (DataSvcUtil.exe) in a Windows Phone 7 application. Retrieving entities and collections is fine as is updating an existing entity. But when I try to add a new entity, I get a NotSupportedException. Here's my code.
private void Button_Click(object sender, RoutedEventArgs e)
{
Drinks d =new Drink();
d.BarCode = "1234567890";
d.Description = "Test Drink";
d.Quantity = -1;
context.AddToDrinks(d);
context.BeginSaveChanges(SaveChangesOptions.Batch, OnChangesSaved, context);
}
private void OnChangesSaved(IAsyncResult result)
{
Dispatcher.BeginInvoke(() =>
{
try
{
var something = result.AsyncState;
context = result.AsyncState as DrinkTrackerModelContainer;
// Complete the save changes operation and display the response.
ShowSaveResponse("Drink Logged!", context.EndSaveChanges(result));
}
catch (DataServiceRequestException ex)
{
ShowSaveResponse("Error Logging Drink", ex.Response);
}
catch (InvalidOperationException ex)
{
ShowSaveResponse(ex.Message, null);
}
}
);
}
As soon as EndSaveChanges is called, I get the
NotSupportedException.
EDIT: I used fiddler and saw that I was in fact getting a different exception from the service. That exception data was not being shown in the debugger. Once I corrected the actual exception, the insert worked fine.
I think you have first chance exceptions turned on which is causing an internal exception thrown by the client library to surface as an exception. Try turning off First Chance Exceptions in the "Exceptions" menu in VS and running the app.
As you mentioned in your edit, the NotSupportedException was a red herring. I think that when debugging a phone app you will hit the NotSupportedException even if you have cleared the setting to break on unhandled CLR exceptions.
If you continue(F5), you'll hit an actual DataServiceRequestException exception. If it doesn't have enough information to debug it, you can follow the steps in this post to get more detailed information in the exception: http://blogs.msdn.com/b/phaniraj/archive/2008/06/18/debugging-ado-net-data-services.aspx
I ran into the same problem yesterday, and after following the steps in the blog I was able to successfully debug the problem.

Resources