Kotlinでクラスのnameを取得するには

Android開発の際、ログを出す時やfragmentのtagによくクラス名を使う。
kotlinでも同じようにしようと思ったのだけど、下記のようにすると

MainActivity::javaClass.name

単に「javaClass」とログに出てきて悲しい感じに・・

MainActivity::class.java.name

とすると期待した結果になった。
下の書き方だと、最終的にClass.javaのgetNameにたどり着く。

WebViewでリダイレクトかどうかを判定する

判定する。

リダイレクトの際にもshouldoverrideurlloadingの中に入ってくるので、
そこは無視したい。

WebView.HitTestResultのUNKNOWN_TYPEの場合はリダイレクトだとする方法で当初は上手くいって見えた。

しかし、リンクテキストをタップした時なんかにもたまにこれが来る時があった。
SRC_ANCHOR_TYPEが通常来るが、たまにUNKNOWN_TYPEで入ってくるという具合。

そのためこの方法は使えず。

色々と調べた結果、リダイレクトの時はonPageFinishedより先にshouldoverrideurlloadingに
入ってくることが判明。

stackoverflow.com

ここで教えてくれている通りにフラグで管理するようにして解決した。
ありがたい・・。

droidkaigiいってきた

行ってきた

仕事の合間に行ったので対して聞けなかったけれども、結構勉強になりました。
英語のスピーチを試しに聞いてみたけど辛いだけだった。英語勉強しなきゃ()

今回は聞いた内の一つ、「実践アニメーション」のサンプルを読む。

xmlで複雑なアニメーションは聖域になるからやめた方が良い、ってのが一番印象に残ってる。

Androidのアニメーションの基本部分の簡単なサンプルたちはスルーして、
花火してたところを見る。

MarbleAnimationってところかなぁ多分


まずは呼び出し側
MarbleAnimationActivity.java

animatorView = (MarbleView) findViewById(R.id.animatorView);

        animatorView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                animatorView.startCustomAnimation();
            }
        });

ほんとに呼ぶだけって感じ。カスタムのView + ValueAnimator最強って言ってたから、
その通りの作りになってるんだな、って。


というわけで本体
MarbleView.java

private void initParams() {
        maxDistance = getContext().getResources().getDimensionPixelSize(R.dimen.marble_max_distance);
        circleRadius = getContext().getResources().getDimensionPixelSize(R.dimen.marble_max_circle_radius);
    }

Viewの拡張クラスの中でgetContextって出来るんだ・・!(無知)
コンストラクタで必ず渡してるんだから当たり前かぁ

上記の個所は初期値を定義している部分で、すべてのコンストラクタで呼び出していた。
外から渡したりはしないんすねーってちょっと思ったけど、設定値を書き換えろやって話か

// 外の公開しているのはこのメソッドだけみたい
 public void startCustomAnimation() {
        if (isRunning) return;

        isRunning = true; // このフラグを折ってるところが見当たらない
        for (int i = 0; i < animators.length; i++) { // animatorsはValueAnimatorの配列で20個
            createAndStart(i);
        }
    }


20個のValueAnimatorを作成してるみたい。
花火の各点になるのかな?なるんじゃないかな?

private ValueAnimator createAnimator() {
        Random random = new Random();
        ValueAnimator animator = ValueAnimator.ofPropertyValuesHolder(
                PropertyValuesHolder.ofFloat(VELOCITY_X, (random.nextFloat() - 0.5f) * 2),
                PropertyValuesHolder.ofFloat(VELOCITY_Y, (random.nextFloat() - 0.5f) * 2),
                PropertyValuesHolder.ofFloat(PROGRESS, 1.0f));
        animator.setDuration(random.nextInt(MAX_DURATION / 2) + MAX_DURATION / 2);
        animator.setInterpolator(new DecelerateInterpolator()); // 最初速くて減速する。花火だ。
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                invalidate(); // これを使ってonDrawを呼び出している様子
            }
        });
        return animator;
    }

一番知りたかった部分・・・かな?
valueAnimatorで値が変化するとonAnimationUpdateが呼ばれるみたい。
そこでinvalidateすることでonDrawを呼んでいる。

setInterpolatorって何だろうと思って調べたけど、スライドにちゃんと書いてた。

private void drawPhotons(Canvas canvas) {
        for (int i = 0; i < animators.length; i++) {
            float velocityX = (float) animators[i].getAnimatedValue(VELOCITY_X);
            float velocityY = (float) animators[i].getAnimatedValue(VELOCITY_Y);
            float progress = (float) animators[i].getAnimatedValue(PROGRESS);
            paints[i].setAlpha(255 - (int) (255 * progress));
            canvas.drawCircle(maxDistance * velocityX + centerOfX(),
                    maxDistance * velocityY + centerOfY(),
                    circleRadius * progress,
                    paints[i]);
        }
    }


最後、onDraw内で呼んでいるメソッド。
ValueAnimatorで動きを定義して、ここで実際の描画を行っているっぽい。
色はcreatePaintメソッドの方でランダムで定義してた。

drawCircleで行っている計算は速度をうまく使ってやってるみたい。
つまり、ランダムで発生した速度を点のサイズに反映することで、速い点はでっかく、
小さい点はちっこくなる・・んじゃないかなぁ。

