2019年2月25日月曜日

Raspberry Pi 3b+でLineageOS 15.1を動かす

前回、Raspberry Pi 3b+でLineageOS 14.1 (Android 7.1.2)をインストールしてみましたが、Scratch Jrのマウスクリックができずに挫折してしまいました。今回、LineageOS 15.1(Android 8.1.0)を見つけたので、再度チャレンジしてみました。

ステップ1:LineageOS 15.1インストール


インストールそのものは簡単です。システムイメージをダウンロードして、マイクロSDカードに書き込んで、Raspberry Piで起動するだけです。

LineageOSの嬉しいところは、F5の長押しで、電源OFFかリブートのメニューが出て安全に電源を切ることが出来ることです。
スマフォでしたら電源ボタン長押しで電源を切ることができますが、Raspberry Piには電源ボタンがないので、電源そのものをOFFにするしかないことです。この場合、SDカードへの書き込み中だとシステムが壊れる可能性もあるので、安全を考えるならshutdownをしてから電源を切りたい所です。
rootが取れれば電源OFF用アプリをインストールできますが、現在Raspberry Piで動いているAndroid 7.1.1ではrootを取るのことは出来ませんが、adb shellがroot権限で動くようなので、別端末から「adb shell setprop sys.powerctl shutdown」で電源を切るようにしています。

ステップ2:Google Play Storeのインストール


こちらもホームページに導入手順が書いてありますので、そのまま実行すればGoogle Play Storeが使えるようになります。
事前準備としては
  • Settings -> Developer options -> Root accessでadbとappにRoot権限を与える
  • Settings -> Developer options -> Local terminalでターミナルを使えるようにする
  • ブラウザを立ち上げて必要なファイルをRaspberry Piにダウンロード
ここで、ともかくやたらと設定が落ちます。この時点で、使い物にならないと諦めてしまいそうになります。コツとしてはスクロールはマウスで行わずに、上下矢印(↑↓)を使って、ゆっくりと行うことがポイントです。どうやらListViewで画面スクロールをする時に処理が追いつかずに落ちている感じです。↓しては待って、また↓して待ってと、ひたすら我慢で使いこなしてください。

準備ができたらTWRPへブートし直します。これもFAQに方法が書かれていますが、ターミナを立ち上げて
su
rpi3-recovery.sh
を叩いて、再起動します。




TWRPのメニュー画面です。
まずは、ダウンロードしておいたGappsをインストールします。
「Install」ボタンを押して






Downloadをクリックすると









ファイルがあるのを確認してクリック後「Install Image」ボタンを押します。









「Swipe to confirm Flash」を右にスワイプしてインストール開始です。









インストールが終わったら、
「Wipe cache/dalvik」を押すと










右にスワイプしてキャッシュのクリアを行います。









キャッシュのクリアが終わったら、続けてFactory resetを行うので「Back」でTOPメニューに戻ります。







TOPメニューで「Wipe」ボタンをクリックすると、この画面が表示されるのでスワイプしてFactory resetを行います。







Factory resetが完了したら、Androidが起動するように起動時設定を変更するために「Back」ボタンでTOPメニューへ戻ります。






TOPメニューで「Mount」ボタンを押して、Systemのマウントを行います。








OKでマウントします。










TOPメニューから「Advanced」を選択して、「Terminal」を開きます。









「rpi3-recovery.sh boot」で起動設定を変更して、TOPメニューへ戻ります。








最後にTOPメニューから「Reboot」を選択して、「System」を再起動します。










ステップ3:Scratch Jrのインストール


再起動後は、Play Storeがインストールされているので、ログインすることでScratch Jrのインストールが可能です。

ただ起動してみると、やはりマウスクリックが効きません。Android 7.1.1では問題なく動いているのでアプリ側の問題ではなさそうです。

そこで
add connect [Raspberry PiのIPアドレス] ・・・adbで接続
adb shell wm size                    ・・・画面サイズの表示
adb shell input mouse tap [x] [y]    ・・・マウスクリックのシミュレーション
で、概ねの座標からボタンをクリックさせると、問題なく動きました。でも、物理的なマウスでクリックしても動かないんですね。

