Google マップへ投稿すると Google Pixel 製品を 10%オフ にできる件

メールが来ました!

 おすすめ: 最新の Google Pixel 製品が 10% オフ

Google マップへの投稿のお礼として、Google Pixel 7、Google Pixel 7 Pro、Google Pixel Watch を含む Google の新製品が 10% オフになる特典をご用意しました。Google ストアに在庫があるうちに次のお買い物をして 10% オフを使いましょう。¹

また、10%引きとかwww

いつものプロモーションコードでの割引です。

Google マップへ投稿して Google Pixel 製品を 10%オフ にできる件

¹プロモーション コードによる特典は、Google 合同会社 が提供するものです。日本の Google ストアのみで利用でき、下記の利用規約が適用されます。日本国内にお住まいで、配送先住所が日本国内にある場合のみご利用いただけます。18 歳以上の方のみを対象とします。プロモーション コードは、2022 年 11 月 15 日午後 9 時 59 分(日本時間)までに日本の Google ストアでご利用ください。それまでにご利用いただけない場合は、期限切れで失効します。その他のプロモーション コードや、同時期に実施中の他の同時購入特典や割引などの特典とは併用できません。在庫がなくなり次第終了させていただきます。

Google マップに投稿しているともらえるのか。

このメッセージは、ローカルガイドからニュースやサービスの最新情報をメールで受け取るようお申し込みされた方にお送りしています。配信の停止やメール設定の変更はローカルガイドの設定ページで行うことができます。

iPhone 14 同様に売れてないのかもしれません、Pixel 7。

👉 【Google ストア公式】Pixel 7/7 PRO プロモーションコード でさらにダメ押しの 10%割引 を見逃すな - 2022年10月16日午後11時59分まで hatena-bookmark


Jetpack Compose Samples でも使われている「Version catalog update plugin」で libs.versions.toml を書き出してみる

一度は見たことがあるでしょう「Jetpack Compose Samples」。

Jetpack Compose Samples

👉 android/compose-samples: Official Jetpack Compose samples. hatena-bookmark

こんな記述があります。

👉 Jetchat/build.gradle.kts#L39-L42 hatena-bookmark

何でしょうか、調べてみましょう。

 

■ Version catalog update plugin

このプラグインは、libs.versions.toml の作成や更新をしてくれるようです。


👉 littlerobots/version-catalog-update-plugin: Gradle plugin for updating a project version catalog hatena-bookmark

一度、書き出して、どのようになるか確かめてみます。

 

■ 作成


./gradlew versionCatalogUpdate --create

作成されました。


[versions]
androidx-appcompat = "1.5.1"
androidx-arch-core = "2.1.0"
androidx-core = "1.8.0"
androidx-emoji2 = "1.2.0"
androidx-vectordrawable = "1.1.0"
org-jetbrains-kotlin = "1.7.20"
org-jetbrains-kotlinx = "1.6.1"

