原文链接:https://github.com/chenxizhang/office365dev/blob/e9b5a59cb827841d36692cc4ec52c11d43062e04/docs/timeline.md

前言

前不久微软正式放出了Windows 10 春季更新(1803),其中有一个非常有特色的应用,就是Windows 10 新增了一个Timeline(时间线)的应用,这个应用可以让用户一目了然地看到最近一段时间所有在Windows中的活动,包括浏览过什么网页,打开过什么文档,设置过什么选项等。下图是一个示范的效果图:

请注意,这里看到的信息不是一个静态的图片,每一个卡片都是可以点击的,而且点击之后会通过调用对应的应用程序自动打开这些活动(恢复到之前的状态),就好像时光倒流了一样。

看起来很酷,不是吗?那么,这样一个应用到底是怎么实现的呢?我们如果也想实现类似的场景,有什么样的思路呢?答案在上周的Microsoft Build 大会上做了揭晓:其实Timeline是一个基于Microsoft Graph实现的应用,只不过他读取的数据,不仅限于Office 365的文档历史,还包括了Windows 10 上面的活动,这也是近年来一个重大的变化:微软已经把Office 365、Windows 10、EMS这三个产品合并为一个——Microsoft 365,将为最终用户提供最佳的体验,他们的能力也将统一通过Microsoft Graph向开发者提供服务。

原理解析

首先,从技术上说,要实现这个Timeline应用,用户需要允许相关的活动源将有关信息发送给Microsoft Graph。这里所谓的活动源,可以是Office客户端,也可以是Windows 10的应用程序。微软一直致力于保护用户的隐私,所以这个Timeline的功能,默认是不开启的,只有用户在被明确告知上述行为并且选择接受的情况下,才会开始收集数据并进行展现。

其次,除了Windows 10自带的Timeline应用,其实只要几行代码,就能实现一个类似的时间线应用。那么问题就来了,这些应用之间的数据是不是隔离的呢?答案是肯定的,也就是说Windows 10这个Timeline应用只能读取到它在经用户同意的前提下收集的那部分活动数据,而我们自定义的应用也是如此。

最后,这里面还有一个有意思的概念。一个活动(Activity)可以对应一个或者多个历史记录(History Items)。历史纪录相当于是活动在某个时间点的快照。

据说这个技术,最早在内部有一个代码叫做“Project Rome”,现在合并到了Microsoft Graph中,并且已经在V1.0中提供。相关官方文档请参考 https://developer.microsoft.com/en-us/graph/docs/concepts/activity-feed-concept-overview .

创建Timeline应用

有了如上概念,我们就闲话少说,撸起袖子加油干吧。因为要访问Microsoft Graph,所以你就必须要注册一个AAD的应用程序。注册这样一个应用程序没有什么特别的,唯一要了解的是,要支持用户活动的读写,需要申请一个UserActivity.ReadWrite.CreatedByApp的委派权限(Delegated Permission),如下图所示

大家可以看到,这个权限并不需要管理员认可就能工作。

请注意,目前UserActivity.ReadWrite.CreatedByApp这个权限,仅在国际版的环境中可以用,而且必须在AAD 1.0的环境中实现。AAD 2.0还不支持,国内版(Gallatin)也暂时不支持。

如何发布Activity

Windows 10自带的Timeline其实是一个UWP应用,不过你可以用你最熟悉的方式来实现自定义的Timeline应用。但抛开这些具体的界面,我们可以快速了解一下如何创建和更新用户活动(Activity)。

创建或更新Activity的API,请参考 https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/api/projectrome_put_activity, 大体上说,这里的关键是用PUT方法操作,同时我们既可以单独创建Activity,也可以在创建Activity的时候同时创建History Item,后者也称为“Deep Insert”。

为了给大家直观演示效果,我这里简化一下步骤。我将采用官方的Microsoft Graph Explorer来模拟一个客户端,并且直接用REST API来进行操作。如果你对Microsoft Graph Explorer不太熟悉,你可能需要先阅读一下这篇文章

正如上一节提到的,你需要确保授予了UserActivity.ReadWrite.CreatedByApp这个权限,请参考下图