ということで、システム全体の動作ももっさりしていますし、マウスクリック問題があるので、やはり使い物にはなりませんでした。Raspberry Pi 4が出て、処理能力がさらにアップすれば使えるようになるかな?







2019年2月22日金曜日

EclipceからAndroidStudioへのお引っ越し ーその2ー

Eclipce側での修正はひと段落したので、いよいよAndroidStudioへの移行を行いたいます。
AndroidStudio側でEclipceのワークスペースをインポートする機能があるので、簡単にできるかと思いましたが、3箇所ほどつまづきましたのでメモを残しておきます。

その1:ビルドができない。


インポートそのものは本家の解説を見て問題なくできたのですが、ビルドをするとエラーが出てしまいます。
ERROR: Could not find com.android.tools.build:gradle:3.3.1.
Searched in the following locations:
  - https://jcenter.bintray.com/com/android/tools/build/gradle/3.3.1/gradle-3.3.1.pom
  - https://jcenter.bintray.com/com/android/tools/build/gradle/3.3.1/gradle-3.3.1.jar
Required by:
    project :
Add Google Maven repository and sync project
Open File
Enable embedded Maven repository and sync project
色々と検索をして見ましたが、これはというサイトが見つかりませんでした。いずれにしろGradle関連の設定では無いかと検討をつけてこちらのサイトを参考に、プロジェクト全体のbuild.gradleにgoogle()を追加すれば良いことがわかりました。
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
    repositories {
        jcenter()
        google() ・・・・・この行を追加
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.3.1'
    }
}

allprojects {
    repositories {
        jcenter()
        google() ・・・・・この行を追加
    }
}

新規にプロジェクトを作成する場合は、初めから追加されているようですがEclipceからインポートした場合には記述されなかったようです。

これに関連して、自動生成された各モジュールのbuild.gradleのdependenciesですが、compileで生成されますがcompileが非推奨となったとのことで、implementationとapiに変更しておいた方が良いようです。
私のアプリでは「アプリケーションモジュール→ライブラリモジュール→Android supportライブラリ」という依存関係があるので
アプリケーションモジュール
 dependencies {
     implementation project(':myLib')
 }

myLibモジュール
 dependencies {
     api project(':lvl')
     api 'com.android.support:appcompat-v7:28.0.0'
     api 'com.android.support:preference-v7:28.0.0'
     api 'com.android.support:recyclerview-v7:28.0.0'
 }

lvlモジュール
 dependenciesは無し
lvlモジュールのメソッドで一部アプリケーションモジュールで利用するものがありますが、myLibでapi宣言しているのでアプリケーションモジュールではlvlを指定する必要はありません。

その2:実行ができない!


無事にビルドも完了したので、さて実行をと思ったところで問題発生。
実行の構成を行おうとメニューから実行>実行の構成>TemplatesからAndroid Appを選択しましたが、モジュールが空っぽで選択することができません。

ソースも特にいじっていなかったので、一旦モジュールを削除して再度インポートし直したところ、実行の構成でモジュールの選択ができるようになりました。

1つのプロジェクトにアプリケーションと共通ライブラリがあったので、まずはライブラリからインポートしたので原因でしょうか?

後でわかった事として、各モジュールのbuild.gradleの先頭で各モジュールの属性を宣言しているようです。Android developerではビルドの設定>ビルド設定ファイル(build.gradle ファイル)>モジュール レベルのビルドファイルにもそれらしい説明はなく詳細はAndroid Plugin DSL Reference(英語)を見ろと突き放しています。結局、こちらに先頭行のプラグインでアプリケーションとライブラリを切り替えている事が説明されていました。ただ、ここは日本語に翻訳されていますが、バージョンが古いのでしょう依存関係の説明でcompileが使用されています。

その3:":" is not a valid resource name


やっと実行に漕ぎ着けましたが、実行してみると上記のようエラーが出てしまいます。

同じようなエラーはネット上でもいくつか見受けましたが、何れにしてもリソース関係のようです。string.xml又はlayout.xmlあたりでnameに":"を使っていないかということをヒントに、検索してみるとlayout.xml内でname="@id/android:empty"と指定しているところがありました。これはListActivityでデータが1件も無かった場合、自動的にこのidを持っているTextViewを表示してくれるという機能を使うためなんですが、どうやらこの指定方法が古かったようです。最近では@android:id/emptyと指定するようです。

