Я хочу поместить историю просмотров YouTube в календарь Google.Android

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Я хочу поместить историю просмотров YouTube в календарь Google.

Сообщение Anonymous »

Чтобы связать учетную запись Google пользователя и записывать использование им приложений и историю просмотров YouTube в их Календаре Google.
Я хочу создать версию https://www для календаря Google. smartertime.com/
Я получаю сообщение об ошибке, когда запускаю приложение в студии Android, и оно вылетает. Я даже не могу получить историю приложений YouTube и не могу добавить их как событие в календарь Google.
**Основная активность
**
`
private fun fetchYouTubeHistoryAndLogToCalendar() { if (signedInAccount == null) { Log.d("YouTubeHistory", "No signed in account, cannot fetch YouTube history.") return }

val credential = GoogleAccountCredential.usingOAuth2(
this, listOf(YouTubeScopes.YOUTUBE_READONLY)
).setSelectedAccount(signedInAccount?.account)

val youtubeService = YouTube.Builder(
com.google.api.client.http.javanet.NetHttpTransport(),
JacksonFactory.getDefaultInstance(),
credential
).setApplicationName("ChapterOne")
.build()

coroutineScope.launch(Dispatchers.IO) {
try {
val response = youtubeService.activities().list("snippet,contentDetails")
.setMine(true)
.setMaxResults(50L)
.execute()

for (activity in response.items) {
val videoId = activity.contentDetails.upload?.videoId ?: continue
val title = activity.snippet.title
val description = activity.snippet.description
val publishedAt = activity.snippet.publishedAt.value

Log.d("YouTubeHistory", "Video ID: $videoId, Title: $title, Description: $description, Published At: $publishedAt")

logEventToCalendar(
appName = title,
packageName = "com.google.android.youtube",
startTime = publishedAt,
endTime = publishedAt + 1000 * 60 * 10 // Assuming each video watched for 10 minutes
)
}
} catch (e: UserRecoverableAuthException) {
pendingTask = { fetchYouTubeHistoryAndLogToCalendar() }
authResultLauncher.launch(e.intent)
} catch (e: GoogleJsonResponseException) {
Log.e("YouTubeHistory", "GoogleJsonResponseException code: ${e.statusCode}, message: ${e.details.message}")
} catch (e: Exception) {
Log.e("YouTubeHistory", "Failed to fetch YouTube history: ${e.localizedMessage}", e)
}
}
}

private fun checkAndLogUsageStats() {
val usageStatsManager = getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager

if (checkUsageStatsPermission()) {
Log.d("UsageStats", "Permission is granted")
val currentTime = System.currentTimeMillis()
val twoHoursAgo = currentTime - 1000 * 60 * 60 * 2
val usageEvents = usageStatsManager.queryEvents(twoHoursAgo, currentTime)
val usageEvent = UsageEvents.Event()

val excludedPackages = listOf(
"com.google.android.gms",
"com.android.providers.media",
"com.google.android.googlequicksearchbox",
"com.android.systemui"
)

val userApps = mutableListOf()
val packages = packageManager.getInstalledPackages(PackageManager.GET_META_DATA)
for (packageInfo in packages) {
if (!isSystemPackage(packageInfo) && !excludedPackages.contains(packageInfo.packageName)) {
userApps.add(packageInfo.packageName)
}
}

var previousApp: String? = null
var previousStartTime: Long = 0
var previousEventType: Int = -1

while (usageEvents.hasNextEvent()) {
usageEvents.getNextEvent(usageEvent)
if (userApps.contains(usageEvent.packageName)) {
val appName = getAppName(usageEvent.packageName)
Log.d("UsageEvent", "Event: $appName, Time: ${usageEvent.timeStamp}, EventType: ${usageEvent.eventType}")

if (usageEvent.eventType == UsageEvents.Event.MOVE_TO_FOREGROUND) {
Log.d("UsageEvent", "$appName moved to foreground: ${usageEvent.packageName}")
if (previousApp != null && previousApp == usageEvent.packageName && previousEventType == UsageEvents.Event.MOVE_TO_BACKGROUND) {
previousEventType = UsageEvents.Event.MOVE_TO_FOREGROUND
} else {
if (previousApp != null && previousEventType == UsageEvents.Event.MOVE_TO_FOREGROUND) {
logEventToCalendar(getAppName(previousApp), previousApp, previousStartTime, usageEvent.timeStamp)
}
previousApp = usageEvent.packageName
previousStartTime = usageEvent.timeStamp
previousEventType = UsageEvents.Event.MOVE_TO_FOREGROUND
}
} else if (usageEvent.eventType == UsageEvents.Event.MOVE_TO_BACKGROUND) {
Log.d("UsageEvent", "$appName moved to background: ${usageEvent.packageName}")
if (previousApp != null && previousApp == usageEvent.packageName && previousEventType == UsageEvents.Event.MOVE_TO_FOREGROUND) {
logEventToCalendar(getAppName(previousApp), previousApp, previousStartTime, usageEvent.timeStamp)
previousEventType = UsageEvents.Event.MOVE_TO_BACKGROUND
}
}
}
}
if (previousApp != null && previousEventType == UsageEvents.Event.MOVE_TO_FOREGROUND) {
logEventToCalendar(getAppName(previousApp), previousApp, previousStartTime, currentTime)
}
} else {
Log.d("UsageStats", "Permission NOT granted")
Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS).also { startActivity(it) }
}
}

private fun checkUsageStatsPermission(): Boolean {
val appOpsManager = getSystemService(AppCompatActivity.APP_OPS_SERVICE) as AppOpsManager
val mode = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
appOpsManager.unsafeCheckOpNoThrow(
"android:get_usage_stats",
Process.myUid(), packageName
)
} else {
appOpsManager.checkOpNoThrow(
"android:get_usage_stats",
Process.myUid(), packageName
)
}
return mode == AppOpsManager.MODE_ALLOWED
}

`
**build.gradle.kts
**
plugins { id("com.android.application")
id("org.jetbrains.kotlin.android")
id("com.google.gms.google-services") }