我直接用官方给的例子,为当前用户新增一个网络文章浏览的活动,请注意下面的appActivityIdactivitySourceHostactivationUrlvisualElements 是必须的。这个例子的意思是指定义了用户这个活动是浏览了 http://www.contoso.com/article?id=12345 这个Url所指向的一篇文章。

{
"appActivityId": "/article?12345",
"activitySourceHost": "https://www.contoso.com",
"userTimezone": "Africa/Casablanca",
"appDisplayName": "Contoso, Ltd.",
"activationUrl": "http://www.contoso.com/article?id=12345",
"contentUrl": "http://www.contoso.com/article?id=12345",
"fallbackUrl": "http://www.contoso.com/article?id=12345",
"contentInfo": {
"@context": "http://schema.org",
"@type": "Article",
"author": "Jennifer Booth",
"name": "How to Tie a Reef Knot"
},
"visualElements": {
"attribution": {
"iconUrl": "http://www.contoso.com/icon",
"alternateText": "Contoso, Ltd.",
"addImageQuery": "false",
},
"description": "How to Tie a Reef Knot. A step-by-step visual guide to the art of nautical knot-tying.",
"backgroundColor": "#ff0000",
"displayText": "Contoso How-To: How to Tie a Reef Knot",
"content": {
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"body":
[{
"type": "TextBlock",
"text": "Contoso MainPage"
}]
}
}
}

在Microsoft Graph Explorer 中用PUT方法,将上述数据,发送到https://graph.microsoft.com/v1.0/me/activities/%2Farticle%3F12345, 同时记得设置Content-Type为application/json

如果一切正常的话,你将收到一个回复,里面包含了在Microsoft Graph中创建的Activity的信息,这里会返回全局唯一的id属性。

请注意,如果要更新,也是使用同样的一个命令。而如果要进行删除,则需要用 DELETE 方法,请参考 https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/api/projectrome_delete_activity

如何查询Activity

有两个接口用来查询用户活动(Activity),分别是

  1. 获取用户活动(可以获取全部,也可以获取指定筛选条件的活动),如果需要同时包含历史信息,则需要添加查询参数 $expand=historyitems。 详细的API说明,请参考 https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/api/projectrome_get_activities

  2. 获取用户最近的活动。可以理解为上一种的简化版本,Microsoft Graph会查询最近的一个History Items,然后找到它们对应的活动条目。详细的API说明,请参考 https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/api/projectrome_get_recent_activities

下面是一个简单的查询例子


结语

这一篇文章带领大家了解了Windows 10最新版本中Timeline这个功能的实现原理,并且用实例演示了如何使用Microsoft Graph来实现自定义的类似应用,我用Microsoft Graph Explorer做了演示,大家可以一目了然地看到接口的调用和返回值。

因为这个功能比较新,Microsoft Graph的SDK中,还没有完全包含这个功能,我还发现.NET SDK中存在一点小问题,已经跟产品团队反馈了。所以,如果你现在开始做实践,建议还使用REST API的方式。