ここでも浦島太郎になっていました(笑)

その他


Javaには長いことお世話になってきましたが、Oracleは(サポート≒セキュリティパッチ)有償化に踏み切ったようで、その話題で盛り上がっている界隈もあるようです。

その昔、SunがOracleに買収された時にJavaが有償化されるのではという危惧をしましたが、ついに来たかという感想です。そうなると次は「MySqlよお前もか!」にならなければいいんですが。(MySqlは現在も有償版とGPL版がありますが、今後はサポートを有償化という流れで、Oracleがあまたある利用サイトからお金を徴収しようと考えるかですね)

まあ、使う側としては、お金のある企業さんはサポート契約を結ぶんでしょうし、中小企業ではセキュリティリスクを我慢して(というか、サポート要員もいないので納品されたシステムをそのまま運用しているので、セキュリティもへったくれも無い)今のまま何もしないという流れではないか、と予想しています。(Oracle側もプライバシーマクを取得しているような企業や、セキュリティに責任を持つ企業さんは有償化わかってるよね、的な発言しているようですしね。)

Androidの開発でもJavaを使っていますが、Androidは2016年にはJavaのライブラリをOpenJDKへ切り替えていますので、直接の影響は出ないでしょう。まあ、GoogleとOracleの間ではJavaに関して訴訟が2010年ごろからあったので、Googleとしてはこの事態はすでに予想して対応していたんでしょう。

この話題と関連してかKotlinという言語が話題に上がってきているようです。すでにAndroid関連の話題でもKotlinを使ったページもだいぶ出てきているようです。

ということで、今年は今あるアプリをSwiftとKotlinで書き直してみたいと思います。

2019年2月11日月曜日

Raspberry Pi 3B+でScratch Jrを動かす

2020年から小学校でプログラミング教育を行うということで教育関係ではそれなりに混乱されているようです。そんな中でバズワードとしてScratchが浮上し、Scratchの入門編としてScratch Jrもあちこちで聞くようになってきました。
ScratchについてはRaspberry Piで動くことは実証済みですが、Scratch Jrは動作環境がiOSまたはAndroidということでRaspberry Piでは動かすことはできません。

とは言えRaspberry PiでAndroid OSを動かしてみた方もたくさんいますし、ビジネスとして展開している会社もあるようです。そこで、我が家のRaspberry Pi 3B+にAndroidを導入してその上でScratch Jrを動かしてみたいと思います。

ステップ1:Raspberry Pi で動くAndroid


まずはRaspberry PiでAndroid OSを動かしている例を検索してみると。
といったところが出てきます。

結論から言うと、現在は一番上のページを参考にしてRaspberry Pi 3B+にAndroid7.1.1を導入してScratch Jrを動かしています。

☆ emteria.OS
企業がビジネスとして公開しているので無償版といえ安定して動いてくれました。ただ、マーケットアプリがF-DroidということでScratch Jrは登録されていませんでした。また、個人使用なら無償ですが、ビジネスで使用するとなるとライセンスが必要なのも注意点でしょうか。Play Storeのインストールは試してみませんでしたが、sshサーバが無償版では使えなかったりと自由にカスタマイズするのは難しそうです。

☆LineageOS 14.1
WikipediaによるとCyanogen Inc.が開発していたCyanogenModというAndroidをカスタマイズしたOSが元になっているそうです。
OSをインストールした状態ではPlay Storeはインストールされいませんが、こちらの方法でインストールは可能なのでScratch Jrのインストールも問題なくできました。
ただ、残念なのはScratch Jrを起動したところ初回の利用場所設定画面でマウスクリックができずに先に進めず、Scratch Jr利用することはできませんでした。

☆Android 7.0 Nougat on Raspberry Pi 3
インストールは問題ありませんでしたが、起動後に設定画面を開こうとしたところ設定が終了してしました。

ステップ2:Raspberry Pi3にScratch Jrをインストール


先ほどの参考ページにもありますが、元ページはこちらになります。ほぼ元ページの作業手順で問題なくPlay Storeのインストールまで出来ました。

参考ページでは有線接続の時のIPアドレスの確認方法がわからないとありますが、Android起動後、設定>端末情報>端末の状態で確認できますし、あらかじめRaspberry Pi 3をrasbianで立ち上げてIPアドレスを確認しておいても良いと思います。

