how to set time limit for splash screen in windows phone app 8.1? - windows-phone-8

Hi I am developing one windows phone app.In this app I want to set time limit for loading in my splash screen.what happend is I am getting data(city names) from one service and insert data into local database(SQLite)table.but what happend is in my data 2000 cities are there.these all are inserted into sqlite table.here one problem occurred.what happend is splash screen will move to main screen(2 to 3 seconds time).but in that time all the cities are not inserted.just 700 to 800 cities are inserted in table.so I want to set certain time to splash screen.how to set time for loading.please help me.
public async void insertcities()
{
try
{
await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
{
var busclient = new NewReloadApp.JsonWebClient();
var Busresp1 = await busclient.DoRequestAsync(Url.weburl + "getCities");
string Busresult1 = Busresp1.ReadToEnd();
JArray BusjsonArray = JArray.Parse(Busresult1);
for (int j = 0; j < BusjsonArray.Count; j++)
{
await Task.Delay(TimeSpan.FromSeconds(0.001));
JObject jobj = (JObject)BusjsonArray[j];
string id = (string)jobj["cityid"];
string cityname = (string)jobj["cityname"];
Db_Helper.Insert(new Buscities(id, cityname));
// citieslist.Add(cityname);
}
});
}

You could not setup time limit for splash screen. As I know, Splash Screen displayed before Window.Current.Activate();.
EDIT
So, you can navigate to your StartupPage and in OnNavigatedTo run your code. Before that, change your method to Task from void
public async Task insertcities()
and you can do it like that
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
await insertcities();
// wait database logic and navigate from startup page
Frame.Navigate(typeof(DestinationPage));
}

Related

Update text block from downloaded text file = RPC_E_WRONG_THREAD WP8.1

I am learning Windows Phone 8.1 development, I have probably done something utterly incorrectly programming wise
The need: I want to download a text file from the web using HttpClient() and display it in the TextBlock1
From variety of tutorials I have found the following:
public async void DownloadDataAsync()
{
string data = "some link to Textfile.txt";
HttpClient client = new HttpClient();
HttpResponseMessage response = await client.GetAsync(data);
HttpContent content = response.Content;
string result = await content.ReadAsStringAsync();
UpdateTextBlock1(result);
}
Then the other functions.
public void UpdateTextBlock1(string result)
{
TextBlock1.Text = result;
}
private void BtnDownloadData_Click(object sender, RoutedEventArgs e)
{
Task t = new Task(DownloadDataAsync);
t.Start();
}
The code starts well enough - on button pressed, I receive RPC_E_WRONG_THREAD.
Is it that I'm trying to call the method when all threads haven't finished? How can I code that efficently so the TextBlock1 is updated with txt data?
Thanks for understanding, baby steps here in programming, and I couldn't find a relevant answer over google. (Maybe I don't yet know how to ask?)
You need to update the textblock on the UI thread like so:
Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
TextBlock1.Text = result;
});
There are many posts on this subject.

WriteableBitmapExtension crashes app on device