[libraries]
androidx-activity = "androidx.activity:activity:1.5.1"
androidx-annotation = "androidx.annotation:annotation:1.3.0"
androidx-annotation-annotation-experimental = "androidx.annotation:annotation-experimental:1.1.0"
androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "androidx-appcompat" }
androidx-appcompat-appcompat-resources = { module = "androidx.appcompat:appcompat-resources", version.ref = "androidx-appcompat" }
androidx-arch-core-core-common = { module = "androidx.arch.core:core-common", version.ref = "androidx-arch-core" }
androidx-arch-core-core-runtime = { module = "androidx.arch.core:core-runtime", version.ref = "androidx-arch-core" }
androidx-cardview = "androidx.cardview:cardview:1.0.0"
androidx-collection = "androidx.collection:collection:1.1.0"
androidx-concurrent-concurrent-futures = "androidx.concurrent:concurrent-futures:1.0.0"
androidx-constraintlayout = "androidx.constraintlayout:constraintlayout:2.1.4"
androidx-constraintlayout-constraintlayout-core = "androidx.constraintlayout:constraintlayout-core:1.0.4"
androidx-constraintlayout-constraintlayout-solver = "androidx.constraintlayout:constraintlayout-solver:2.0.1"
androidx-coordinatorlayout = "androidx.coordinatorlayout:coordinatorlayout:1.1.0"
androidx-core = { module = "androidx.core:core", version.ref = "androidx-core" }
androidx-core-core-ktx = { module = "androidx.core:core-ktx", version.ref = "androidx-core" }
androidx-cursoradapter = "androidx.cursoradapter:cursoradapter:1.0.0"
androidx-customview = "androidx.customview:customview:1.1.0"
androidx-documentfile = "androidx.documentfile:documentfile:1.0.0"
androidx-drawerlayout = "androidx.drawerlayout:drawerlayout:1.1.1"
androidx-dynamicanimation = "androidx.dynamicanimation:dynamicanimation:1.0.0"
androidx-emoji2 = { module = "androidx.emoji2:emoji2", version.ref = "androidx-emoji2" }
androidx-emoji2-emoji2-views-helper = { module = "androidx.emoji2:emoji2-views-helper", version.ref = "androidx-emoji2" }
androidx-fragment = "androidx.fragment:fragment:1.3.6"
androidx-interpolator = "androidx.interpolator:interpolator:1.0.0"
androidx-legacy-legacy-support-core-utils = "androidx.legacy:legacy-support-core-utils:1.0.0"
androidx-lifecycle-lifecycle-common = "androidx.lifecycle:lifecycle-common:2.5.1"
androidx-lifecycle-lifecycle-livedata = "androidx.lifecycle:lifecycle-livedata:2.0.0"
androidx-lifecycle-lifecycle-livedata-core = "androidx.lifecycle:lifecycle-livedata-core:2.5.1"
androidx-lifecycle-lifecycle-process = "androidx.lifecycle:lifecycle-process:2.4.1"
androidx-lifecycle-lifecycle-runtime = "androidx.lifecycle:lifecycle-runtime:2.5.1"
androidx-lifecycle-lifecycle-viewmodel = "androidx.lifecycle:lifecycle-viewmodel:2.5.1"
androidx-lifecycle-lifecycle-viewmodel-savedstate = "androidx.lifecycle:lifecycle-viewmodel-savedstate:2.5.1"
androidx-loader = "androidx.loader:loader:1.0.0"
androidx-localbroadcastmanager = "androidx.localbroadcastmanager:localbroadcastmanager:1.0.0"
androidx-print = "androidx.print:print:1.0.0"
androidx-recyclerview = "androidx.recyclerview:recyclerview:1.1.0"
androidx-resourceinspection-resourceinspection-annotation = "androidx.resourceinspection:resourceinspection-annotation:1.0.1"
androidx-savedstate = "androidx.savedstate:savedstate:1.2.0"
androidx-startup-startup-runtime = "androidx.startup:startup-runtime:1.1.1"
androidx-test-espresso-espresso-core = "androidx.test.espresso:espresso-core:3.4.0"
androidx-test-ext-junit = "androidx.test.ext:junit:1.1.3"
androidx-tracing = "androidx.tracing:tracing:1.0.0"
androidx-transition = "androidx.transition:transition:1.2.0"
androidx-vectordrawable = { module = "androidx.vectordrawable:vectordrawable", version.ref = "androidx-vectordrawable" }
androidx-vectordrawable-vectordrawable-animated = { module = "androidx.vectordrawable:vectordrawable-animated", version.ref = "androidx-vectordrawable" }
androidx-versionedparcelable = "androidx.versionedparcelable:versionedparcelable:1.1.1"
androidx-viewpager = "androidx.viewpager:viewpager:1.0.0"
androidx-viewpager2 = "androidx.viewpager2:viewpager2:1.0.0"
com-google-android-material = "com.google.android.material:material:1.7.0"
junit = "junit:junit:4.13.2"
org-apache-logging-log4j-log4j-core = "org.apache.logging.log4j:log4j-core:2.17.1"
org-jacoco-org-jacoco-ant = "org.jacoco:org.jacoco.ant:0.8.7"
org-jetbrains-annotations = "org.jetbrains:annotations:13.0"
org-jetbrains-kotlin-kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "org-jetbrains-kotlin" }
org-jetbrains-kotlin-kotlin-stdlib-common = { module = "org.jetbrains.kotlin:kotlin-stdlib-common", version.ref = "org-jetbrains-kotlin" }
org-jetbrains-kotlin-kotlin-stdlib-jdk7 = { module = "org.jetbrains.kotlin:kotlin-stdlib-jdk7", version.ref = "org-jetbrains-kotlin" }
org-jetbrains-kotlin-kotlin-stdlib-jdk8 = { module = "org.jetbrains.kotlin:kotlin-stdlib-jdk8", version.ref = "org-jetbrains-kotlin" }
org-jetbrains-kotlinx-kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "org-jetbrains-kotlinx" }
org-jetbrains-kotlinx-kotlinx-coroutines-bom = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-bom", version.ref = "org-jetbrains-kotlinx" }
org-jetbrains-kotlinx-kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "org-jetbrains-kotlinx" }
org-jetbrains-kotlinx-kotlinx-coroutines-core-jvm = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm", version.ref = "org-jetbrains-kotlinx" }