progressって何だろう・・・

xmlで書くよりは確かに読みやすそう。でも描画を行っている部分が多少複雑になりそう。

これでAndroidのアニメーションが書けるようになった!

AndroidThingsのサンプルを読んでみる

読んでみる。
対象になるサンプルコードはいくつかあるが、今回はBlinkActivityにする。

(前回このコードでLED光らせたし・・。)


BoardDefaults.java

・・・動いているデバイスが何かを判定してるっぽい?。
edisonってデバイスの時だけ色々してるから、Android的には同じデバイスって判断しちゃうけど
実際はGPIOのところの配置が違う別物って感じなのかな。

if (sBoardVariant.equals(DEVICE_EDISON)) {
            PeripheralManagerService pioService = new PeripheralManagerService();
            List<String> gpioList = pioService.getGpioList();
            if (gpioList.size() != 0) {
                String pin = gpioList.get(0);
                if (pin.startsWith("IO")) { // 0番目のピン?が"IO"で始まる何かならこっち
                    sBoardVariant = DEVICE_EDISON_ARDUINO;
                }
            }
        }


大事なのはgetGPIOForLED()のところっぽい。
バイスごとに違う文字列返している。
LEDをセットしているところがどこか教えろーって感じかー


BlinkActivity.java

全然関係ないけど、Handlerはフィールドで宣言して初期化してるのね。
毎回newしてたけどこっちの書き方がいいのかねぇ。
中身読まなきゃなぁ。



mBlinkRunnable がフィールドにいない・・・!と思ったら下で宣言してた。
自由だな!

// このサービスにGPIOの名前を文字列で渡すといいみたい
PeripheralManagerService service = new PeripheralManagerService();

// 大事そう。DIRECTION_OUTとDIRECTION_INがあるらしい
// OUT_~以降はよくわからん。
mLedGpio.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);


// このsetValueに値を渡してon/offを切り替えている。
// 今回はLEDを点滅させるためにこうしてるみたい。
mLedGpio.setValue(!mLedGpio.getValue());


GpioインスタンスにどこにつなげるかとIN/OUTを教えてあげて、最後にon/offを
切り替えるって感じかな。
切り替え処理はHandlerに渡す形で実装しないとダメみたいだ。

closeを忘れるとまずそうだ。


センサーとかだと結果の戻りがあると思うんだけど、どう処理するんだろう。
それはボタンのサンプル見れば分かるかな?次回はそちらを動かしてみよう。


removeCallbacksってなんだろ。

onMapReadyに入らない

Google Map APIを使って粛々と開発していた。

特に問題なく動いていたが、テスト前にいくつかの端末で動かしたところ、Mapが

表示されない端末があった。

 

冷汗がすごく出た。

 

Fragmentにインタフェースを継承させて実装していたのが良くなかった。

OnMapReadyのインスタンスを直接newして持たせたら上手く表示された。

 

そもそもFragment上にGoogle Mapを表示させるって実装が良くないんだろうなぁ・・。ただでさえ重いのにね。

 

お客さんのところで発覚とかにならなくて良かった良かった

Android Thingsを試した話

先日、Android Thingsを試したので忘れないうちに

 

まず、Amazonラズベリーパイ3のキットとセンサー等の詰め合わせを購入。

結構種類があって何が何やらさっぱりだったが、for Dummies というやつが一通りそろっていてよさげだったので購入。

 

サンプルを試すのに一通りのセットがほしいと思い、スターターキットとやらも購入。

しめて1万円弱。

 

高いのか安いのか。

 

で、キットについていたSDカードにAndroid Thingsを入れて動かしてみた。

 

SDカードに入れるのにはWin32DiskImagerを使った。

キットについていたUSBにSDカードを挿してPCにセット。先に書いたWin32~でSDカードに焼きこみ。PCはWindows10。

 

会社がmacで家がWindowsなので、家でキーボード叩くとタイプミス多くて混乱する。そして家でキーボード叩くと会社でタイプミスが多くなって混乱する。

 

入れたらラズベリーパイ3にSDカードを挿す。場所がわからなくてしばらく悩んだ。最初は勘違いしてUSBごと挿した。裏側を眺めていたら気づいた。あぁ。。

 

さらにLANケーブル、HDMIラズベリーパイ3に挿す。最後に電源ケーブルを挿す。

赤いランプが点いたが、赤いと不安だった。待つことしばし。何度か抜いたりして時間を無駄にしつつ。無事、立ち上がって画面に少し古い雰囲気の「Android Things」が表示された。ついでにIPアドレスが載っていた。

その後の手順は公式サイトのまま

 

Wi-Fiへのアクセスがどうにもうまくいかなかった。

 

最後は電子工作。見よう見まねで台?にぐさぐさ挿して試した。

gitからサンプルコード落として手順の通りに入れた。LEDを光らせた。Android studioを使った。コードの意味は後日読むようにしよう。

 

最初、上手く光らず悩んだ。抵抗器が間違っていた。ちょっと色違うだけでこんなに違うのね。

 

以上です。

日々のまとめを書いていく

日々の学習などの内容について記載する備忘録を目指します。

飽きずに続けられますように。