Flutter Home_Widgetの実装がマジわからんのでメモ書きなう
はいはいわたしです。
先日までgeminiの話をしていますが、ちょっと仲違いしまして、、
(私がやりたいことはまだできなさそうという判断をしました(´・ω・`)
くっそーー!という気持ちの中で、やけくそで別のアプリをゴリゴリ作っております。
※スマホに時間に追われるゲームを入れてしまったため、めちゃんこゆっくりw
で、以上前置き。
本題です。アプリに初めてホームウェジットってやつを追加しようと思いましたところめちゃくそ泥沼に使っているなうです。
もう三日はやってる。www
何が悪いかって
Androidアプリ(in AndroidStudio)の開発方法にJavaとKotlinがあるうえでFlutterをメインで利用しよう!という考えがすべてを面倒にしているという感じであります。。。
と、いうことで自身の頭をすっきりさせるために!これを書き記す!
ちゃんとできたら公開する!!
今回は真面目に最初からやります
利用するのは私が大好きAndroidStudioでふー
※昔、エクリプスに挑戦したことがあったんですが、、昔使っていたパソコンはスペックがくそだったんで、実行に数分待たされて待ちきれずに諦めた過去がある。。(調べると結構重かったみたいでふ。。)
それに比べるとめちゃんこ軽くてサクサク(PCのスペックが上がったから
エミュレータもなかなかよきですー(PCのスペックをちゃんと上げたから
複数プロジェクトを立ち上げてもry(PCのスペックをry
・・・脱線終了。
いやぁ、最近のパソコンってサクサク動きますね。HD→SSDへの変更が一番インパクトデカかったような気がします。
と、いうことでAndroidStudioであたらしいFlutterプロジェクトを作成するよ
(あ、Webで調べるとき、英語での回答の方が多いから、AndroidStudioの表示、英語のままで使っているのでそのつもりでおなしゃす)
今回迷走しすぎてくそ長くなってしまったので、
やり方だけ知りてえんだよ〇〇が!
って人は下の目次からぽちっとしてもらうとよいです。
※※ここからしばらく迷走を続けます。。※※
迷走の名残・・・
Flutterプロジェクトの作成
File->New->NewFlutterProject をクリーック!
で、えーっとね右下のNextをクリーックしますよ。
適当に入力(嘘
一番上から行くか、、
ProjectName
まんまプロジェクト名です。わかる名前を入れましょう。まぁファイル名ですね。(ザクザク
ProjectLocation
保存先です。保存先わからなくならんように気を付けてな。
Description
よくわかりませんwなんか説明を入れる欄みたいですが、私は毎回無視してるww
ProjectType
プロジェクトの種類ですね。
・・・いろいろありますが、今回はアプリ作りたいのでApplicationでOKです。
Organization
ここはですね、、リリースする気がないなら何でも良いです。
要はリリースされるときに「このあぷり!」ってわかるように一意の名前が欲しいんでしょうねGoogleさんが。
(「一意」が何かだって?AIにおしえてもらうのです)
AndroidLanguage
androidアプリを開発する際の言語ですね。
Flutter(Dart)で開発するだよ?っておもうだよ?(誤タップおもろw
FlutterはDartを使用するのですが、AndroidやiOSで実装できるすべての機能を網羅しているかというとそうではなくてですね、
その網羅していない部分の実装なんかはそれぞれ作ってあげなければならなかったりするんです。
(詳しく話すと無知がばれる!!!)
そのための言語をどうしますか?ってやつです。
選択肢はJavaかKotlinがあります(最近はGoogleがKotlinを推している傾向がある。。気がする※KotlinのJetpack苦手民・・・(´・ω・`))
iOSLanguage
iOS側の開発する際の言語ですね。
Objective-cとSwiftが選べます(どっちもやったことないな(´・ω・`))
Platforms
作成したいアプリをどこで動かしたいか?
Android,iOS,Linux,MacOS,Web,Windowsの選択肢があり、複数選べます。
複数選ぶとどうなるかって?
・・・開発が複雑になるよ!(´・ω・`)
リリースする気がないなら自分が使うと思う奴だけオンにしておけばよいです。
で、ここまで書けましたらみぎしたのCreateボタンをクリーックします。
すると、なんか、こんな感じでですね、ソースがすでにある!状態になっております。
この状態で実行してもうまく行くです。
右下のボタンをタップするとカウントしてくれるアプリです。
はい。まずここまでできたのでヨシ。
ではHome_Widgetを追加できるようにしていきましょう。画面の下にTerminalってあるんですが、
こちらをクリックしましてコマンドを打ちます。
flutter pub add home_widget
これですね、home_widgetを使いますよーって宣言してると思ってもらえばよいです。
それをしますと、Flutterで「お、それ作るならこいつら必要やから入れとくわー」っていろいろ追加してくれます。
はい。これで準備OKかな?多分これからいろいろバージョンが―って怒られるからそのあたりを記事にしたい。
ちなみに、この状態で、アプリを再実行しても問題なく動くっポイです。
で、ここからの実装にはドキュメントを眺めながらやろうと思っております。(´・ω・`)
こいつなんですけどね、
iOS とAndroid(jetpack)とAndroid(XML)のやりかたがありまして、、、ちょっと混乱しているなう。
まぁ、一個ずつ頑張る。
じゃぁいっこめ
こちらGradleファイルに依存関係として追加するとありますね。
最近Gradleファイルの記述方法が変わったので、これをどこに書くのかがちょっとわからんかったんですわ。で、かつ。
androidフォルダがあると思うんです。その中のファイルを開くと右上に
「Open for Editing in Android Studio」って出るんですね。
よくわかっていないんですが、Flutterとして開いた場合と、Android(JavaやKotlin)で開いた場合でちょっとAndroidStudioが違う動きをするみたいです。
なので、JavaやKotlinなどを更新する用のAndroidStudioを使用したいときはこの「Open for Editing in Android Studio」をクリックするとそのJava・Kotlinを更新するためのウィンドウが開くんですが、これが開かないw
(なんかトラブルとしてあるようですが、根本的な解決方法が見つからないw)
一応回避策としてFile->openから、
プロジェクト内にある「Android」を指定して開くとjavaやKotlinをメンテする用のウィンドウが開くようです。
(プロジェクト名はお試しだから適当。作成日をいれておるw)
で、開きます。
で、えーっとどうしたんだっけな、、implementation(綴りがちがうかなこれ
したいから、、
File->ProjectStructureをクリックしまして、えーっと、Dependenciesを選択します。
で、アプリのGradleファイルーって言っていたので、
に追加しましょう。
+ボタンをタップしまする。
文言入れて(androidx.glanceくらいでええやろ)Searchをクリックします。
検索結果からInplementationしたいやつを選択。Versionsは、、1.0.0でいいかな。
(文字が入ってるのはβ版とか、動きがまだちゃんとしてない奴と思ってる。。)
ここまで入れたらOKボタンをクリック。
で、OKボタンをクリックします。
さっきの手順が終わっている、、、ハズです。。。。
(ソースコード上だと、app>build.gradleの中にimplementationが追加されているはず。。)
じゃぁつぎぃー
あ、公式ドキュメント、本来は英語ですが、ブラウザに翻訳してもらっております。
さ、ウェジット設定を作成するということなので、
えっと、xmlっていうフォルダにウィジット設定を追加とあるので、フォルダを追加しますか。
で?この中にウィジット設定を入れると、、
あと、マニフェストに設定を追加すると。。
字が小さくなってきちゃったなこれ。
うんとねーー、基本は公式ドキュメント通りですが、meta-dataのresourceの中身はさっきxmlファイル?ディレクトリ内に格納したレイアウトデータにつけた名前を記述します。多分。
はいつぎつぎ
えーっと、、こいつらを記述します。
まぁ、MainActivity.ktに書けばいけるやろ(雑
なんでやろ。。。赤字が消えんw
あ、できた。
currentState()の赤字は「import androidx.glance.currentState」を追加すると消えますね。
で、HomeWidgetGlanceStateの赤字は、、どれだっけw
あ、これか
「import HomeWidgetGlanceStateDefinition」を追加するとよさげです。
Columnは私が書き方知らなかっただけだよ(´・ω・`)
(Kotlin関連の記憶が古くてあかんw)
さて、赤字も消えたので、次。
これを書けばいいんでしょうが、nameはどこから来るんだよ!みたいな気持ちになるわし。
まぁ書きましょう。おそらくflutter側の記述と思われるので、mainのinitあたりに書きゃいけんだろ(雑
書いたので実行
E/flutter ( 4235): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: MissingPluginException(No implementation found for method updateWidget on channel home_widget)
E/flutter ( 4235): #0 MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:332:7)
はいエラーwなんや、MissingPluginExceptionだから、プラグインが見つからんぞなもしですな。こりゃ。えー?どうすっかなぁ、、
(´・ω・`)<確認なう
あーーちょいいじいじしておりましたら
ちょっとねぇ、赤字がいっぱい出てきてしまいました。。
一部抜粋よっとな。
e: Incompatible classes were found in dependencies. Remove them from the classpath or use '-Xskip-metadata-version-check' to suppress errors
e: C:/Users/xxxxx/x/.gradle/caches/transforms-3/05dcfd3fbd26290e509497c7e427fd37/transformed/jetified-kotlin-stdlib-common-1.9.0.jar!/META-INF/kotlin-stdlib-common.kotlin_module: Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.9.0, expected version is 1.7.1.
e: C:/Users/xxxxx/.gradle/caches/transforms-3/ba1df8cdc5eaee1ccf3a090956d8fbab/transformed/jetified-kotlin-stdlib-1.9.0.jar!/META-INF/kotlin-stdlib-jdk7.kotlin_module: Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.9.0, expected version is 1.7.1.
e: C:/Users/xxxxx/.gradle/caches/transforms-3/ba1df8cdc5eaee1ccf3a090956d8fbab/transformed/jetified-kotlin-stdlib-1.9.0.jar!/META-INF/kotlin-stdlib-jdk8.kotlin_module: Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.9.0, expected version is 1.7.1.
e: C:/Users/xxxxx/.gradle/caches/transforms-3/ba1df8cdc5eaee1ccf3a090956d8fbab/transformed/jetified-kotlin-stdlib-1.9.0.jar!/META-INF/kotlin-stdlib.kotlin_module: Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.9.0, expected version is 1.7.1.
要は現状のKotlinバージョンでは動かないよって言われております。
「1.7.1」じゃぁ、動かねぇ!「1.9.0」以上にしろ!
ってことでしょう(多分。
えっと、ここだ
settings.gradleのkotlinのバージョンを変更しませう。
一応バージョン確認して―の
今の最新が2.0.0なので2.0.0でやってみよ
で、再実行するなう
* What went wrong:
Execution failed for task ':app:mergeExtDexDebug'.
> Could not resolve all files for configuration ':app:debugRuntimeClasspath'.
> Failed to transform kotlin-stdlib-2.0.0.jar (org.jetbrains.kotlin:kotlin-stdlib:2.0.0) to match attributes {artifactType=android-dex, asm-transformed-variant=NONE, dexing-enable-desugaring=true, dexing-enable-jacoco-instrumentation=false, dexing-is-debuggable=true, dexing-min-sdk=21, org.gradle.category=library, org.gradle.jvm.environment=standard-jvm, org.gradle.libraryelements=jar, org.gradle.status=release, org.gradle.usage=java-runtime, org.jetbrains.kotlin.platform.type=jvm}.
> Execution failed for DexingWithClasspathTransform: C:\Users\xxxxx\.gradle\caches\transforms-3\c930802426878496aca18f851d9cdeb4\transformed\jetified-kotlin-stdlib-2.0.0.jar.
> Error while dexing.
はいエラー
なんかGradleが対応してないよ!って言われている様子。
うーん、、どうしたっけなぁ、、あ!
これはですね、AndroidStudio側でGradle古いよーっていうアナウンスが入っているんですね。
これでアップデートすりゃいいや。
(あ、出てこない人はAndroidStudio開きなおすと出たりするよ☆)
Start AGP Upgrade Assistantをクリックしますとこのような画面が表示されます。
このままRun Selected Step を押せば自動で更新してくれるはずです。
…気になるのでshow Usagesを押してみますポチ
主な変更内容としてはこれですね。
一か所だと思っていたのに複数ありましたわ、、あぶねぇ
じゃぁ、これで更新します。
~~Builb待ちなう~~
お、おわっっっ。。。
むぅん、うまく行かねぇかなぁ、まぁ黄色だからいけるかな(無視
まぁ再実行してみるじゃん?
* What went wrong:
Execution failed for task ':app:compileDebugKotlin'.
> Inconsistent JVM-target compatibility detected for tasks 'compileDebugJavaWithJavac' (1.8) and 'compileDebugKotlin' (17).
エラー再び、、
うんと、Kotlinが使用しようとしているJavaのバージョンと指定しているバージョンが異なるって話のようです。(まんどくせ
えーっと?file->Settingsの中、OtherSettings->KotlinCompilerから変更ができそうな気配。。変更しますかね(17でいいのかな?)
Buildを再実施すると、、
いけるかなぁ、再実行!
・・同じエラーが出ました。。。。
Javaのバージョンを上げました、、1.8→17
はぁ、怖えw
はい実行、、
※迷走終了※
できたやり方まとめ
唐突な区切り線w
(こんななげぇやつ読むやついねぇよなw
何が起きたかありのままを説明すると実行→エラーの繰り返しを半日繰り返しておりましたとさ。
結論から言うとめちゃくちゃ苦戦してどうにかなったんですが、、、
エラー解消にいろいろやりすぎて何をすればいいのかを説明できなくなったわし。
ちょっと最初からやり直す。
(大丈夫!今度はちゃんとできたやつがあるから!)
ちょっと箇条書きにするお
・Flutter : home_widgetの追加
・android:Gradle Pluginのバージョンアップ(8.4.1にする)
※Upgrade Assistentを利用しました。
・android:settings.gradle(project Settings)の修正
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version '8.4.1' apply false
id "org.jetbrains.kotlin.android" version "1.7.10" apply false
}
を
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version '8.4.1' apply false
id "org.jetbrains.kotlin.android" version "1.9.24" apply false
}
にする
・android:build.gradle(app)を修正
~省略~
android {
namespace = "com.example.test0529"
compileSdk = flutter.compileSdkVersion
ndkVersion = flutter.ndkVersion
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
~省略~
を
android {
namespace = "com.example.test0529"
compileSdk = flutter.compileSdkVersion
ndkVersion = "26.1.10909125"
buildFeatures{
compose true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.5.14"
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
一番下のdependenciesにはこれ。
dependencies {
implementation 'androidx.glance:glance-appwidget:1.0.0'
}
で!ここからです。
名前がごっちゃりして私が混乱しているだけです。。が!ここから大事よ!
・xmlディレクトリにファイルを作る
まずはxmlディレクトリにファイルを作りましょう。中身はこれですね。
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialLayout="@layout/glance_default_loading_layout"
android:minHeight="40dp"
android:minWidth="40dp"
android:resizeMode="horizontal|vertical"
android:updatePeriodMillis="100000">
</appwidget-provider>
ここで大事なこと「今作ったファイル名」
おっけ?
つぎ!
・マニフェストの記述!(AndroidManifest)
<receiver android:name=".HomeWidgetGlanceReceiver"
android:label="てすとだよ"
android:exported="true">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/home_widget"/>
</receiver>
<activity~~~~~
ここで大事なこと!
「receiverのandroid:name」
これは後で使うからな!ちゃんと覚えといてな!
「meta-dataのresource」
ここはxmlディレクトリに作成したファイル名を書くよ!
・・・おっけ?
つぎ!
・ソースを書くよ!(MainActivity.ktに書いたよ!)
class HomeWidgetGlanceReceiver : HomeWidgetGlanceWidgetReceiver<HomeWidget>() {
override val glanceAppWidget = HomeWidget()
}
class HomeWidget :GlanceAppWidget(){
override val stateDefinition = HomeWidgetGlanceStateDefinition()
override suspend fun provideGlance(context: Context, id: GlanceId) {
provideContent {
GlanceContent(context, currentState())
}
}
@Composable
private fun GlanceContent(context: Context, currentState:HomeWidgetGlanceState){
Box {
Column(
modifier = GlanceModifier.fillMaxSize(),
verticalAlignment = Alignment.Vertical.CenterVertically,
horizontalAlignment = Alignment.Horizontal.CenterHorizontally
) {
Text(
"てすとだよ",
style = TextStyle(fontSize = 14.sp, textAlign = TextAlign.Center)
)
}
}
}
}
大事なこと
「HomeWidgetGlanceWidgetReceiverを付けている方のクラス名」
この名前でFlutterからのアップデートをかけます。
あと、さっき書いたマニフェストのandroid:nameの部分もこれを入れます!
おし、、最後はFlutter側です。。
・Flutter側にアップデート処理追加
HomeWidget.updateWidget(
name: 'HomeWidgetGlanceReceiver',
androidName: 'HomeWidgetGlanceReceiver'
);
こいつを書くとウィジットが更新されるらしい、、
nameはさっき大事!って言っていた「HomeWidgetGlanceWidgetReceiver」がついているクラスのクラス名でふ。。。
こ、、、これでいけるはず!!!
がんばったよーん!
余談
今回、xmlのやり方だと割と簡単にできたんです。。。
できたんですが、、どうやらレイアウトの変更なんかが動的にできなさそうだなというのがありまして、jetpackならできるだろという謎の信頼のもと、こちらを通したかった次第。
jetpackの困った点はバージョンに厳しいっていうところかなぁと。。
前回も作成しながら思ったなぁと回想なう
(動くようにバージョンそろえているのにandroidstudioちゃんがね、「新しいバージョンあるよ?」って勧めてくるの。。うっかり更新しちゃった日には、、、っていうね。。)
ふふふ、、迷走っぷりが文字数に表れておりますね。
ではではおつおつ。。
この記事が気に入ったらサポートをしてみませんか?