[plugins]
com-android-application = "com.android.application:7.3.1"
com-android-library = "com.android.library:7.3.1"
com-github-ben-manes-versions = "com.github.ben-manes.versions:0.41.0"
nl-littlerobots-version-catalog-update = "nl.littlerobots.version-catalog-update:0.7.0"
org-jetbrains-kotlin-android = "org.jetbrains.kotlin.android:1.7.20"

フォーマットが統一され、ソートされたきれいなTOMLファイルです。

キーは、kebab-case で重複処理も上手に行ってくれてるように見えます。

👉 【Gradle Version Catalog】libs.versions.toml キー名の形式 camelCase vs kebab-case hatena-bookmark

build.gradle 側は更新しないようなので新規作成は安全ですが、既存の場合は、


./gradlew versionCatalogUpdate --interactive

とすると、別のファイル名 libs.versions.updates.toml で書き出してくれるようです。

Version catalog update plugin

実行後は gradle ディレクトリを Reload すると作成されてることが確認できます。


[plugins]
# From version 7.3.1 --> 8.0.0-alpha06
android-application = "com.android.application:8.0.0-alpha06"

まずは、参考にまで使ってみました。簡単で便利です。

無駄のない最小限の記述なので、最初の書き出しには使うと良いと思います。

👌 もっと、シンプルでいいような気がするので以下の方法でもやってみました。


👉 「⚠ This project uses Gradle Version Catalogs: this tool may not behave as expected.」→ 今現在、Gradle Version Catalog には gradle-versions-plugin が必須では? hatena-bookmark


【Plugin DSL】「com.android.tools.build:gradle」の記述は不要?

Plugin DSL に移行ながらの気持ちが悪いのは以下の変化。


// 2020-10-13
// build.gradle ( root | Project )
classpath "com.android.tools.build:gradle:4.0.2"

// build.gradle ( module | Module )
apply plugin: 'com.android.application'


// 2022-10-25
// build.gradle ( root | Project )
plugins {
  id 'com.android.application' version '7.3.1' apply false
  id 'com.android.library' version '7.3.1' apply false
}

// build.gradle ( module | Module )
plugins {
  id 'com.android.application'
}

👉 今現在 AndroidStudio が推してくる Gradle の設定記述と構成を2年前と比較 - libs.versions.toml, settings.gradle, build.gradle hatena-bookmark

ここに登場する3つの文字列。


com.android.tools.build:gradle
com.android.application
com.android.library

ここらがなんとなくあやふやに使っていたのでよく調べてみます。

 

■ アプリケーションかライブラリか

root の build.gradle でプラグインのバージョンを指定しておいて、


// 2022-10-25
// build.gradle ( root | Project )
plugins {
  id 'com.android.application' version '7.3.1' apply false
  id 'com.android.library' version '7.3.1' apply false
}

その子のモジュールの build.gradle で適用する、


// 2022-10-25
// build.gradle ( module | Module )
plugins {
  id 'com.android.application'
}