今回、時間がかかったのが画面表示のところでした。今回は古いSharp LL-173Cというディスプレイを使っていましたが初めは真っ黒で何も表示してくれませんでした。
この場合、AndroidをインストールしたSDカード内の/boot/config.txtを編集するのですが、Androidを起動した状態では編集できない(そもそも画面が真っ黒です!)ので、Windows等で編集する必要があります。

Sharp LL-173C、DELL E2014H、Panasonic TH-32LX70(液晶テレビ)で画面表示できるようにしましたが、その時の設定を以下に示しておきますので、画面が真っ黒になった時には参考にしてください。直感的には最近のモニタであればデフォルト設定で問題なく表示されるのではないかと思います。
# DELL E2014H
#hdmi_group=2
#hdmi_mode=87
#hdmi_cvt=1600 900 60 6 0 0 0
#disable_overscan=1

# Panasonic TH-32LX70 4(720p),16(1080p)
#hdmi_group=1
#hdmi_mode=16
#disable_overscan=1

# Sharp LL-173C(OK=36,17,8)
hdmi_group=2
hdmi_mode=8
disable_overscan=1

Androidが起動直後は、言語設定が英語になっているので、設定>言語と入力>言語>言語の追加で日本語を追加して、日本語をドラッグして一番上に持って行きます。これで設定の表示なども日本語に切り替わります。また、設定>日付と時刻>タムゾーンで「日本標準時」を選択して日本時間にしておきます。

次にユーザ登録をしてからPlay Storeのインストールをしましょう。

ユーザ登録は設定>アカウント>アカウントを追加>Googleで、ユーザの追加をします。
私はAndroidが起動後すぐにPlay Storeのインストールをしたので、Play Storeインストールでユーザ登録が要求されましたが、うまく既存ユーザでの登録ができませんでした。

あとはScratch JrをPlay StoreからインストールすればRaspberry Pi 3でScratch Jrが利用できるようになります。

ステップ3:マウスポインターの解消


Raspberry PiにAndroidを導入したサイトをみてもマウスポインターが化けているとの報告(導入動画でもマウスがモヤモヤしています)がされています。Androidでは標準でマウスカーソルの表示(そもそもマウス全般)に対応して無いのが原因かと思いますが、以下の方法で解消できましたので、モヤモヤカーソルを解消した方は設定して見て下さい。
  • 設定>ユーザ補助>大きなマウスポインタをONに設定
ちょっと大袈裟なくらい大きくなってしまいますが、画面サイズからすればまあ許容範囲かなということで(笑)

ステップ4:Scratch Jrでの日本語入力


Scratch Jrは問題なく利用できたのですが、日本語の入力でちょっと問題がありました。

標準のJapanese IMEでは日本語キーボードのレイアウトがサポートされてませんし、入力ができたり、できなかったり、長い文章を入力するとおかしくなったりと不安定でした。そこで日本語入力をGoogle日本語入力に変更して、設定を一部見直したところ安定したようです。
  • Play Storeで「Google日本語入力」を検索して、インストールします。
  • 設定>言語と入力>仮想キーボード>キーボードを管理で、Google日本語入力をON、Japanese IMEをOFFに設定
  • 設定>言語と入力>仮想キーボード>Google日本語入力>入力>ハードウエアキーボードのキーマッピングで「日本語109A」を選択
  • 設定>言語と入力>仮想キーボード>Google日本語入力>入力で変換オプションを全てOFFに設定(CPU負荷を軽減するためです)
  • 設定>言語と入力>物理キーボードで「仮想キーボードの表示」をOFFに設定

最後に:使い物になるか?


今のところScratch Jrの操作感として、速度的には我慢どころかなという印象です。日本語入力も余り早いキータッチには追随できませんが、CPUの能力を考えれば致し方ないかなと思います。

音の出力は外部スピーカーを付けるか、テレビをモニタ代わりにすれば問題はありませんが、その場合はconfig.txtの設定が必要になるかもしれません。カメラとマイクの利用もUSB接続という方法もありますが、プログラムの勉強用なら特に無くても問題はないかと考えています。