I have added a WriteableBitmapExtension via NuGet to my Windows Phone 8.1 WinRT app. I have functions to capture an image from camera and save it to picture library. I tried rotate captured image before save and I found solution here
WriteableBitmap crashes program with no message?. Everything works fine on emulator but when I run my app on Nokia Lumia 630 it crashes few seconds after taking a photo without debbuger message. Can anyone help me with this issue? Here is my code of taking photo:
public WriteableBitmap Image
{
get
{
return this.image;
}
set
{
this.image = value;
this.RaisePropertyChanged(() => this.Image);
}
}
private async void TakePhoto()
{
using (var stream = new InMemoryRandomAccessStream())
{
var imgEncodingProperties = ImageEncodingProperties.CreateJpeg();
var img = BitmapFactory.New(640, 480);
await this.MediaCapture.CapturePhotoToStreamAsync(imgEncodingProperties, stream);
stream.Seek(0);
img.SetSource(stream);
WriteableBitmapExtensions.DrawLine(img, 10, 10, 300, 300, Colors.Black);
this.Image = img.Rotate(90);
this.TurnOffCaptureMode();
}
}
private void TurnOffCaptureMode()
{
this.MediaCapture.StopPreviewAsync();
this.IsInCaptureMode = false;
}
Alternate solution is here.
1 Open file Picket use build in camera to take picture.
var openPicker = new FileOpenPicker();
openPicker.ContinuationData["Action"] = "SendPicture";
openPicker.FileTypeFilter.Add(".jpg");
openPicker.FileTypeFilter.Add(".png");
openPicker.PickSingleFileAndContinue();
***2. In app.xaml.cs you will get captured image. as below.***
public void Continue(IContinuationActivatedEventArgs args)
{
if(args.Kind == ActivationKind.PickFileContinuation)
{
var openPickerContinuationArgs = args as FileOpenPickerContinuationEventArgs;
// Recover the "Action" info we stored in ContinuationData
string action = (string) openPickerContinuationArgs.ContinuationData["Action"];
if(openPickerContinuationArgs.Files.Count > 0)
{
// TODO: Get the files here
}
else
{
// TODO: Write code here to handle picker cancellation.
}
}
}

How (and when) properly initialize camera in Windows Phone 8.1 (RT)

I'm writing simple WP app, that can work with images stored in a device or image taken by a camera right in my app. I'm maybe confused with navigation and camera initializing. There is a MainPage in the app where are buttons to select camera or library. Camera button just navigates to the CameraPage like this:
private void CameraButton_Click(object sender, RoutedEventArgs e)
{
...
this.Frame.Navigate(typeof(CameraPage));
}
And then I initialize camera in CameraPage OnNavigatedTo:
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
...
cameraCapture = new CameraCapture();
PreviewElement.Source = await cameraCapture.Initialize(Dispatcher);
await cameraCapture.StartPreview();
...
}
And CameraCapture initialization:
public async Task<MediaCapture> Initialize(CoreDispatcher dispatcher)
{
var cameraID = await GetCameraID(Windows.Devices.Enumeration.Panel.Back);
// Create MediaCapture and init
mediaCapture = new MediaCapture();
await mediaCapture.InitializeAsync(new MediaCaptureInitializationSettings
{
StreamingCaptureMode = StreamingCaptureMode.Video,
PhotoCaptureSource = PhotoCaptureSource.VideoPreview,
AudioDeviceId = string.Empty,
VideoDeviceId = cameraID.Id
});
mediaCapture.VideoDeviceController.PrimaryUse = Windows.Media.Devices.CaptureUse.Video;
this.dispatcher = dispatcher;
var maxResolution = mediaCapture.VideoDeviceController.GetAvailableMediaStreamProperties(MediaStreamType.Photo).Aggregate((i1, i2) => (i1 as VideoEncodingProperties).Width > (i2 as VideoEncodingProperties).Width ? i1 : i2);
await mediaCapture.VideoDeviceController.SetMediaStreamPropertiesAsync(MediaStreamType.Photo, maxResolution);
imgEncodingProperties = ImageEncodingProperties.CreateJpeg();
return mediaCapture;
}
The problem is - when I tap on the CameraButton on my MainPage, the app freezes on the MainPage until camera isn't initialized and then is the CameraPage loaded. What is the best approach to deal with this? Should I just move content from CameraPage to MainPage (so initialize camera on the MainPage and take a photo here)? Or there is a better way - like some event on the CameraPage? Tapping another button on the CameraPage to initialize camera would be so annoying for both me and user :)

Display splash page only on the 1st launch, or after a crash or a kill of the app

