大家好:)我们正在编写一个针对当地消防部门的应用程序,因为他们计划删除两个寻呼机频率中的一个,并将其替换为应用程序(他们有两个警报频道,经典寻呼机和手机)。如果有传入警报,手机会创建带有音频的警报方案ToastNotification。到目前为止一直很好,问题是如果用户将系统主音量设置为零,则不播放音频文件。我知道到目前为止无法从应用程序更改系统音量,但对于我的场景,我需要播放音频通知,无论手机音量设置等。
如果有人知道如何克服这个问题,我将非常感谢:)
答案 0 :(得分:2)
我知道它不是你想听到的,但Win10Mobile设备是消费者设备。如果你买了一部手机,将它静音,它仍会发出噪音,你会有什么感觉?
当一个人将手机静音时,他们说它不应该发出声音。您是说要覆盖用户设置,而不是设备应该做什么。
如果您有专业要求,可能需要使用专业设备。我还没有检查过,但可能有些设备(不是UWP)没有用户可访问的硬件卷设置。
如果您无法控制正在使用的设备,那么我建议获取(或制作?)一个隐藏访问音量按钮的案例。
如果一个人在收到来电/留言时有责任接听电话,那么在一天结束时,您可以在具有固定功能的设备上进行代码处理。
答案 1 :(得分:0)
我遇到了完全相同的问题。幸运的是,我使用P / Invoke从C#接口使用IAudioEndpointVolume找到了一个有效的解决方案。
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
using Windows.Media.Devices;
namespace AudioUtils
{
public static class VolumeControl
{
public static void ChangeVolumeToMinLevel(double level)
{
if (level > 1)
level = 1;
else if (level < 0)
level = 0;
try
{
var masterVol = GetAudioEndpointVolume();
if (masterVol == null)
return;
var hr = masterVol.GetMute(out var muted);
if (hr != (uint)HResult.S_OK)
return;
if (muted)
{
masterVol.SetMute(false, Guid.Empty);
}
// Only adapt volume if the current level is below the specified minumum level
hr = masterVol.GetMasterVolumeLevelScalar(out float currentAudioValue);
float newAudioValue = Convert.ToSingle(level);
if (currentAudioValue > newAudioValue)
return;
masterVol.SetMasterVolumeLevelScalar(newAudioValue, Guid.Empty);
}
catch { }
}
private static IAudioEndpointVolume GetAudioEndpointVolume()
{
var speakerId = MediaDevice.GetDefaultAudioRenderId(AudioDeviceRole.Default);
var completionHandler = new ActivateAudioInterfaceCompletionHandler<IAudioEndpointVolume>();
var hr = ActivateAudioInterfaceAsync(
speakerId,
typeof(IAudioEndpointVolume).GetTypeInfo().GUID,
IntPtr.Zero,
completionHandler,
out var activateOperation);
Debug.Assert(hr == (uint)HResult.S_OK);
return completionHandler.WaitForCompletion();
}
[DllImport("Mmdevapi.dll", ExactSpelling = true, PreserveSig = false)]
[return: MarshalAs(UnmanagedType.Error)]
private static extern uint ActivateAudioInterfaceAsync(
[In, MarshalAs(UnmanagedType.LPWStr)]string deviceInterfacePath,
[In, MarshalAs(UnmanagedType.LPStruct)]Guid riid,
[In] IntPtr activationParams,
[In] IActivateAudioInterfaceCompletionHandler completionHandler,
out IActivateAudioInterfaceAsyncOperation activationOperation);
}
internal class ActivateAudioInterfaceCompletionHandler<T> : IActivateAudioInterfaceCompletionHandler
{
private AutoResetEvent _completionEvent;
private T _result;
public ActivateAudioInterfaceCompletionHandler()
{
_completionEvent = new AutoResetEvent(false);
}
public void ActivateCompleted(IActivateAudioInterfaceAsyncOperation operation)
{
operation.GetActivateResult(out var hr, out var activatedInterface);
Debug.Assert(hr == (uint)HResult.S_OK);
_result = (T)activatedInterface;
var setResult = _completionEvent.Set();
Debug.Assert(setResult != false);
}
public T WaitForCompletion()
{
var waitResult = _completionEvent.WaitOne();
Debug.Assert(waitResult != false);
return _result;
}
}
internal enum HResult : uint
{
S_OK = 0
}
[ComImport]
[Guid("5CDF2C82-841E-4546-9722-0CF74078229A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IAudioEndpointVolume
{
[PreserveSig]
int NotImpl1();
[PreserveSig]
int NotImpl2();
[PreserveSig]
int GetChannelCount([Out] [MarshalAs(UnmanagedType.U4)] out uint channelCount);
[PreserveSig]
int SetMasterVolumeLevel(
[In] [MarshalAs(UnmanagedType.R4)] float level,
[In] [MarshalAs(UnmanagedType.LPStruct)] Guid eventContext);
[PreserveSig]
int SetMasterVolumeLevelScalar(
[In] [MarshalAs(UnmanagedType.R4)] float level,
[In] [MarshalAs(UnmanagedType.LPStruct)] Guid eventContext);
[PreserveSig]
int GetMasterVolumeLevel([Out] [MarshalAs(UnmanagedType.R4)] out float level);
[PreserveSig]
int GetMasterVolumeLevelScalar([Out] [MarshalAs(UnmanagedType.R4)] out float level);
[PreserveSig]
int SetChannelVolumeLevel(
[In] [MarshalAs(UnmanagedType.U4)] UInt32 channelNumber,
[In] [MarshalAs(UnmanagedType.R4)] float level,
[In] [MarshalAs(UnmanagedType.LPStruct)] Guid eventContext);
[PreserveSig]
int SetChannelVolumeLevelScalar(
[In] [MarshalAs(UnmanagedType.U4)] uint channelNumber,
[In] [MarshalAs(UnmanagedType.R4)] float level,
[In] [MarshalAs(UnmanagedType.LPStruct)] Guid eventContext);
int GetChannelVolumeLevel(
[In] [MarshalAs(UnmanagedType.U4)] uint channelNumber,
[Out] [MarshalAs(UnmanagedType.R4)] out float level);
[PreserveSig]
int GetChannelVolumeLevelScalar(
[In] [MarshalAs(UnmanagedType.U4)] uint channelNumber,
[Out] [MarshalAs(UnmanagedType.R4)] out float level);
[PreserveSig]
int SetMute(
[In] [MarshalAs(UnmanagedType.Bool)] bool isMuted,
[In] [MarshalAs(UnmanagedType.LPStruct)] Guid eventContext);
[PreserveSig]
int GetMute([Out] [MarshalAs(UnmanagedType.Bool)] out bool isMuted);
[PreserveSig]
int GetVolumeStepInfo(
[Out] [MarshalAs(UnmanagedType.U4)] out uint step,
[Out] [MarshalAs(UnmanagedType.U4)] out uint stepCount);
[PreserveSig]
int VolumeStepUp([In] [MarshalAs(UnmanagedType.LPStruct)] Guid eventContext);
[PreserveSig]
int VolumeStepDown([In] [MarshalAs(UnmanagedType.LPStruct)] Guid eventContext);
[PreserveSig]
int QueryHardwareSupport([Out] [MarshalAs(UnmanagedType.U4)] out uint hardwareSupportMask);
[PreserveSig]
int GetVolumeRange(
[Out] [MarshalAs(UnmanagedType.R4)] out float volumeMin,
[Out] [MarshalAs(UnmanagedType.R4)] out float volumeMax,
[Out] [MarshalAs(UnmanagedType.R4)] out float volumeStep);
}
[ComImport]
[Guid("72A22D78-CDE4-431D-B8CC-843A71199B6D")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IActivateAudioInterfaceAsyncOperation
{
void GetActivateResult(
[MarshalAs(UnmanagedType.Error)]out uint activateResult,
[MarshalAs(UnmanagedType.IUnknown)]out object activatedInterface);
}
[ComImport]
[Guid("41D949AB-9862-444A-80F6-C261334DA5EB")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IActivateAudioInterfaceCompletionHandler
{
void ActivateCompleted(IActivateAudioInterfaceAsyncOperation activateOperation);
}
}
<强>积分强>
sunius提供的代码有两个主要缺点:
为了摆脱不安全的代码和崩溃,使用了更明确的编组属性并保留了签名(请参阅vannatech源代码)