今回はScratch Jrを動かすことが目的でしたが、他の学習用アプリもいくつかインストールして使ってみました。結果は、全てのアプリが使い物になりませんでした。起動しないアプリ、起動してもマウスクリックを受け付けなくて(全く受け付けない、画面の一部で受け付けないの2パターンがありました)操作ができないものなど、普通に使う範囲で問題が発生しました。

ちなみに、私が公開しているアプリもインストールしてみましたが、アプリそのものは動いているようですが、画面が真っ黒になりやはり使えませんでした。動作はしているようなのでテーマ絡みで画面が真っ黒になっているのではないかと想像しています。現在、Android 8.0対応を進めているので、落ち着いたら調べてみたいと思います。

そういった意味でScratch Jrは特に問題なく動いているのはすごいなという感想でした。

2019年2月9日土曜日

EclipceからAndroidStudioへのお引っ越し ーその1ー

Google Play ストアにアプリを公開していますが、いつの間にかターゲット SDK を API レベル 26 以上(Android 8.0 Oreo)に設定することが求めらていました。(通知は来ていたのでしょうが、無視していました)2018年秋のアップデートは問題なかったのですが2018年11月1以降は新規アプリだけでなくアップデートもできなくなっていたんですね。1月になってちょっと修正したのでアップデートしようとしたところで怒られてしまいました(泣)

如何せんAndroid1.6の頃に作ったアプリでターゲット SDKも8(Froyo)という、とんでもアプリでした。仕方がないので急遽3倍以上のジャンプアップを目指して作業を開始しました。とはいえ、最近はAndroidの本格的な開発からは遠ざかっていた(スマフォもいつの間にかiPhoneになっています)ので最新情報にも疎く、だいぶあたふたとしております。

多くのデベロッパーの方はすでに最新のバージョンにもバリバリ対応していると思いますので、全く役に立たない情報ではありますが、作業中つまづいたところをドタバタ奮戦記として残しておきたいと思います。

さて、ターゲット SDK のAPI レベルを上げると当時に、開発環境もEclipceがサポート対象外となっているのでAndroidStudioへのお引っ越しが必要となっています。両方をいっぺんに行うのは大変なので、まずはAPI レベル を現在のEclipce環境で上げられるところまでアップしてからAndroidStudioへ引っ越したいと思います。

その1:API レベル8(Froyo)からレベル16(Jelly Bean)へ


ここでもステップを踏んで作業を進めていきたいと思います。本家でも「Google Play の対象 API レベルの要件を満たす」として説明されていますが、一番初めに「動作の変更点」があったのがレベル16のようなのでまずはここを目指します。
作業はビルドターゲットを変えてリビルドするだけで済みましたが、実行してみると「You cannot combine custom titles with other title features」なるメッセージで実行できませんでした。早速Googleさんにお伺いをたてると、タイトルをカスタマイズしている場合はテーマの設定が必要なようです。そういえばテーマなんて機能がだいぶ前に追加されていましたね。
AndroidManifest.xmlを編集してテーマを以下のように設定しところ問題なく表示されるようになりました。でも、これが後で発覚する別の問題を引き起こしていました。
<application ... android:theme="@android:style/Theme.NoTitleBar">
<activity ... android:theme="@android:style/Theme">

その2:support v7の導入


AndroidにFragmentが導入されたのはAndroid 3.0でしたが、当時Preferenceがまだサポートされていなかったと思います。そこでPreferenceFragment/PreferenceManagerCompatを使って対応していました。そのまま使っていましたが、現在ではOSで対応していますし、サポートライブラリでも使えるのでsupport v7 preferenceを導入して切り替えることにしました。
PreferenceFragmentはPreferenceFragmentCompatへPreferenceManagerCompatはPreferenceManagerにクラス名を変更することでその他にソース修正は必要ありません。ただ、support v7 preferenceはリソースなども含んでいるので、Eclipceへ取り込む必要があります。ここで問題が発生です。
取り込んだリソースの内res/values/attr.xml内でエラーが発生してしまいます。フォーマットが未定義だというので、以下のようにformat指定を追加することでエラーは出なくなりました。
<declare-styleable name="Preference">
 <attr name="icon" format="reference">
 <attr name="title" format="reference">
 <attr name="layout" format="reference">