Could you please explain how to display splash page when only first launch or crash or kill the app in windows phone.
You could use the IsolatedStorage to check if the app was opened before or not
private static bool hasSeenIntro;
/// <summary>Will return false only the first time a user ever runs this.
/// Everytime thereafter, a placeholder file will have been written to disk
/// and will trigger a value of true.</summary>
public static bool HasUserSeenIntro()
{
if (hasSeenIntro) return true;
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
if (!store.FileExists(LandingBitFileName))
{
// just write a placeholder file one byte long so we know they've landed before
using (var stream = store.OpenFile(LandingBitFileName, FileMode.Create))
{
stream.Write(new byte[] { 1 }, 0, 1);
}
return false;
}
hasSeenIntro = true;
return true;
}
}
For the crash system, you could use BugSense for Windows Phone

Windows Phone link from Tile error

I have a list of theaters and I created a secondary tile from my application to navigate directly to specific theater. I pass the id of the theater in query string :
I load the theaters from a WCF service in the file "MainViewModel.cs"
In my home page, I have a list of theaters and I can navigate to a details page.
But when I want to navigate from the tile, I have an error...
The Tile :
ShellTile.Create(new Uri("/TheaterDetails.xaml?selectedItem=" + theater.idTheater, UriKind.Relative), tile, false);
My TheaterDetails page :
public partial class TheaterDetails : PhoneApplicationPage
{
theater theater = new theater();
public TheaterDetails()
{
InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (!App.ViewModel.IsDataLoaded)
{
App.ViewModel.LoadData();
}
if (DataContext == null)
{
string selectedIndex = "";
if (NavigationContext.QueryString.TryGetValue("selectedItem", out selectedIndex))
{
int index = int.Parse(selectedIndex);
theater = (from t in App.ViewModel.Theaters
where t.idTheater == index
select t).SingleOrDefault();
DataContext = theater;
....
....
....
The error :
https://dl.dropboxusercontent.com/u/9197067/error.png
Like if the data were not loaded...
Do you have an idea where the problem come from ?
The solution could be easy but I am a beginner... Maybe it's because I load the data asynchronously and the application doesn't wait until it's done...
Thanks
EDIT :
My LoadData() method :
public void LoadData()
{
client.GetTheatersCompleted += new EventHandler<ServiceReference1.GetTheatersCompletedEventArgs>(client_GetTheatersCompleted);
client.GetTheatersAsync();
// Other get methods...
this.IsDataLoaded = true;
}
private void client_GetTheatersCompleted(object sender, ServiceReference1.GetTheatersCompletedEventArgs e)
{
Theaters = e.Result;
}
You should check to see which variable is actually null. In this case it looks to be Theaters (otherwise the error would have thrown earlier).
Since Theaters is populated from a web call it is most likely being called asynchronously, in other words when you return from LoadData() the data is not yet there (it's still waiting for the web call to come back), and is waiting for the web service to return its values.
Possible solutions:
Make LoadData() an async function and then use await LoadData(). This might require a bit of rewriting / refactoring to fit into the async pattern (general introduction to async here, and specific to web calls on Windows Phone here)
A neat way of doing this that doesn't involve hacks (like looping until the data is there) is to raise a custom event when the data is actually populated and then do your Tile navigation processing in that event. There's a basic example here.
So the solution that I found, thanks to Servy in this post : Using async/await with void method
I managed to use async/await to load the data.
I replaced my LoadData() method by :
public static Task<ObservableCollection<theater>> WhenGetTheaters(ServiceClient client)
{
var tcs = new TaskCompletionSource<ObservableCollection<theater>>();
EventHandler<ServiceReference1.GetTheatersCompletedEventArgs> handler = null;
handler = (obj, args) =>
{
tcs.SetResult(args.Result);
client.GetTheatersCompleted -= handler;
};
client.GetTheatersCompleted += handler;
client.GetTheatersAsync();
return tcs.Task;
}
public async Task LoadData()
{
var theatersTask = WhenGetTheaters(client);
Theaters = await theatersTask;
IsDataLoaded = true;
}
And in my page :
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
if (!App.ViewModel.IsDataLoaded)
{
await App.ViewModel.LoadData();
}