Android Google 日历 API 推送到 Google 播放时无法正常工作
Android Google Calendar API not working when pushed to Google Play
我在使用 google 日历 api 和 android 时遇到问题。一切正常(调试 + 发布)但是当将发布 apk 推送到 Play 商店时,下载的版本在尝试使用 api 时抛出异常。我正在记录产生的错误:println("couldn't insert into Google Calendar! " + e.message)
这是 I/System.out: couldn't insert into Google Calendar! null
这是 kotlin 的东西还是我遗漏了什么?
这是我的 GoogleCalendar.kt
:
package de.schooldiary.flokol120.schooldiary.utils
import android.Manifest
import android.app.Activity
import android.content.Context
import android.net.ConnectivityManager
import android.os.AsyncTask
import android.widget.Toast
import com.google.android.gms.common.ConnectionResult
import com.google.android.gms.common.GoogleApiAvailability
import com.google.api.client.extensions.android.http.AndroidHttp
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential
import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException
import com.google.api.client.json.jackson2.JacksonFactory
import com.google.api.client.util.DateTime
import com.google.api.client.util.ExponentialBackOff
import com.google.api.services.calendar.CalendarScopes
import com.google.api.services.calendar.model.Event
import com.google.api.services.calendar.model.EventDateTime
import com.google.api.services.calendar.model.EventReminder
import pub.devrel.easypermissions.AfterPermissionGranted
import pub.devrel.easypermissions.EasyPermissions
import java.io.IOException
import java.text.SimpleDateFormat
import java.util.*
import kotlin.collections.ArrayList
class GoogleCalendar(val context: Activity): EasyPermissions.PermissionCallbacks {
var mCredential: GoogleAccountCredential
companion object {
internal const val REQUEST_ACCOUNT_PICKER: Int = 1000
internal const val REQUEST_AUTHORIZATION = 1001
internal const val REQUEST_GOOGLE_PLAY_SERVICES = 1002
internal const val REQUEST_PERMISSION_GET_ACCOUNTS = 1003
internal const val PREF_ACCOUNT_NAME = "accountName"
var lastAdded: ArrayList<Any> = ArrayList()
var lastError: String = ""
private class InsertData internal constructor(credential: GoogleAccountCredential): AsyncTask<ArrayList<Any>, Void, Void>(){
private var mService: com.google.api.services.calendar.Calendar? = null
init {
val transport = AndroidHttp.newCompatibleTransport()
val jsonFactory = JacksonFactory.getDefaultInstance()
mService = com.google.api.services.calendar.Calendar.Builder(
transport, jsonFactory, credential)
.setApplicationName("School Diary")
.build()
}
override fun doInBackground(vararg params: ArrayList<Any>?): Void? {
if(params.isNotEmpty()){
for (subList: ArrayList<Any>? in params){
if(subList != null) {
insertEvent(subList[0] as String, subList[1] as String, subList[2] as String,
subList[3] as String, subList[4] as Boolean, subList[5] as Boolean,
subList[6] as Boolean, subList[7] as Activity)
}
}
}
return null
}
@Throws(IOException::class)
private fun insertEvent(summary: String, des: String, startDate: String, endDate: String,
repeating: Boolean, reminder: Boolean, dateTime: Boolean, context: Activity) {
try{
if(!startDate.isEmpty()){
val startDater: DateTime
val endDater: DateTime
val formatter: SimpleDateFormat
println(startDate)
println(endDate)
if(!dateTime){
formatter = SimpleDateFormat("dd.MM.yyyy", Locale.getDefault())
startDater = DateTime(formatter.parse(startDate))
endDater = DateTime(formatter.parse(endDate))
}else{
formatter = SimpleDateFormat("dd-MM-yyyy HH:mm:ss.SSS", Locale.getDefault())
startDater = DateTime(formatter.parse(startDate))
endDater = DateTime(formatter.parse(endDate))
}
val event = Event()
.setSummary(summary)
.setDescription(des)
val start = EventDateTime()
.setDateTime(startDater)
.setTimeZone("Europe/Berlin")
event.start = start
val end = EventDateTime()
.setDateTime(endDater)
.setTimeZone("Europe/Berlin")
event.end = end
if(repeating){
val recurrence = arrayOf("RRULE:FREQ=WEEKLY")
event.recurrence = Arrays.asList(*recurrence)
}
if(reminder){
val reminderOverrides = arrayOf(EventReminder().setMethod("email").setMinutes(24 * 60), EventReminder().setMethod("popup").setMinutes(10))
val reminders = Event.Reminders()
.setUseDefault(false)
.setOverrides(Arrays.asList(*reminderOverrides))
event.reminders = reminders
}else{
event.reminders = Event.Reminders()
.setUseDefault(false)
}
val calendarId = "primary"
//val calendarId = context.getString(R.string.app_name)
mService?.events()?.insert(calendarId, event)?.setSendNotifications(true)?.execute()
lastError = "added event successfully to google calendar!!"
}
}catch (e: UserRecoverableAuthIOException){
lastAdded = arrayListOf(summary, des, startDate, endDate, repeating, reminder, dateTime)
//Toast.makeText(context, "something went wrong, adding the event to your google calendar (${e.message})", Toast.LENGTH_LONG).show()
context.startActivityForResult(e.intent, REQUEST_AUTHORIZATION)
lastError = "something went wrong, adding the event to your google calendar (${e.message})"
}catch (e: Exception){
//Toast.makeText(context, "couldn't insert into Google Calendar! " + e.localizedMessage, Toast.LENGTH_LONG).show()
println("couldn't insert into Google Calendar! " + e.message)
lastError = "something went wrong, adding the event to your google calendar (${e.message})"
//Toast.makeText(context, "something went wrong, adding the event to your google calendar (${e.message})", Toast.LENGTH_LONG).show()
}
}
}
}
val SCOPES = arrayOf(CalendarScopes.CALENDAR)
init {
// Initialize credentials and service object.
mCredential = GoogleAccountCredential.usingOAuth2(
context.applicationContext, Arrays.asList(*SCOPES))
.setBackOff(ExponentialBackOff())
}
/**
* Attempt to call the API, after verifying that all the preconditions are
* satisfied. The preconditions are: Google Play Services installed, an
* account was selected and the device currently has online access. If any
* of the preconditions are not satisfied, the app will prompt the user as
* appropriate.
*/
fun insertEvent(summary: String, des: String, startDate: String, endDate: String,
repeating: Boolean, reminder: Boolean, dateTime: Boolean) {
if(lastError != ""){
Toast.makeText(context, lastError, Toast.LENGTH_LONG).show()
}
if (!isGooglePlayServicesAvailable()) {
acquireGooglePlayServices()
} else if (mCredential.selectedAccountName == null) {
chooseAccount(summary, des, startDate, endDate, repeating, reminder, dateTime)
} else if (!isDeviceOnline()) {
Toast.makeText(context, "No network connection available.", Toast.LENGTH_LONG).show()
} else {
//MakeRequestTask(mCredential).execute()
InsertData(mCredential).execute(arrayListOf(summary, des, startDate, endDate, repeating, reminder, dateTime, context))
}
}
/**
* Attempts to set the account used with the API credentials. If an account
* name was previously saved it will use that one; otherwise an account
* picker dialog will be shown to the user. Note that the setting the
* account to use with the credentials object requires the app to have the
* GET_ACCOUNTS permission, which is requested here if it is not already
* present. The AfterPermissionGranted annotation indicates that this
* function will be rerun automatically whenever the GET_ACCOUNTS permission
* is granted.
*/
@AfterPermissionGranted(REQUEST_PERMISSION_GET_ACCOUNTS)
private fun chooseAccount(summary: String, des: String, startDate: String, endDate: String,
repeating: Boolean, reminder: Boolean, dateTime: Boolean) {
if (EasyPermissions.hasPermissions(
context, Manifest.permission.GET_ACCOUNTS)) {
val accountName = context.getPreferences(Context.MODE_PRIVATE)
.getString(PREF_ACCOUNT_NAME, null)
if (accountName != null) {
mCredential.selectedAccountName = accountName
insertEvent(summary, des, startDate, endDate, repeating, reminder, dateTime)
} else {
// Start a dialog from which the user can choose an account
lastAdded = arrayListOf(summary, des, startDate, endDate, repeating, reminder, dateTime)
context.startActivityForResult(mCredential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER)
//insertEvent(summary, des, startDate, endDate, repeating, reminder, dateTime)
}
} else {
// Request the GET_ACCOUNTS permission via a user dialog
EasyPermissions.requestPermissions(
context,
"This app needs to access your Google account (via Contacts).",
REQUEST_PERMISSION_GET_ACCOUNTS,
Manifest.permission.GET_ACCOUNTS)
}
}
/**
* Respond to requests for permissions at runtime for API 23 and above.
* @param requestCode The request code passed in
* requestPermissions(android.app.Activity, String, int, String[])
* @param permissions The requested permissions. Never null.
* @param grantResults The grant results for the corresponding permissions
* which is either PERMISSION_GRANTED or PERMISSION_DENIED. Never null.
*/
override fun onRequestPermissionsResult(requestCode: Int,
permissions: Array<String>,
grantResults: IntArray) {
EasyPermissions.onRequestPermissionsResult(
requestCode, permissions, grantResults, this)
}
/**
* Callback for when a permission is granted using the EasyPermissions
* library.
* @param requestCode The request code associated with the requested
* permission
* @param list The requested permission list. Never null.
*/
override fun onPermissionsGranted(requestCode: Int, list: List<String>) {
// Do nothing.
}
/**
* Callback for when a permission is denied using the EasyPermissions
* library.
* @param requestCode The request code associated with the requested
* permission
* @param list The requested permission list. Never null.
*/
override fun onPermissionsDenied(requestCode: Int, list: List<String>) {
// Do nothing.
}
/**
* Checks whether the device currently has a network connection.
* @return true if the device has a network connection, false otherwise.
*/
private fun isDeviceOnline(): Boolean {
val connMgr = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager?
val networkInfo = connMgr!!.activeNetworkInfo
return networkInfo != null && networkInfo.isConnected
}
/**
* Check that Google Play services APK is installed and up to date.
* @return true if Google Play Services is available and up to
* date on this device; false otherwise.
*/
private fun isGooglePlayServicesAvailable(): Boolean {
val apiAvailability = GoogleApiAvailability.getInstance()
val connectionStatusCode = apiAvailability.isGooglePlayServicesAvailable(context)
return connectionStatusCode == ConnectionResult.SUCCESS
}
/**
* Attempt to resolve a missing, out-of-date, invalid or disabled Google
* Play Services installation via a user dialog, if possible.
*/
private fun acquireGooglePlayServices() {
val apiAvailability = GoogleApiAvailability.getInstance()
val connectionStatusCode = apiAvailability.isGooglePlayServicesAvailable(context)
if (apiAvailability.isUserResolvableError(connectionStatusCode)) {
showGooglePlayServicesAvailabilityErrorDialog(connectionStatusCode)
}
}
/**
* Display an error dialog showing that Google Play Services is missing
* or out of date.
* @param connectionStatusCode code describing the presence (or lack of)
* Google Play Services on this device.
*/
private fun showGooglePlayServicesAvailabilityErrorDialog(
connectionStatusCode: Int) {
val apiAvailability = GoogleApiAvailability.getInstance()
val dialog = apiAvailability.getErrorDialog(
context,
connectionStatusCode,
REQUEST_GOOGLE_PLAY_SERVICES)
dialog.show()
}
}
我在AndroidManifest.xml
中设置的权限:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
我的MainActivity.kt
中的onActivityResult
函数:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
when (requestCode) {
GoogleCalendar.REQUEST_GOOGLE_PLAY_SERVICES -> if (resultCode != Activity.RESULT_OK) {
Toast.makeText(this, "This app requires Google Play Services. Please install " + "Google Play Services on your device and relaunch this app."
, Toast.LENGTH_LONG).show()
}
de.schooldiary.flokol120.schooldiary.utils.GoogleCalendar.REQUEST_ACCOUNT_PICKER -> if (resultCode == Activity.RESULT_OK && data != null &&
data.extras != null) {
val accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME)
if (accountName != null) {
val settings = getPreferences(Context.MODE_PRIVATE)
val editor = settings.edit()
editor.putString(GoogleCalendar.PREF_ACCOUNT_NAME, accountName)
editor.apply()
gCalendar.mCredential.selectedAccountName = accountName
}
val list: ArrayList<Any> = GoogleCalendar.lastAdded
if(list.isNotEmpty()){
gCalendar.insertEvent(list[0] as String, list[1] as String, list[2] as String,
list[3] as String, list[4] as Boolean, list[5] as Boolean, list[6] as Boolean)
}
}
de.schooldiary.flokol120.schooldiary.utils.GoogleCalendar.REQUEST_AUTHORIZATION -> if (resultCode == Activity.RESULT_OK) {
val list: ArrayList<Any> = GoogleCalendar.lastAdded
if(list.isNotEmpty()){
gCalendar.insertEvent(list[0] as String, list[1] as String, list[2] as String,
list[3] as String, list[4] as Boolean, list[5] as Boolean, list[6] as Boolean)
}
}
}
super.onActivityResult(requestCode, resultCode, data)
}
我在 build.gradle
中的实现:
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:27.1.0'
implementation 'com.android.support:design:27.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
implementation 'com.android.support:support-v4:27.1.0'
implementation 'com.android.support:cardview-v7:27.1.0'
implementation 'com.android.support:recyclerview-v7:27.1.0'
implementation 'com.github.QuadFlask:colorpicker:0.0.13'
implementation 'com.github.florent37:expansionpanel:1.0.6'
implementation 'com.google.android.gms:play-services-auth:11.8.0'
implementation 'pub.devrel:easypermissions:1.1.3'
implementation('com.google.api-client:google-api-client-android:1.23.0') {
exclude group: 'org.apache.httpcomponents'
}
implementation('com.google.apis:google-api-services-calendar:v3-rev292-1.23.0') {
exclude group: 'org.apache.httpcomponents'
}
implementation 'com.google.firebase:firebase-ads:11.8.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
}
对于遇到此类问题的每个人:
启用新的 Google 签名功能时,您需要将 Google Play 管理中心的指纹添加到经过身份验证的指纹列表中。
我在使用 google 日历 api 和 android 时遇到问题。一切正常(调试 + 发布)但是当将发布 apk 推送到 Play 商店时,下载的版本在尝试使用 api 时抛出异常。我正在记录产生的错误:println("couldn't insert into Google Calendar! " + e.message)
这是 I/System.out: couldn't insert into Google Calendar! null
这是 kotlin 的东西还是我遗漏了什么?
这是我的 GoogleCalendar.kt
:
package de.schooldiary.flokol120.schooldiary.utils
import android.Manifest
import android.app.Activity
import android.content.Context
import android.net.ConnectivityManager
import android.os.AsyncTask
import android.widget.Toast
import com.google.android.gms.common.ConnectionResult
import com.google.android.gms.common.GoogleApiAvailability
import com.google.api.client.extensions.android.http.AndroidHttp
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential
import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException
import com.google.api.client.json.jackson2.JacksonFactory
import com.google.api.client.util.DateTime
import com.google.api.client.util.ExponentialBackOff
import com.google.api.services.calendar.CalendarScopes
import com.google.api.services.calendar.model.Event
import com.google.api.services.calendar.model.EventDateTime
import com.google.api.services.calendar.model.EventReminder
import pub.devrel.easypermissions.AfterPermissionGranted
import pub.devrel.easypermissions.EasyPermissions
import java.io.IOException
import java.text.SimpleDateFormat
import java.util.*
import kotlin.collections.ArrayList
class GoogleCalendar(val context: Activity): EasyPermissions.PermissionCallbacks {
var mCredential: GoogleAccountCredential
companion object {
internal const val REQUEST_ACCOUNT_PICKER: Int = 1000
internal const val REQUEST_AUTHORIZATION = 1001
internal const val REQUEST_GOOGLE_PLAY_SERVICES = 1002
internal const val REQUEST_PERMISSION_GET_ACCOUNTS = 1003
internal const val PREF_ACCOUNT_NAME = "accountName"
var lastAdded: ArrayList<Any> = ArrayList()
var lastError: String = ""
private class InsertData internal constructor(credential: GoogleAccountCredential): AsyncTask<ArrayList<Any>, Void, Void>(){
private var mService: com.google.api.services.calendar.Calendar? = null
init {
val transport = AndroidHttp.newCompatibleTransport()
val jsonFactory = JacksonFactory.getDefaultInstance()
mService = com.google.api.services.calendar.Calendar.Builder(
transport, jsonFactory, credential)
.setApplicationName("School Diary")
.build()
}
override fun doInBackground(vararg params: ArrayList<Any>?): Void? {
if(params.isNotEmpty()){
for (subList: ArrayList<Any>? in params){
if(subList != null) {
insertEvent(subList[0] as String, subList[1] as String, subList[2] as String,
subList[3] as String, subList[4] as Boolean, subList[5] as Boolean,
subList[6] as Boolean, subList[7] as Activity)
}
}
}
return null
}
@Throws(IOException::class)
private fun insertEvent(summary: String, des: String, startDate: String, endDate: String,
repeating: Boolean, reminder: Boolean, dateTime: Boolean, context: Activity) {
try{
if(!startDate.isEmpty()){
val startDater: DateTime
val endDater: DateTime
val formatter: SimpleDateFormat
println(startDate)
println(endDate)
if(!dateTime){
formatter = SimpleDateFormat("dd.MM.yyyy", Locale.getDefault())
startDater = DateTime(formatter.parse(startDate))
endDater = DateTime(formatter.parse(endDate))
}else{
formatter = SimpleDateFormat("dd-MM-yyyy HH:mm:ss.SSS", Locale.getDefault())
startDater = DateTime(formatter.parse(startDate))
endDater = DateTime(formatter.parse(endDate))
}
val event = Event()
.setSummary(summary)
.setDescription(des)
val start = EventDateTime()
.setDateTime(startDater)
.setTimeZone("Europe/Berlin")
event.start = start
val end = EventDateTime()
.setDateTime(endDater)
.setTimeZone("Europe/Berlin")
event.end = end
if(repeating){
val recurrence = arrayOf("RRULE:FREQ=WEEKLY")
event.recurrence = Arrays.asList(*recurrence)
}
if(reminder){
val reminderOverrides = arrayOf(EventReminder().setMethod("email").setMinutes(24 * 60), EventReminder().setMethod("popup").setMinutes(10))
val reminders = Event.Reminders()
.setUseDefault(false)
.setOverrides(Arrays.asList(*reminderOverrides))
event.reminders = reminders
}else{
event.reminders = Event.Reminders()
.setUseDefault(false)
}
val calendarId = "primary"
//val calendarId = context.getString(R.string.app_name)
mService?.events()?.insert(calendarId, event)?.setSendNotifications(true)?.execute()
lastError = "added event successfully to google calendar!!"
}
}catch (e: UserRecoverableAuthIOException){
lastAdded = arrayListOf(summary, des, startDate, endDate, repeating, reminder, dateTime)
//Toast.makeText(context, "something went wrong, adding the event to your google calendar (${e.message})", Toast.LENGTH_LONG).show()
context.startActivityForResult(e.intent, REQUEST_AUTHORIZATION)
lastError = "something went wrong, adding the event to your google calendar (${e.message})"
}catch (e: Exception){
//Toast.makeText(context, "couldn't insert into Google Calendar! " + e.localizedMessage, Toast.LENGTH_LONG).show()
println("couldn't insert into Google Calendar! " + e.message)
lastError = "something went wrong, adding the event to your google calendar (${e.message})"
//Toast.makeText(context, "something went wrong, adding the event to your google calendar (${e.message})", Toast.LENGTH_LONG).show()
}
}
}
}
val SCOPES = arrayOf(CalendarScopes.CALENDAR)
init {
// Initialize credentials and service object.
mCredential = GoogleAccountCredential.usingOAuth2(
context.applicationContext, Arrays.asList(*SCOPES))
.setBackOff(ExponentialBackOff())
}
/**
* Attempt to call the API, after verifying that all the preconditions are
* satisfied. The preconditions are: Google Play Services installed, an
* account was selected and the device currently has online access. If any
* of the preconditions are not satisfied, the app will prompt the user as
* appropriate.
*/
fun insertEvent(summary: String, des: String, startDate: String, endDate: String,
repeating: Boolean, reminder: Boolean, dateTime: Boolean) {
if(lastError != ""){
Toast.makeText(context, lastError, Toast.LENGTH_LONG).show()
}
if (!isGooglePlayServicesAvailable()) {
acquireGooglePlayServices()
} else if (mCredential.selectedAccountName == null) {
chooseAccount(summary, des, startDate, endDate, repeating, reminder, dateTime)
} else if (!isDeviceOnline()) {
Toast.makeText(context, "No network connection available.", Toast.LENGTH_LONG).show()
} else {
//MakeRequestTask(mCredential).execute()
InsertData(mCredential).execute(arrayListOf(summary, des, startDate, endDate, repeating, reminder, dateTime, context))
}
}
/**
* Attempts to set the account used with the API credentials. If an account
* name was previously saved it will use that one; otherwise an account
* picker dialog will be shown to the user. Note that the setting the
* account to use with the credentials object requires the app to have the
* GET_ACCOUNTS permission, which is requested here if it is not already
* present. The AfterPermissionGranted annotation indicates that this
* function will be rerun automatically whenever the GET_ACCOUNTS permission
* is granted.
*/
@AfterPermissionGranted(REQUEST_PERMISSION_GET_ACCOUNTS)
private fun chooseAccount(summary: String, des: String, startDate: String, endDate: String,
repeating: Boolean, reminder: Boolean, dateTime: Boolean) {
if (EasyPermissions.hasPermissions(
context, Manifest.permission.GET_ACCOUNTS)) {
val accountName = context.getPreferences(Context.MODE_PRIVATE)
.getString(PREF_ACCOUNT_NAME, null)
if (accountName != null) {
mCredential.selectedAccountName = accountName
insertEvent(summary, des, startDate, endDate, repeating, reminder, dateTime)
} else {
// Start a dialog from which the user can choose an account
lastAdded = arrayListOf(summary, des, startDate, endDate, repeating, reminder, dateTime)
context.startActivityForResult(mCredential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER)
//insertEvent(summary, des, startDate, endDate, repeating, reminder, dateTime)
}
} else {
// Request the GET_ACCOUNTS permission via a user dialog
EasyPermissions.requestPermissions(
context,
"This app needs to access your Google account (via Contacts).",
REQUEST_PERMISSION_GET_ACCOUNTS,
Manifest.permission.GET_ACCOUNTS)
}
}
/**
* Respond to requests for permissions at runtime for API 23 and above.
* @param requestCode The request code passed in
* requestPermissions(android.app.Activity, String, int, String[])
* @param permissions The requested permissions. Never null.
* @param grantResults The grant results for the corresponding permissions
* which is either PERMISSION_GRANTED or PERMISSION_DENIED. Never null.
*/
override fun onRequestPermissionsResult(requestCode: Int,
permissions: Array<String>,
grantResults: IntArray) {
EasyPermissions.onRequestPermissionsResult(
requestCode, permissions, grantResults, this)
}
/**
* Callback for when a permission is granted using the EasyPermissions
* library.
* @param requestCode The request code associated with the requested
* permission
* @param list The requested permission list. Never null.
*/
override fun onPermissionsGranted(requestCode: Int, list: List<String>) {
// Do nothing.
}
/**
* Callback for when a permission is denied using the EasyPermissions
* library.
* @param requestCode The request code associated with the requested
* permission
* @param list The requested permission list. Never null.
*/
override fun onPermissionsDenied(requestCode: Int, list: List<String>) {
// Do nothing.
}
/**
* Checks whether the device currently has a network connection.
* @return true if the device has a network connection, false otherwise.
*/
private fun isDeviceOnline(): Boolean {
val connMgr = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager?
val networkInfo = connMgr!!.activeNetworkInfo
return networkInfo != null && networkInfo.isConnected
}
/**
* Check that Google Play services APK is installed and up to date.
* @return true if Google Play Services is available and up to
* date on this device; false otherwise.
*/
private fun isGooglePlayServicesAvailable(): Boolean {
val apiAvailability = GoogleApiAvailability.getInstance()
val connectionStatusCode = apiAvailability.isGooglePlayServicesAvailable(context)
return connectionStatusCode == ConnectionResult.SUCCESS
}
/**
* Attempt to resolve a missing, out-of-date, invalid or disabled Google
* Play Services installation via a user dialog, if possible.
*/
private fun acquireGooglePlayServices() {
val apiAvailability = GoogleApiAvailability.getInstance()
val connectionStatusCode = apiAvailability.isGooglePlayServicesAvailable(context)
if (apiAvailability.isUserResolvableError(connectionStatusCode)) {
showGooglePlayServicesAvailabilityErrorDialog(connectionStatusCode)
}
}
/**
* Display an error dialog showing that Google Play Services is missing
* or out of date.
* @param connectionStatusCode code describing the presence (or lack of)
* Google Play Services on this device.
*/
private fun showGooglePlayServicesAvailabilityErrorDialog(
connectionStatusCode: Int) {
val apiAvailability = GoogleApiAvailability.getInstance()
val dialog = apiAvailability.getErrorDialog(
context,
connectionStatusCode,
REQUEST_GOOGLE_PLAY_SERVICES)
dialog.show()
}
}
我在AndroidManifest.xml
中设置的权限:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
我的MainActivity.kt
中的onActivityResult
函数:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
when (requestCode) {
GoogleCalendar.REQUEST_GOOGLE_PLAY_SERVICES -> if (resultCode != Activity.RESULT_OK) {
Toast.makeText(this, "This app requires Google Play Services. Please install " + "Google Play Services on your device and relaunch this app."
, Toast.LENGTH_LONG).show()
}
de.schooldiary.flokol120.schooldiary.utils.GoogleCalendar.REQUEST_ACCOUNT_PICKER -> if (resultCode == Activity.RESULT_OK && data != null &&
data.extras != null) {
val accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME)
if (accountName != null) {
val settings = getPreferences(Context.MODE_PRIVATE)
val editor = settings.edit()
editor.putString(GoogleCalendar.PREF_ACCOUNT_NAME, accountName)
editor.apply()
gCalendar.mCredential.selectedAccountName = accountName
}
val list: ArrayList<Any> = GoogleCalendar.lastAdded
if(list.isNotEmpty()){
gCalendar.insertEvent(list[0] as String, list[1] as String, list[2] as String,
list[3] as String, list[4] as Boolean, list[5] as Boolean, list[6] as Boolean)
}
}
de.schooldiary.flokol120.schooldiary.utils.GoogleCalendar.REQUEST_AUTHORIZATION -> if (resultCode == Activity.RESULT_OK) {
val list: ArrayList<Any> = GoogleCalendar.lastAdded
if(list.isNotEmpty()){
gCalendar.insertEvent(list[0] as String, list[1] as String, list[2] as String,
list[3] as String, list[4] as Boolean, list[5] as Boolean, list[6] as Boolean)
}
}
}
super.onActivityResult(requestCode, resultCode, data)
}
我在 build.gradle
中的实现:
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:27.1.0'
implementation 'com.android.support:design:27.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
implementation 'com.android.support:support-v4:27.1.0'
implementation 'com.android.support:cardview-v7:27.1.0'
implementation 'com.android.support:recyclerview-v7:27.1.0'
implementation 'com.github.QuadFlask:colorpicker:0.0.13'
implementation 'com.github.florent37:expansionpanel:1.0.6'
implementation 'com.google.android.gms:play-services-auth:11.8.0'
implementation 'pub.devrel:easypermissions:1.1.3'
implementation('com.google.api-client:google-api-client-android:1.23.0') {
exclude group: 'org.apache.httpcomponents'
}
implementation('com.google.apis:google-api-services-calendar:v3-rev292-1.23.0') {
exclude group: 'org.apache.httpcomponents'
}
implementation 'com.google.firebase:firebase-ads:11.8.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
}
对于遇到此类问题的每个人: 启用新的 Google 签名功能时,您需要将 Google Play 管理中心的指纹添加到经过身份验证的指纹列表中。