- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我认为答案是肯定的,但我不确定该怎么做。我一直在使用 API 从设备上存储的日历中获取事件。例如
public static ArrayList<MINCalendarEvent> queryEvents(long startMillis, long endMillis) throws MINPermissionException
{
if ( ContextCompat.checkSelfPermission(MINMainActivity.getSharedInstance(), Manifest.permission.WRITE_CALENDAR) != PackageManager.PERMISSION_GRANTED )
{
throw new MINPermissionException(NO_PERMISSION);
}
else
{
ArrayList<MINCalendarEvent> eventArray = new ArrayList<MINCalendarEvent>();
Cursor cur = CalendarContract.Instances.query(MINMainActivity.getSharedInstance().getContentResolver(), EVENT_PROJECTION, startMillis, endMillis);
int numItems = cur.getCount();
Log.d("MINCalendarUtils.queryEvents", "Number of events retrieved: " + numItems);
while (cur.moveToNext())
{
MINCalendarEvent event = new MINCalendarEvent();
event.calendarID = cur.getLong(EVENT_PROJECTION_CALENDAR_ID);
event.organizer = cur.getString(EVENT_PROJECTION_ORGANIZER);
event.title = cur.getString(EVENT_PROJECTION_TITLE);
event.eventLocation = cur.getString(EVENT_PROJECTION_EVENT_LOCATION);
event.description = cur.getString(EVENT_PROJECTION_DESCRIPTION);
event.dtStart = cur.getLong(EVENT_PROJECTION_DTSTART);
event.dtEnd = cur.getLong(EVENT_PROJECTION_DTEND);
event.eventTimeZone = cur.getString(EVENT_PROJECTION_EVENT_TIMEZONE);
event.eventEndTimeZone = cur.getString(EVENT_PROJECTION_EVENT_END_TIMEZONE);
event.duration = cur.getString(EVENT_PROJECTION_DURATION);
event.allDay = (cur.getInt(EVENT_PROJECTION_ALL_DAY) != 0);
event.rRule = cur.getString(EVENT_PROJECTION_RRULE);
event.rDate = cur.getString(EVENT_PROJECTION_RDATE);
event.availability = cur.getInt(EVENT_PROJECTION_AVAILABILITY);
event.guestsCanModify = (cur.getInt(EVENT_PROJECTION_GUESTS_CAN_MODIFY) != 0);
event.guestsCanInviteOthers = (cur.getInt(EVENT_PROJECTION_GUESTS_CAN_INVITE_OTHERS) != 0);
event.guestsCanSeeGuests = (cur.getInt(EVENT_PROJECTION_GUESTS_CAN_SEE_GUESTS) != 0);
eventArray.add(event);
}
return eventArray;
}
}
这很好用。问题是我需要查询存储在用户没有权限的服务器上的共享日历。我的应用程序创建了一个本地日历。我需要访问一个用户也没有权限的共享,并将存储在共享日历中的事件与本地日历(非同步)同步。我假设我可以使用服务帐户访问共享日历。
我已成功创建服务帐户并将该帐户添加到共享日历。现在呢????
似乎有几种使用服务帐户访问日历事件的方法,但我完全搞不清楚。显然,我想使用我一直在使用的 API,但我认为它只适用于与设备同步的日历。
我已经使用“GoogleCredentials”进行了调查,但我需要一些示例源代码才能完成这项工作。首先,当我创建服务帐户时,我使用 JSON 而不是 p12 将其导出。我不知道如何使用它。 API 似乎需要 p12。我也完全不知道如何在获得凭据后使用这些凭据。这是我开始使用的示例源:
//String emailAddress = "123456789000-abc123def456@developer.gserviceaccount.com";
GoogleCredential credential = null;
JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
HttpTransport httpTransport = null;
try
{
httpTransport = GoogleNetHttpTransport.newTrustedTransport();
credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId(emailAddress)
.setServiceAccountPrivateKeyFromP12File(new File("MyProject.p12"))
.setServiceAccountScopes(Collections.singleton(SQLAdminScopes.SQLSERVICE_ADMIN))
.build();
}
catch (GeneralSecurityException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
有几个问题。 1)我无法编译它。我似乎无法让导入工作:
import com.google.api.services.sqladmin.SQLAdminScopes;
假设我可以克服它,现在该怎么做。我不确定如何使用凭据访问远程日历。我需要的是从共享日历中获取事件列表。
我也一直在通过以下链接查看源代码以获取指导,但它不使用服务帐户:https://developers.google.com/google-apps/calendar/quickstart/android
此外,是否有一种方法可以 Hook 对基于服务器的共享日历的更改,以便在共享日历发生更改时收到 ping 通知?
有什么帮助吗????
根据 Andres 的回答,我整理了以下代码:
public static void calendarAuthenticate()
{
Thread thread = new Thread(new Runnable()
{
@Override
public void run()
{
try
{
MINAppConfiguration appConfig = MINAppConfiguration.getSharedInstance();
// Application Name
appName = appConfig.getCurrentAppInfo().appName;
// Directory to store user credentials for this application;
//dataStoreDir = new File(appConfig.appDirectoryOnDevice);
// Instance of the JSON factory
jsonFactory = JacksonFactory.getDefaultInstance();
// Instance of the scopes required
scopes = new ArrayList<String>();
scopes.add(CalendarScopes.CALENDAR_READONLY);
// Http transport creation
httpTransport = AndroidHttp.newCompatibleTransport();
java.io.File licenseFile = getSecretFile();
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setServiceAccountId("account-1@handy-contact-762.iam.gserviceaccount.com")
.setServiceAccountScopes(scopes)
.setServiceAccountPrivateKeyFromP12File(licenseFile)
.build();
com.google.api.services.calendar.Calendar.Builder builder = new com.google.api.services.calendar.Calendar.Builder(httpTransport, jsonFactory, credential);
builder.setApplicationName(appName);
com.google.api.services.calendar.Calendar client = builder.build();
// List the next 10 events from the target calendar.
DateTime now = new DateTime(System.currentTimeMillis());
com.google.api.services.calendar.Calendar.Events.List list = client.events().list("mobilityinitiative.com_qfvbdrk368f9la06hacb4bduos@group.calendar.google.com");
list.setMaxAttendees(10);
list.setTimeMin(now);
list.setOrderBy("startTime");
list.setSingleEvents(true);
Events events = list.execute();
List<Event> items = events.getItems();
if (items.size() == 0)
{
Log.d(TAG, "No upcoming events found.");
}
else
{
Log.d(TAG, "Upcoming events");
for (Event event : items) {
DateTime start = event.getStart().getDateTime();
if (start == null) {
start = event.getStart().getDate();
}
Log.d(TAG, event.getSummary() + " (" + start + ")\n");
}
}
}
catch (GeneralSecurityException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
});
thread.start();
}
public static java.io.File getSecretFile()
{
File f = new File(MINMainActivity.getSharedInstance().getCacheDir()+ "/" +"google_calendar_secret.p12");
if (f.exists())
{
f.delete();
}
try
{
InputStream is = MINMainActivity.getSharedInstance().getAssets().open("google_calendar_secret.p12");
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
FileOutputStream fos = new FileOutputStream(f);
fos.write(buffer);
fos.close();
}
catch (Exception e)
{
throw new RuntimeException(e);
}
return f;
}
一些注意事项:
最佳答案
我不是 Android 专家,但以下任一方法都适用于您的用例。
您的方法:使用服务帐户,将避免用户对您的应用程序进行身份验证。您可能想阅读有关“Delegating domain-wide authority”的内容',这将允许您的应用程序以您域中的用户身份进行 API 调用(也称为“模拟”用户)。我也找到了这个SO有帮助。
另一种方法:使用 Acl.Insert资源。这将要求用户每次登录到您的应用程序时进行身份验证。这是一个 example关于如何实现这一点。
从上面的示例源中,将范围设置为日历范围而不是 SQL 管理,看起来像这样:
GoogleCredential credential = new GoogleCredential.Builder()
...
.setServiceAccountScopes(CalendarScopes.CALENDAR)
.setServiceAccountPrivateKeyFromP12File(xxxx)
.build();
希望这对您有所帮助,祝您好运!
关于android - 如何让我的 Android 应用程序使用 "Service Account"访问共享的 Google 日历?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33947631/
只是想知道是否有可能找出谁从 Windows 共享中读取了文件(最好使用 .NET,但 win32 native 可以)? 我想做的是创建类似 awstats 的东西对于 Windows 共享,这样我
是否可以列出 Intent.ACTION_SEND ?我的意思是我需要知道是否有人通过 action_send 在 Facebook 上分享或在 Twitter 上发推文。 最佳答案 也许你想要一个更
我正在使用 Google Apps 应用程序。实际上,我想在不使用密码的情况下访问另一个 ID。我使用了 OAuth,它运行良好。但我无法分享特定人的日历。我尝试了以下代码。 GoogleOAuthP
我怎样才能只创建模拟器...可能吗?我知道,设备需要分发证书。 最佳答案 您只需将应用程序目录从 iPhone 模拟器复制到另一个实例/操作系统版本,它就应该可以工作。 因此,如果您想分发 3.1.3
我想使用多阶段构建来避免每次构建应用程序时都下载我的 Java 项目所需的所有 Maven 依赖项。 我正在考虑在第一阶段解决 Maven 依赖项,然后在第二阶段构建应用程序,这将需要访问在前一阶段下
我正在寻找保护用户下载内容的初步想法。用户下载充满有趣资源的 zip 文件,这些资源被提取到本地文件系统中以供应用程序使用。我的目标是防止用户通过互联网将下载的资源共享给其他用户(假设他们获得了对文件
我想知道在具有移动和桌面版本的网站上共享身份验证、 session 管理等的最佳方法是什么。我们正在运行 Tomcat,并且更愿意将移动站点和桌面站点的应用程序保持在不同的节点上。 我看过类似的帖子,
我发现了这个单例的实现。我怎样才能创建指向它的指针或共享指针?` 为什么这不起作用?自动测试 = Singleton::Instance(); class Singleton { public: st
我有一个 heroku 项目,我想与其他人分享。作为the instructions describe ,我使用 virtualenv 来管理环境和依赖项。有没有办法在新机器上从 requiremen
Maven 将所有 jar 存储在本地存储库 ~/.m2/repository/ 下。用户多时占用空间大。 那么,是否可以由多个用户共享这个本地存储库,或许在不同的目录结构下? 最佳答案 简单的回答
为什么共享 worker 在重新加载页面时死了?应该是复活了我该如何解决这个问题? 重装前 重新加载后(在example.com上按F5) parent worker var port = new S
我正在开发多个小型应用程序,这些应用程序将共享通用和共享模块和 Assets 。 关于如何创建项目结构的部分在这里回答:https://stackoverflow.com/a/61254557/135
我在 RHEL 上安装了 jenkins (localhost:8080),我能够成功地构建代码 现在,我想设置主/从代理。 我的笔记本电脑将充当“Master Jenkins”,而我同事的笔记本电脑
我有这种方法可以根据我使用的 EXTRA_STREAM 共享文本文件或图片。我有这两个我可以选择 i.putExtra(Intent.EXTRA_STREAM, uri); i.putExtra(In
我正在使用 R 中的一个数据分析项目,我正在使用 R 中的敏感私有(private)数据进行一些逻辑和多级建模。我爱上了 。预订 包,我已经创建了一本关于我们的工作流程和分析管道的相当广泛的书。问题是
我正在构建的应用程序需要在 UITabBarController 框架内为多个 View (及其 subview )显示共享的自定义 UIToolbar。自定义工具栏的内容在所有 View 中都是相同
我有多个应用程序,我想共享相同的 eslint 配置: - project_root/ - app1/ - node_modules/ - eslint.rc
我有多个 Electron 应用程序。一个是主应用程序,其他几个功能应用程序。主应用程序上的按钮很少,这将导致功能应用程序打开。这里的问题是每个应用程序都有一个主进程,该进程导致要利用更多的CPU。是
我正在开发一个 Node.js 后端,它通过 websocket 与一些桌面客户端进行通信,而服务器端的通信是从 Web 前端发起的。一切正常,因为我将 SockJS Connection 实例存储在
我对托管多个网站的服务器上的多个用户帐户使用私有(private) SSH key 和无密码条目。 我为每个用户帐户使用相同的私钥。 (因为我很懒?或者那是“正确”的方式)。 我现在想授权该国不同地区
我是一名优秀的程序员,十分优秀!