基于Microsoft Graph打造自己的Timeline应用的更多相关文章

  1. 扩展Microsoft Graph数据结构(开放扩展)

    作者:陈希章 发表于 2018年1月2日 前言 Microsoft Graph是一张拥有巨大价值的网络,它定义了包括Office 365在内的资源的实体及其关系,它的价值体现在,随着用户积累的数据越来 ...

  2. 基于Microsoft Azure、ASP.NET Core和Docker的博客系统

    欢迎阅读daxnet的新博客:一个基于Microsoft Azure.ASP.NET Core和Docker的博客系统   2008年11月,我在博客园开通了个人帐号,并在博客园发表了自己的第一篇博客 ...

  3. 在无人值守程序(服务)中调用Microsoft Graph

    作者:陈希章 发表于 2017年5月31日 什么是无人值守程序(服务) 我在此前用了几篇文章分别介绍了在桌面应用程序(控制台),Web应用程序(ASP.NET MVC),以及PowerSehll脚本中 ...

  4. 在PowerShell脚本中集成Microsoft Graph

    作者:陈希章 发表于2017年4月23日 我旗帜鲜明地表态,我很喜欢PowerShell,相比较于此前的Cmd Shell,它有一些重大的创新,例如基于.NET的类型系统,以及管道.模块的概念等等.那 ...

  5. 扩展Microsoft Graph数据结构 - 架构扩展

    前言 此前我有一篇 文章 讲解了Microsoft Graph的一种数据扩展技术-- 开发扩展(Open Extensions),它可以实现在支持的对象(例如用户,组等)上面附加任意的数据.但开放扩展 ...

  6. 基于windows 10打造的kali工具集

    基于windows 10打造的kali工具集.iso,适合于习惯使用windows的安全从业者.if you like it,please touch star! 作为安全从业主,Kali都是必备工具 ...

  7. win10 uwp 使用 Microsoft.Graph 发送邮件

    在 2018 年 10 月 13 号参加了 张队长 的 Office 365 训练营 学习如何开发 Office 365 插件和 OAuth 2.0 开发,于是我就使用 UWP 尝试使用 Micros ...

  8. 如何使用 Azure Active Directory 认证和 Microsoft Graph 构建 Blazor Web 应用

    如何使用 Azure Active Directory 认证和 Microsoft Graph 构建 Blazor Web 应用 英文原文:https://developer.microsoft.co ...

  9. 跨平台应用集成(在ASP.NET Core MVC 应用程序中集成 Microsoft Graph)

    作者:陈希章 发表于 2017年6月25日 谈一谈.NET 的跨平台 终于要写到这一篇了.跨平台的支持可以说是 Office 365 平台在设计伊始就考虑的目标.我在前面的文章已经提到过了,Micro ...

随机推荐

  1. 【翻译】针对多种设备定制Ext JS 5应用程序

    原文:Tailoring Your Ext JS 5 Application for a Multi-Device World 概述 鉴于当今设备和表单因素的扩散,要针对所有这些可能性来优化应用程序已 ...

  2. java中,用json格式转换遇到问题

    将list转为JSONObject类,报 org/apache/commons/lang/exception/NestableRuntimeException是什么原因? 还需要导入这些包common ...

  3. DQM Serial Sync Index Program ERROR

    Error syncing hz_stage_party_sites_t1:ORA-20000:Oracle Text 错误: DRG-10502:索引AR.HZ_STAGE_PARTY_SITES_ ...

  4. Android的内存分配与回收

    想写一篇关于android的内存分配和回收文章的想法来源于追查一个魅族手机图片滑动卡顿问题,我们想了很多办法还是没有避免他不停的GC,所以就打算详细的看看内存分配和GC的原理,为什么会不断的GC,GC ...

  5. Emotiv脑电设备与RDS机器人仿真初步测试

    Emotiv脑电设备与RDS机器人仿真初步测试 在脑电设备相关算法进行真实机器人测试前,有必要进行大量仿真验证算法,节约开发时间. 这里给我启发的Emotiv使用所参考的一些网址. 官网:https: ...

  6. URLClassLoader

    package com.reflect.load; import java.net.URL; import java.net.URLClassLoader; import java.sql.Conne ...

  7. Android群英传笔记——第七章:Android动画机制和使用技巧

    Android群英传笔记--第七章:Android动画机制和使用技巧 想来,最 近忙的不可开交,都把看书给冷落了,还有好几本没有看完呢,速度得加快了 今天看了第七章,Android动画效果一直是人家中 ...

  8. ANN实现

    ANN核心数据结构: typedef struct  {     int input_n;                  /* number of input units */     int h ...

  9. Android MTK平台最完备的开机动画修改教程

    修改手机的开机动画不是什么难事儿. 但修改一款很冷门的"山寨机",就不太好修改第一屏了. 手机是MTK的一款手机,虽然比较贵(价格超过三星Note3),但在我看来跟山寨机木有啥区别 ...

  10. 深入理解JNI

    深入理解JNI 最近在学习android底层的一些东西,看了一些大神的博客,整体上有了一点把握,也产生了很多疑惑,于是再次把邓大神的深入系列翻出来仔细看看,下面主要是一些阅读笔记. JNI概述 JNI ...