さて、エラーがなくなって実行したところで、はたと気がついたのが設定を開くためのメニューが出ない。最近の人は知らないかの知れませんが、昔はメニューの表示は画面下部のホームボタンとか表示されているとこにあったんですね。どうやら最近は画面上部のツールバー?(タイトルバー改めアクションバーが改名してツールバー?なんて呼ぶのが正式なんでしょうか?)に表示されるようです。そうです、Theme.NoTitleBarでタイトルバーを消していたんですね。
<style name="Theme.Light_actionBar" parent="@android:style/Theme.Light">
 <item name="android:icon">@android:color/transparent</item>
 <item name="android:windowNoTitle">false</item>
 <item name="android:windowActionBar">true</item>
</style>
カスタムテーマを作って無事にメニューが表示されて、やっと設定画面を開くと、今度は実行時エラーが出ます。実はsupport  v7 recyclerviewを使っていたんですね。と言うことで、こちらもインポートして無事に設定画面も動くようになりました。
ところが、ここでカスタムPreference(ボタン)が動きません。色々と探っていると、今まではPreference全体のレイアウトを作ってカスタマイズしていたんですが、どうやらwidget部分だけをカスタマイズできるようです。カスタマイズが簡単になっていたんですね。
参考サイト:Preference(4)-Preferenceのカスタマイズ 

 その3:LVL (License Verification Library)バージョンアップ


LVLとはGoogle Play で有料アプリを配布する際に組み込んでおきたい、ライセンス認証ライブラリのことです。とは言え、ハッキングツールも公開されていたりとあまり役に立たない機能ではありますが、気休めで導入してありました。ところが、APIレベルを23(Marshmallow)に上げたところ、コンパイルでエラーが発生しました。どうやらAndroid6.0からApache HTTP クライアントが削除されたのが原因のようです。最新のソースがGithubにあったのでダウンロードして差し替えました。

オプションメニューがアクションバーに移動したことに伴い、アクションバーへの表示ができない画面が1つだけありましたが、そこはコンテキストメニューに切り替えることでクリアしました。こちらはほぼメソッド名の変更だけで完了です。

その4:テーマでハマった件


最後に残ったのがAbout画面として使っていたAlertDialogです。表示はされるのですが、背景色や文字色がダーク系になってしまい、文字が見づらいのです。テーマで設定できるかと思いましたが、なかなか思うように設定できませんでした。
結論から言うと、support v7 appcompatを導入&カスタムスタイル作成で思うような設定が可能でした。ただし、結論に達するまで数日を要し今回の作業で一番ハマったとことです。キモはカスタムスタイルを作成するときにTextAppearance.AppCompatからの派生スタイルを継承することでした。
テーマをカスタマイズするにはTheme.AppCompatを継承するように、widgetのスタイルを独自に変更しつつテーマを反映させるにはAppCompatから派生したスタイルを継承しておくことが必要なようです。
<style name="Dialog_TextSmall" parent="TextAppearance.AppCompat.Caption">
 <item name="android:textColor">?android:colorPrimary</item>
</style>
スタイルを定義して、レイアウトで指定します。
<TextView android:text="@string/about_copyright"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:layout_marginLeft="15dip"
 android:layout_marginRight="15dip"
 style="@style/Dialog_TextSmall"
/>
この作業の中で、その2で修正したdeclare-styleableですが、今度は二重定義でエラーになりました。どうやらsupport v7 appcompat側のリソースで定義されているようです。support v7 appcompatは必須という位置付けなんでしょうかね。その2での修正を削除してクリアです。

最後に


これで終わりではなく、次にAndroidStudioへの移行と、API レベル 26 への対応が必要ですが、作業が無事に終了したら別に報告したいと思います。

いづれにしろ、FragmentやらThemeやらToolBarやら浦島太郎となっている状況なので、もう一度真面目に勉強し直してアプリも1から書き直す必要がありそうです。

Raspberry Pi ZeroでHeadphonesが無くなった

最近こんなの Adeept Robotic Arm Kit for Arduino や こんなの 「Petoi Bittle」(ペトイ・ビトル) を購入して遊んでいました。 両方共にArduino互換ボードでサーボモーターを駆動する物ですが基本的なプログラムは提供されるのでとりあ...