c# - 使用 C# TAPI 调用监视器
问题描述
我需要创建一个程序来监控电话活动。并获取有关电话的信息,例如号码和姓名。我不擅长 TAPI 代码和 C#,所以希望有人能帮助我,我很绝望。
我有这段代码,我在其中尝试检测可用设备并在来电时从这些设备获取信息:
using System;
using TAPI3Lib;
using JulMar.Atapi;
namespace ConsoleApp1
{
class Program
{
private void tapi_ITTAPIEventNotification_Event(TAPI_EVENT TapiEvent, object pEvent)
{
try
{
ITCallNotificationEvent cn = pEvent as ITCallNotificationEvent;
if(cn.Call.CallState == CALL_STATE.CS_CONNECTED)
{
string calledidname = cn.Call.get_CallInfoString(CALLINFO_STRING.CIS_CALLEDIDNAME);
Console.WriteLine("Called ID Name " + calledidname);
string callednumber = cn.Call.get_CallInfoString(CALLINFO_STRING.CIS_CALLEDIDNUMBER);
Console.WriteLine("Called Number " + callednumber);
string calleridname = cn.Call.get_CallInfoString(CALLINFO_STRING.CIS_CALLERIDNAME);
Console.WriteLine("Caller ID Name " + calleridname);
string callernumber = cn.Call.get_CallInfoString(CALLINFO_STRING.CIS_CALLERIDNUMBER);
Console.WriteLine("Caller Number " + callernumber);
}
}
catch(Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
static void Main(string[] args)
{
TapiManager mgr = new TapiManager("ConsoleApp1");
mgr.Initialize();
foreach(TapiLine line in mgr.Lines)
{
foreach (string s in line.Capabilities.AvailableDeviceClasses)
Console.WriteLine("{0} - {1}", line.Name, s);
}
}
}
}
但是当我运行它时,只看到可用的设备,但看不到任何有关呼叫的信息。我习惯于用 java 编程,所以我想我应该发送来调用在 main 中获取调用信息的方法,但我不知道如何做到这一点,并且在我见过的任何代码中他们都这样做。所以,希望你能帮助我理解 TAPI 是如何工作的,以及我可以做些什么来完成我的代码工作。
解决方案
好的,首先,您要坚持使用一个版本的 TAPI。在您的using
语句中,您正在导入一个 TAPI 2.x 托管库和一个 TAPI 3.x 托管库。
using TAPI3Lib; // this is a TAPI 3.x library
using JulMar.Atapi; // this is a TAPI 2.x library
如果您选择使用 TAPI 3.x,您应该首先创建一个新类,该类处理不同类型的 TAPI 事件。为此,它需要实现ITTAPIEventNotification
接口:
public class CallNotification : ITTAPIEventNotification
{
public void Event(TAPI_EVENT TapiEvent, object pEvent)
{
if(pEvent == null)
throw new ArgumentNullException(nameof(pEvent));
switch (TapiEvent)
{
case TAPI_EVENT.TE_CALLNOTIFICATION:
// This event will be raised every time a new call is created on an monitored line-
// You can use CALLINFO_LONG.CIL_ORIGIN to see weather it's an inbound call, or an
// outbound call.
break;
case TAPI_EVENT.TE_CALLSTATE:
// This event will be raised every time the state of a call on one of your monitored
// Lines changes.
// If you'd want to read information about a call, you can do it here:
ITCallStateEvent callStateEvent = (ITCallStateEvent)pEvent;
ITCallInfo call = callStateEvent.Call;
string calledidname = call.get_CallInfoString(CALLINFO_STRING.CIS_CALLEDIDNAME);
Console.WriteLine("Called ID Name " + calledidname);
string callednumber = call.get_CallInfoString(CALLINFO_STRING.CIS_CALLEDIDNUMBER);
Console.WriteLine("Called Number " + callednumber);
string calleridname = call.get_CallInfoString(CALLINFO_STRING.CIS_CALLERIDNAME);
Console.WriteLine("Caller ID Name " + calleridname);
string callernumber = call.get_CallInfoString(CALLINFO_STRING.CIS_CALLERIDNUMBER);
Console.WriteLine("Caller Number " + callernumber);
break;
}
// Since you're working with COM objects, you should release any used references.
Marshal.ReleaseComObject(pEvent);
}
}
为了使用这个类,你需要创建一个新的实例TAPI3Lib.TAPIClass
并调用它的Initialize
方法。之后,您可以将新创建CallNotification
的类附加为事件处理程序。您还可以指定您希望处理程序接收哪些类型的事件。请注意,此时您不会收到任何事件通知,因为您还没有告诉TAPIClass
它应该监视哪些行:
CallNotification callevent = new CallNotification();
TAPIClass tapi = new TAPIClass();
tapi.Initialize();
tapi.EventFilter = (int)(TAPI_EVENT.TE_CALLNOTIFICATION | TAPI_EVENT.TE_CALLSTATE);
tapi.ITTAPIEventNotification_Event_Event += new ITTAPIEventNotification_EventEventHandler(callevent.Event);
为了知道TAPIClass
它应该监控哪些线路,您需要做两件事。询问注册给您 IPBX 的所有线路,并确定您有权监控的线路(这是 IPBX 配置):
public List<ITAddress> EnumerateLines(TAPIClass tapi)
{
List<ITAddress> addresses = new List<ITAddress>();
ITAddress address;
uint arg = 0;
ITAddressCapabilities addressCapabilities;
int callfeatures;
int linefeatures;
bool hasCallFeaturesDial;
bool hasLineFeaturesMakeCall;
IEnumAddress ea = tapi.EnumerateAddresses();
do
{
ea.Next(1, out address, ref arg);
if (address != null)
{
addressCapabilities = (ITAddressCapabilities)address;
callfeatures = addressCapabilities.get_AddressCapability(ADDRESS_CAPABILITY.AC_CALLFEATURES1);
linefeatures = addressCapabilities.get_AddressCapability(ADDRESS_CAPABILITY.AC_LINEFEATURES);
hasCallFeaturesDial = (callfeatures1 & (int)0x00000040) != 0; //Contains LineCallFeatures Dial; see Tapi.h for details
hasLineFeaturesMakeCall = (linefeatures & (int)0x00000008) != 0; //Contains LineFeatures MakeCall; see Tapi.h for details
// this is basically saying "Am I allowed to dial numbers and create calls on this specific line?"
if(hasCallFeaturesDial && hasLineFeaturesMakeCall)
address.Add(address);
}
} while (address != null);
return addresses;
}
public void RegisterLines(TAPIClass tapi, IEnumerable<ITAddress> addresses)
{
if (tapi == null)
throw new ArgumentNullException(nameof(tapi));
if (addresses == null)
throw new ArgumentNullException(nameof(addresses));
foreach (ITAddress address in addresses)
{
tapi.RegisterCallNotifications(address, true, true, TapiConstants.TAPIMEDIATYPE_AUDIO, 2);
}
}
所以你的初始化看起来像这样:
CallNotification callevent = new CallNotification();
TAPIClass tapi = new TAPIClass();
tapi.Initialize();
IEnumerable<ITAddress> addresses = this.EnumerateLines(tapi);
this.RegisterLines(tapi, addresses);
tapi.EventFilter = (int)(TAPI_EVENT.TE_CALLNOTIFICATION | TAPI_EVENT.TE_CALLSTATE);
tapi.ITTAPIEventNotification_Event_Event += new
ITTAPIEventNotification_EventEventHandler(callevent.Event);
运行程序并执行完上述代码后,当呼叫状态发生变化时,您将收到来自传入和传出呼叫的通知。
我希望你能关注这个帖子。如果您有任何问题,请直接询问 =)
推荐阅读
- tabs - tns create app-name --template tns-template-drawer-navigation-ng
- python - 如何让 Python 文件打开到现有的 Spyder IDE 会话中
- javascript - 经常更新不同大小的顶点缓冲区部分
- python - MySQL插入一个条目,其中值数<列数
- android - 即时应用在奥利奥设备上未激活
- mysql - SQLite / MySQL 使用 LIKE 或 REGEXP 匹配 String 中的特殊内容词
- macos - 在 OSX 上安装 ocaml-top - GTK 问题
- java - Java中的优化方法
- asp.net - 在 IIS 上呈现奇怪的字符
- postgresql - SQL查询带有美元符号的表