ということです。

👉 Applying external plugins with same version to subprojects - Using Gradle Plugins hatena-bookmark

そのときに、そのモジュールがアプリケーションかライブラリかで適用するGradleプラグインのIDが変わります。


plugins {
  id 'com.android.application'
}


plugins {
  id 'com.android.library'
}

👉 Android ライブラリの作成  |  Android デベロッパー  |  Android Developers hatena-bookmark

 

■ 'com.android.tools.build:gradle' の記述

Plugin DSL が登場する前は以下のような記述でしたが、


// 2020-10-13
// build.gradle ( root | Project )
classpath "com.android.tools.build:gradle:4.0.2"

// build.gradle ( module | Module )
apply plugin: 'com.android.application'

Plugin DSL では消えてます、"com.android.tools.build:gradle"

👉 【Plugin DSL】Android Gradle Plugin のバージョンがわからない hatena-bookmark

ここで、Plugin ID から参照されるリポジトリの内容を見てみます。

Google Maven Repository では、

Plugin Marker Artifacts
Since the plugins {} DSL block only allows for declaring plugins by their globally unique plugin id and version properties, Gradle needs a way to look up the coordinates of the plugin implementation artifact. To do so, Gradle will look for a Plugin Marker Artifact with the coordinates plugin.id:plugin.id.gradle.plugin:plugin.version. This marker needs to have a dependency on the actual plugin implementation. Publishing these markers is automated by the java-gradle-plugin.

プラグインマーカーアーティファクト
plugins {} DSLブロックでは、グローバルにユニークなプラグインIDとバージョンプロパティによってのみプラグインを宣言できるので、Gradleはプラグイン実装アーティファクトの座標を検索する方法が必要です。そのために、Gradleは plugin.id:plugin.id.gradle.plugin:plugin.version という座標を持つプラグインマーカーアーティファクトを探します。このマーカーは、実際のプラグイン実装への依存関係を持つ必要があります。これらのマーカーの発行は、java-gradle-pluginによって自動化されます。

👉 Plugin Marker Artifacts - Using Gradle Plugins hatena-bookmark


plugin.id:plugin.id.gradle.plugin:plugin.version
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

ということなので、

Plugin ID : com.android.application は、


Group Id    : com.android.application
Artifact ID : com.android.application.gradle.plugin

で、

Plugin ID : com.android.library は、


Group Id    : com.android.library
Artifact ID : com.android.library.gradle.plugin

で、検索します。


Group ID	com.android.application
Artifact ID	com.android.application.gradle.plugin
Version	8.0.0-alpha06
Gradle Groovy DSL	
implementation 'com.android.application:com.android.application.gradle.plugin:8.0.0-alpha06'
Gradle Kotlin DSL	
implementation("com.android.application:com.android.application.gradle.plugin:8.0.0-alpha06") 
Last Updated Date	10/24/2022


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.android.application</groupId>
  <artifactId>com.android.application.gradle.plugin</artifactId>
  <version>8.0.0-alpha06</version>
  <packaging>pom</packaging>
  <description>Gradle plug-in to build Android applications.</description>
  <url>https://developer.android.com/studio/build</url>
  <name>com.android.tools.build.gradle</name>
  <licenses>
    <license>
      <name>The Apache Software License, Version 2.0</name>
      <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
      <distribution>repo</distribution>
    </license>
  </licenses>
  <developers>
    <developer>
      <name>The Android Open Source Project</name>
    </developer>
  </developers>
  <scm>
    <connection>git://android.googlesource.com/platform/tools/base.git</connection>
    <url>https://android.googlesource.com/platform/tools/base</url>
  </scm>
  <dependencies>
    <dependency>
      <groupId>com.android.tools.build</groupId>
      <artifactId>gradle</artifactId>
      <version>8.0.0-alpha06</version>
    </dependency>
  </dependencies>
</project>

👉 com.android.application.com.android.application.gradle.plugin-8.0.0-alpha06 - Google's Maven Repository hatena-bookmark


