I am trying to write my very first Windows phone application and I am stuck on something. I have never had hands on experience with C# before.
The app is a simple count down timer that plays a sound at the end.
This is a Windows Phone 8 app. I created it using Visual Studio 2015 using: new Project > Templates > Visual C# > Windows > Windows 8 > Windows Phone > Blank App
I added a Background Task with Audio in Declarations in the Package.appxmanifest
I am using a MediaElement in the MainPage.xaml
<MediaElement Name="media"
AudioCategory="BackgroundCapableMedia"
Source="Audio/bell.mp3" AutoPlay="False" />
I added Audio/bell.mp3 to the project.
I am using a DispatchTimer like this
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = new TimeSpan(0, 0, 0, 1);
timer.Tick += new EventHandler<object>(timer_Tick);
void timer_Tick(object sender, object e)
{
if (tik > 0)
tik--;
progress.Value = progress.Maximum - tik;
if(tik <= 0)
{
timer.Stop();
media.Play();
}
}
It works perfectly fine with the screen is unlocked, the sounds plays at the end of the time.
However, if I lock the screen before the time is up, the timer continues (and that's perfect), but when the time is up, I get System.UnauthorizedAccessException on media.Play();
Additional information: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
I don't understand why I get access denied on locked screen only. What do I need to do to change that? I would really like the sound to play in locked screen to notify the user that the time is up.
I tried enabling the app to run in locked screen adding
PhoneApplicationService.Current.ApplicationIdleDetectionMode = IdleDetectionMode.Disabled;
to App.xaml.cs but I get
The name PhoneApplicationService does not exist in this context
and I can't add the Microsoft.Phone.dll otherwise I can't deploy the app onto the phone...
Related
I have an App that uses a floating overlay over other apps with a Search function.
Basic User Story is to copy a text to the clipboard, click on Overlay, and search for text in Clipboard.
this worked for a long time no Problem but with Android 10 it only works if the App is in the foreground.
If another App like Chrome is in the foreground the clipboard.getPrimaryClip() returns only a null pointer.
I guess they changed some permissions in Android. I searched on google and co but I didn't find any clues.
Is there an alternative way to get the Clipboard content event when I'm not in the App the overlay comes from? This kinda breaks the whole idea of that feature.
Technical Info: I'm extending the Service class and a WindowManager like this:
mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
this is how I get the clipboard text:
public String getClipboardText()
{
try {
ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
if (clipboard.getPrimaryClip().getItemCount() > 0) {
return clipboard.getPrimaryClip().getItemAt(0).getText().toString();
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
return "";
}
It seems Android 10 changes privacy settings and there is no alternative way to access the clipboard text. its also not possible to request permission, because clipboard permission given by "READ_LOGS" permission is only allowed for system apps.
I want to prevent the phone to lock if the user didnt interact with the phone for some time.
In win8 phone development i used the PhoneApplicationService.UserIdleDetectionMode Property. Unfortunately i cannot find anything alike for win 10 universal app.
Any suggestions?
Simple Answer
DisplayRequest class
var displayRequest = new DisplayRequest();
displayRequest.RequestActive(); //to request keep display on
displayRequest.RequestRelease(); //to release request of keep display on
Detailed Answer
Using display requests to keep the display on consumes a lot of power. Use these guidelines for best app behavior when using display requests.
Use display requests only when required, that is, times when no user input is expected but the display should remain on. For example, during full screen presentations or when the user is reading an e-book.
Release each display request as soon as it is no longer required.
Release all display requests when the app is suspended. If the display is still required to remain on, the app can create a new display request when it is reactivated.
To Request keep display on
private void Activate_Click(object sender, RoutedEventArgs e)
{
if (g_DisplayRequest == null)
{
g_DisplayRequest = new DisplayRequest();
}
if (g_DisplayRequest != null)
{
// This call activates a display-required request. If successful,
// the screen is guaranteed not to turn off automatically due to user inactivity.
g_DisplayRequest.RequestActive();
drCount += 1;
}
}
To release request of keep display on
private void Release_Click(object sender, RoutedEventArgs e)
{
// This call de-activates the display-required request. If successful, the screen
// might be turned off automatically due to a user inactivity, depending on the
// power policy settings of the system. The requestRelease method throws an exception
// if it is called before a successful requestActive call on this object.
if (g_DisplayRequest != null)
{
g_DisplayRequest.RequestRelease();
drCount -= 1;
}
}
References - Prevent the screen from locking on Universal Windows Platform
Hope it help someone!!
You want the DisplayRequest class in Windows 10.
i`m using mediaElement to play background music in my app. And that works just fine.
Problem is when the user minimize the application. When the application resume there is no sound... I can play other sounds in my application but cant play that background music any more.
First i have this code to stop all background music at first time app open:
if (Microsoft.Xna.Framework.Media.MediaPlayer.State == MediaState.Playing)
{
Microsoft.Xna.Framework.Media.MediaPlayer.Pause();
FrameworkDispatcher.Update();
}
xaml code of that mediaElement
<MediaElement AutoPlay="True" Source="/Dodaci/pozadina.mp3" x:Name="muzika_pozadina" MediaEnded="pustiPonovo" Loaded="pustiPonovo" />
and the cs code
private void pustiPonovo(object sender, RoutedEventArgs e)
{
muzika_pozadina.Play();
}
sound is about 300kb size.
So, how can i resume that sound playing after the user resume the application?
When your App is put into Dormant State (when you hit Start buton for example), the MediaElement is stopped. Then after you return to your App (and it wasn't Tombstoned), the Page is not Initialized once again, which means that your MediaElement is not loaded once again, so your Music doesn't start once again.
It depends on your purpose and code how it can be returned. In very simple example when you don't need to remember music last position you can just set source of your MediaElement once again in OnNavigatedTo() event:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
if (e.NavigationMode == NavigationMode.Back)
muzika_pozadina.Source = new Uri("/Dodaci/pozadina.mp3", UriKind.RelativeOrAbsolute);
}
As you have set your MediaElement.AutoPlay to true - it should start automatically (because of that you probably also don't need your Loaded event pustiPonovo).
In more complicated cases you can take an advantage of Activation and Deactivation events of your App - returning to MediaElement from Dormant/Tombstoned case is well explained here in the article.
You should also read about Fast App Resume in case User decides to return to your App by Tile instead of Launchers-Choosers.
I haven't tried above code, but hopefully it will do the job.
I have created a System Tray Application using Windows Forms Template (Visual C++) in Visual Studio 2008. I have used ContextMenuStrip and NotifyIcon. It's a managed code as I have used the form and Drag/Drop.
I want as soon as this System Tray Application starts, it starts polling for any new USB devices (from a specific vendor) connected.
The logic is ready except I don't know "Where to put this while(1) loop?"
It works fine in a console app that I made but now we want it to be integrated to the system tray app.
Here is the code snippet:
int numDevices, n = 0;
while(1)
{
Sleep(5000);
numDevices = usb_find_devices();
if(connectedDevices > numDevices)
{
enumDevices();
connectedDevices++;
}
}
It would really be appreciable if anyone could suggest me some pointers on how to proceed.
Thank you Hans! I added a new "Component Class" with WM_DEVICECHANGE and it is working fine.
Just in case anyone needs this info:
If a function needs to be called as soon as the Windows Forms App starts (Systray app in my case), the respective function can be called after the call to "InitializeComponent()" function. Though it is clearly mentioned "TODO: Add the constructor code here", still a beginner (like me) has inhibitions regarding "Where to put this Function Call??" Hope this helps somebody..
I have a similar situation to this question.
I have a custom sequential SharePoint workflow, deleoped in Visual Studio 2008. It is associated with an InfoPath form submitted to a form library. It is configured to automatically start when an item is created.
It works sometimes. Sometimes it just fails to start.
Just like the question linked above, I checked in the debugger, and the issue is that the InfoPath fields published as columns in the library are empty when the workflow fires. (I access the fields with workflowProperties.Item["fieldName"].) But there appears to be a race condition, as those fields actually show up in the library view, and if I terminate the failed workflow and restart it manually, it works fine!
After a lot of head-scratching and testing, I've determined that the workflow will start successfully if the user is running any version of IE on Windows XP, but it fails if the same user submits the same form data from a Vista or Windows 7 client machine.
Does anyone have any idea why this is happening?
I have used another solution which will only wait until InfoPath property is available (or max 60 seconds):
public SPWorkflowActivationProperties workflowProperties =
new SPWorkflowActivationProperties();
private void onOrderFormWorkflowActivated_Invoked(object sender, ExternalDataEventArgs e)
{
SPListItem workflowItem;
workflowItem = workflowProperties.List.GetItemById(workflowProperties.ItemId);
int waited = 0;
int maxWait = 60000; // Max wait time in ms
while (workflowItem["fieldName"] == null && (waited < maxWait))
{
System.Threading.Thread.Sleep(1);
waited ++;
workflowItem = workflowProperties.List.GetItemById(workflowProperties.ItemId);
}
// For testing: Write delay time in Workflow History Event
SPWorkflow.CreateHistoryEvent(
workflowProperties.Web,
workflowProperties.WorkflowId,
(int)SPWorkflowHistoryEventType.WorkflowComment,
workflowProperties.OriginatorUser, TimeSpan.Zero,
waited.ToString() + " ms", "Waiting time", "");
}
workflowProperties.Item will never get the InfoPath property in the code above.
workflowProperties.List.GetItemById(workflowProperties.ItemId) will after some delay.
This occurs due to the fact that Vista/7 saves InfoPath forms through WebDAV, however XP uses another protocol (sorry, can't remember at the time). SharePoint catches the "ItemAdded" event before the file is actually uploaded (that is, the item is already created, but file upload is currently in progress).
What you can do for a workaround is to add a dealay activity and wait for 10 seconds as the first thing in your workflow (will actually be longer than ten seconds due to the way workflows are built in SPPS). This way the upload will already have ended when you perform to read the item. To inform the users about what's happening, you can add a "logToHistoryList" activity before the delay.