android { namespace = "com.jp.xx" compileSdk = 34

defaultConfig {
applicationId = "com.jp.xx"
minSdk = 31
targetSdk = 34
versionCode = 1
versionName = "1.0"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary = true
}
}

buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
buildFeatures {
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.5.1"
}
packagingOptions {
resources {
excludes += "META-INF/DEPENDENCIES"
}
}

}

dependencies { implementation(libs.androidx.core.ktx) implementation(libs.androidx.lifecycle.runtime.ktx) implementation(libs.androidx.activity.compose) implementation(platform(libs.androidx.compose.bom)) implementation(libs.androidx.ui) implementation(libs.androidx.ui.graphics) implementation(libs.androidx.ui.tooling.preview) implementation(libs.androidx.material3) implementation(libs.androidx.appcompat) implementation(libs.firebase.auth) testImplementation(libs.junit) androidTestImplementation(libs.androidx.junit) androidTestImplementation(libs.androidx.espresso.core) androidTestImplementation(platform(libs.androidx.compose.bom)) androidTestImplementation(libs.androidx.ui.test.junit4) debugImplementation(libs.androidx.ui.tooling) debugImplementation(libs.androidx.ui.test.manifest)
implementation("com.google.api-client:google-api-client-android:1.32.1")
implementation("com.google.http-client:google-http-client-jackson2:1.41.5")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0")
implementation("com.google.apis:google-api-services-youtube:v3-rev222-1.25.0")
implementation("com.google.android.gms:play-services-auth:20.0.1")
implementation("com.google.apis:google-api-services-calendar:v3-rev20240111-2.0.0")
implementation(platform("com.google.firebase:firebase-bom:32.8.1"))
implementation("com.google.firebase:firebase-firestore-ktx")

} apply(plugin = "com.google.gms.google-services")


Подробнее здесь: https://stackoverflow.com/questions/787 ... e-calendar
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»