Group ID	com.android.library
Artifact ID	com.android.library.gradle.plugin
Version	8.0.0-alpha06
Gradle Groovy DSL	
implementation 'com.android.library:com.android.library.gradle.plugin:8.0.0-alpha06' 
Gradle Kotlin DSL	
implementation("com.android.library:com.android.library.gradle.plugin:8.0.0-alpha06")
Last Updated Date	10/24/2022


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.android.library</groupId>
  <artifactId>com.android.library.gradle.plugin</artifactId>
  <version>8.0.0-alpha06</version>
  <packaging>pom</packaging>
  <description>Gradle plug-in to build Android applications.</description>
  <url>https://developer.android.com/studio/build</url>
  <name>com.android.tools.build.gradle</name>
  <licenses>
    <license>
      <name>The Apache Software License, Version 2.0</name>
      <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
      <distribution>repo</distribution>
    </license>
  </licenses>
  <developers>
    <developer>
      <name>The Android Open Source Project</name>
    </developer>
  </developers>
  <scm>
    <connection>git://android.googlesource.com/platform/tools/base.git</connection>
    <url>https://android.googlesource.com/platform/tools/base</url>
  </scm>
  <dependencies>
    <dependency>
      <groupId>com.android.tools.build</groupId>
      <artifactId>gradle</artifactId>
      <version>8.0.0-alpha06</version>
    </dependency>
  </dependencies>
</project>

👉 com.android.library.com.android.library.gradle.plugin-8.0.0-alpha06 - Google's Maven Repository hatena-bookmark

それぞれ、同じ


<dependency>
  <groupId>com.android.tools.build</groupId>
  <artifactId>gradle</artifactId>
  <version>8.0.0-alpha06</version>
</dependency>

となってますので、以下の実装アーティファクトを解決できてるのでしょう。


Group ID	com.android.tools.build
Artifact ID	gradle
Version	8.0.0-alpha06
Gradle Groovy DSL	
implementation 'com.android.tools.build:gradle:8.0.0-alpha06'
Gradle Kotlin DSL	
implementation("com.android.tools.build:gradle:8.0.0-alpha06") 
Last Updated Date	10/24/2022

👉 com.android.tools.build.gradle-8.0.0-alpha06 - Google's Maven Repository hatena-bookmark

よって、'com.android.tools.build:gradle' の記述は、plugin DSL では記述の必要はないのでしょう。

少し古いコードに以下のような記述が見られるのは、プラグインマーカーアーティファクトが公開される前のものだったということで納得できます。


pluginManagement {
  // ...
  resolutionStrategy {
    eachPlugin {
      if(requested.id.namespace == "com.android") {
        useModule("com.android.tools.build:gradle:${requested.version}")
      }
    }
  }

 

■ まとめ

最後に、AndroidStudio のプロジェクトテンプレートを利用して確認します。

例にならって、 New Project から Empty Activity を選択後、 New Module から Android Library を作成します。

【Plugin DSL】'com.android.tools.build:gradle'

以下、Gradle まわりの設定ファイル該当部分です。


// settings.gradle
pluginManagement {
  repositories {
    gradlePluginPortal()
    google()
    mavenCentral()
  }
  repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
  repositories {
    google()
    mavenCentral()
  }

include ':app'
include ':el'


// build.gradle
plugins {
  id 'com.android.application' version '7.3.1' apply false
  id 'com.android.library' version '7.3.1' apply false
  id 'org.jetbrains.kotlin.android' version '1.7.20' apply false


// app/build.gradle
plugins {
  id 'com.android.application'
  id 'org.jetbrains.kotlin.android'
  implementation project(path: ':el')


// el/build.gradle
plugins {
  id 'com.android.library'
  id 'org.jetbrains.kotlin.android'

'com.android.tools.build:gradle' は見当たりませんね!

素晴らしいです、Plugin DSL !!

👉 Jetpack Compose Samples でも使われている「Version catalog update plugin」で libs.versions.toml を書き出してみる hatena-bookmark
👉 今現在 AndroidStudio が推してくる Gradle の設定記述と構成を2年前と比較 - libs.versions.toml, settings.gradle, build.gradle hatena-bookmark