kojiko-android’s blog

開発中にハマった時の解決策や、忘れがちなことを残しておきます。

Shapeで真円のボタンをコードで生成する

ボタンの背景に真円を使いたい時、とりあえず簡単に実装したい時に。

f:id:kentaro198477:20171017182545p:plain
iOSの電卓風のボタンです

Buttonを継承したカスタムButtonクラスを作り、以下のメソッドを追加し、onLayout等で呼び出します。

    public void setSolidColor(final int color){

        int w = getWidth();
        int h = getHeight();

        final int r = Math.min(w,h) / 2;

        final int cX = w / 2;
        final int cY = h / 2;

        Shape s = new Shape() {
            @Override
            public void draw(Canvas canvas, Paint paint) {
                paint.setColor(color);
                paint.setAntiAlias(true);
                canvas.drawCircle(cX,cY,r ,paint);
            }
        };

        ShapeDrawable sd = new ShapeDrawable(s);
        RippleDrawable rd = new RippleDrawable(ColorStateList.valueOf(Color.WHITE),sd,sd);
        setBackgroundDrawable(rd);
    }

xmlでリソースを書くことも無く、とりあえず簡単に実装できます。
リップルエフェクトも実装しているので、マテリアル的なタッチフィードバックも実現できています。
また、動的に色を変えたい時も上記のメソッドを呼べばいいので、色のカスタマイズ機能を実装する時も
ドロワーブルを取り出してカラーフィルターをかけて…としなくても良いので簡単だと思います。
等間隔に配置するなど工夫するとよりキレイなデザインになると思うので、いろいろやってみてください。



楕円のボタンなど古臭くて使わないと思うので、真ん丸のリソースくらい簡単に書けるようになってほしいですねぇ。

Apple ID を忘れてしまった。サポートに電話しないで思い出す方法【iPhone】

iPhoneiCloudのバックアップから復元しようとしたが、AppleIDを忘れてしまった」
公式サイトで検索したがヒットしない、サポートに電話をかけるも、
「結論から申し上げて自力で思い起こして頂く他ありません」と言われてしまう。
あの親切丁寧なアップルのオペレーターさんでも、打つ手が無いという状況。
AppleIDは、公の情報のようでありながら、実はとてもパーソナルで重要な情報です。


このページを読まれている方は、IDを思い起こすために既に様々な方法を試されたのではないでしょうか?


ここでは、私が実際に、丸一日苦悩した末に、新規Apple ID作成の一歩手前で思い出した方法を紹介します。
(全ての方に結果が出るかはわかりません、あくまで自分の行った例です)

他のSNSサービスの登録情報から探す


公式サイトから、「Apple ID をお忘れですか?」は、試されましたか?
性と名を入力し、メールアドレスを入力します。
しかし、このメールアドレスがiCloudのアドレスだと、Apple IDと同じ物なので、
ここで詰みます。
それが分かれば苦労していませんね。

逆を言うと、iCloudのメールアドレスが分かれば、Apple IDが分かります。

iPhone純正の”メール”アプリがありますね。
届いたメールは、iCloudGmail、Yahooメールなど、アカウントごとに分類されています。
iCloudの受信箱を見たときのことを、よーく思い出して下さい。
だいたいは、Appleからのお知らせやiTunesのメールがほとんどだと思いますが、
Apple以外からのメールはありませんでしたか?

私の場合は、Twitterからのメールが来ていたのを覚えていました。
本文には「最後のステップです・・・」とあったので、
初めはiCloudのアドレスを狙った迷惑メールかなと思っていましたが、
SafariからTwitterにログインし、
「設定とプライバシー」、「アカウント」と進むと、
「メール」の項目のところに、バッチリとiCloudのメールアドレスが入っていました!

これこそ探していたApple IDです!


私の場合は、このTwitterからのメールが決め手でしたが、
他のSNSサービスからのメールが入っていたのを思い起こせたのなら、
当該SNSにログインすれば、登録情報からiCloudのメールアドレスを発見できるかもしれません。


これを機に私は、Apple IDの表示された画面のスクショを撮り(Googleドライブなど別のアカウントにも保存)、
紙に書いて物理的に保管することを決めました笑。


その他、最終手段

Appleのサポートに電話をし、サポートの「スペシャリスト」に繋いでもらいます。
Apple IDアカウント作成の際に、使用したと思われる語句を思い出せる限り伝えて、
あらゆる組み合わせの可能性も伝えます。
検索してもらう際に、誤字を含んだIDの候補も教えてくれることもあるので、
(おそらく、スペシャリストさんには、Appleに登録されているIDのリストが見えている)
それらの候補を片っ端から打ち込んで試してみるという方法です。

ただしこの方法は、オペレーターの方に大変な負荷がかかってしまううえ、
こちらから提示した語句が正しいとは限りません。

私の思い出せる限り、
「名前 + 苗字のイニシャル + 生年月日 @icloud.com」
と登録したと思っていたのが、
実際に登録していたものは、
「あだ名 + 誕生日 @icloud.com」
でした。

人間の記憶はあいまいです。
もし私がオペレーターに上記の方法をお願いしていたら、
何時間かけようが解決しなかったでしょう。
たいへんなご迷惑をかけてしまうところでした。


普段、親身になって相談に乗ってくださるAppleのサポートチームの方々には、迷惑はかけたくないものです。



以上、私が試して解決できた方法です。
同じような悩みを抱えている方の問題解決を祈っております!

【日記】電卓アプリ製作中・・・【進捗状況】

私も電卓アプリでポルシェを買いたい!と思って電卓アプリを作っています笑

といってもなかなかダウンロードは伸びず、ポルシェを買えるようになるには100年はかかりそうですね。

そのまえにキーストアの有効期限の25年を過ぎそう・・・


でも電卓って、基本的な機能を抑えてプラスアルファの機能を付けたり、デザインで勝負したり、

付加価値を生み出せれば、それにヒットする方には使って頂けそう。


そういう意味では夢があるテーマではあると思うのである。


ではどうするか。

まずはターゲティング?

万人受けにするか、ニッチな感じにするか。

既に10万ダウンロード以上されているアプリを見ても、

シンプルなもの、実物のようにリアルなもの、単位変換なども計算できる多機能なもの、

関数電卓・・・これは、層が狭そうだし、私には到底作れない。

あとは、キャラものだったり、テーマが豊富なものだったり。

ただ、どれも自分にはしっくり来ないんですよね。


なんかで読んだ、ターゲティングはアバウトにしないで、

現実世界の一人にまで絞る(もしくは、実在するかのごとく詳細まで設定する)といいらしい。

じゃあ、ターゲットを自分にして、自分が最も使いたい電卓を作ろうと思う。

これってありなのかな?

自分だと客観的になれないとか、

なんか作ったけど、既製品とは違う手作り感がでてしまう。

ボタンの余白とか、色とか、既製品は全てうまいことまとまっている感があるが、

自作のだとどこか不安定な感じがするのですが。


いや、それより大元の部分をしっかりするべきなのか。

電卓という、それでできることはほぼ一緒という、

なにか感動を与えるものではないということがネックになっている気がします。

誰もが使ったことのある、ごく身近なツールの一つなので、

使い慣れた電卓(電卓アプリ)から乗り換えてくれるような、

もしくはダウンロード済みのアプリに並べてインストールしてもいいよってくらいの

クオリティと、狭い意味でのポテンシャルがないと厳しいのかな。


ターゲティング自分だと完壁主義に陥りなかなか完成しなさそうなので、

ターゲットは身近な家族にします笑

プレゼントするつもりで作ってみます。



今日はメモリー機能を付けました。

頑張ります。

Viewを指に追従させる方法

ボタン等のViewをタッチし、そのまま指をスライドさせたときに、
指にくっついて来るようにViewを動かす方法です。

サンプルでは横移動のみに制限し、指を離すとゴムのように元の位置に戻る動きをします。
iOSの”スライドでロック解除”のイメージ)

Viewのタッチリスナーに以下のように記述します。

movableButton.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {

                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        v.setTag(event.getX());
                        break;
                    case MotionEvent.ACTION_MOVE:
                        float f = event.getRawX();
                        v.setTranslationX(f - (float)v.getTag());
                        break;
                    case MotionEvent.ACTION_UP:
                        ObjectAnimator.ofFloat(v, "translationX", v.getTranslationX(), 0f)
                                .setDuration(100l)
                                .start();

                }
                
                return false;
            }

        });


getRawX()では、スマホの画面に対する絶対位置を取得できます。
getX()は、Viewに対する相対的な位置を取得するので、
指を動かしたときにViewを移動させると、その都度、相対位置が変わってしまいます。


アクションダウンで、移動開始時のX値を取得しておきます。
フィールドを使わずシンプルにするため、Viewのタグを利用しました。
v.setTag(event.getX());


アクションムーブで移動量を求め、
その値の分だけViewを移動します。

float f = event.getRawX();
v.setTranslationX(f - (float)v.getTag());


指を離したときに、元の位置に戻るアニメーションです。
移動後の現在位置から元々設置されていた位置まで戻る動きをします。

Ollieを導入する

簡単にデータベースを扱うことができるOllieの導入方法です。
build.gradle(app)に、以下の青色文字の部分を追加します。


apply plugin: 'com.android.application'
apply plugin: 'com.neenbedankt.android-apt'


dependencies {

  ・・・

compile 'com.michaelpardo:ollie:0.3.1'
provided 'com.michaelpardo:ollie-compiler:0.3.1'

}


build.gradle(プロジェクト)に、以下の青色文字の部分を追加します。



buildscript {
repositories {
・・・
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'

}
}

以上備忘録。

Androidアプリ終了に広告を出すとポリシー違反になる!?

ポリシー違反の回避と、長く使ってもらうアプリにするための考察

 アプリ終了時にインタースティシャルなどの広告を表示するのは、
Googleデベロッパーポリシー違反にあたります。
Androidに慣れ親しんでいるユーザーは、端末のバックボタンを押したら、
一つ前に見ていた画面に戻るということを、経験則から予測しています。
新しい端末に買い換えたときでも、Androidであればすぐに不自由なく操作ができるわけですが、
この一貫性を損なうような振る舞いをしてはいけません。

 ユーザーの期待する動作を妨げてはいけません。
時間がない時、すぐに終電を調べたいのに、アプリを切り替える時に突然広告が出てきたらとても困ります。
テレビCMのように、ある程度予測できるタイミングにする必要があります。
「このアプリの機能を無料で提供するので、ちょっとだけ広告を見て頂けませんか?」というくらいの気持ちで、
極力ストレスにならないようなタイミングで表示するべき。
よく言われていますが、緊張が解けたタイミングが、ベストだと思います。

ユーザーの事を考えてみる

 普段、無料のアプリを利用するユーザーは、
開発者たちがどのようにして収益を得ているかを知っているとは限りません。

 アプリとユーザーで、WIN-WINの関係が保てることが大切です。
広告に対して不快な思いが強くなってしまえば、WINーLOSEとなり、
アプリがアンインストールされてしまうと、
結局LOSEーLOSEになってしまいます。
当たり前のようですが、長く使ってもらうにはユーザーの気持ちになって考えることが大切であると思います。

対策案

1.ネイティブ広告に変える

 アプリのデザインに溶け込むデザインの広告を使うと、視覚的なわずらわしさを解消できます。
広告というのは意識を向けさせるために、色鮮やかだったり、点滅したりしているが、
色数を抑えられた落ち着いたものにするだけでも効果的。
アプリにはあまり多くの色を使わないほうが良い。
不快ではないから「そのまま無視で問題ナシ」と思われるのか
収益的にはあまり良くなかった。
それでも、前途のLOSEになることは防げるのではないでしょうか。

2.インストール時に位置情報などのパーミッションを要求する

 インストール時に、ユーザーの質をふるいにかけます。
「電卓アプリなのに、なぜ位置情報?」と懐疑心を抱くユーザーは、
広告に対しても消極的でしょう。
逆にあまり疑わずにインストールする人は、
広告に対しても警戒心が低いかもしれません。
結局広告に興味を持ち、クリックしてもらわないことには収益に繋がらないので、
意地でも広告をクリックしないという人には初めからインストールをご遠慮いただくというのもひとつの方法です。
予算に余裕がある場合は別ですが。
インストールしてくれたユーザーには、
位置情報からより適切な広告を表示することができます。

「位置情報は疑問だったが、どうしてもこのアプリの機能を使いたくて」インストールした方のために、
個人情報保護方針(プライバシーポリシー)を明記します。
なぜ、このアプリは位置情報を取得したのか。

「このアプリには○○、○○などの第三者の広告事業者による広告が表示されることがありますが、
お客様を特定しない範囲での情報(電話番号を含まない端末情報、性別、現在の位置情報など)を
利用することで、より適した広告を表示することができます。」
というように、透明性をアピールすることで、
納得でき、アプリと、広告に対して信頼感も得られるかもしれません。

Googleでは、機密情報を取得するアプリには、アプリ内と、アプリストアの目立つところに、
プライバシーポリシー(へのリンク)を記載するように示唆していますので、
いずれにしても、プライバシーポリシー記載は必要です。
play.google.com

3.ビデオ広告を見てくれたら、バナー広告を非表示にします

3日間などの期限を決めて広告を非表示にする代わりに、高単価のリワード広告を視聴してもらうというもの。
WIN-WINな取引のようであるが、広告に焦点が当たりすぎているので、少々胡散臭さが出てしまうかもしれません。
ユーザーに選択肢を与えるという意味では良いかもしれないが、ユーザーにとってメリットが薄い。
いままでマイナスだったものがゼロになる程度のもので、
私のアプリの場合、実装後数回再生されたものの、しばらくしたらほとんど再生されなくなった。
一度試して期限が終了したら、今後は他の広告くらい我慢できてしまう。
ゲームで劇的な効果を上げるアイテムとの取引なら応じてくれるかもしれないが、
私はゲームは作らないので検証できず。
ツール系アプリなら、便利な機能の開放など、大きなメリットを提示しないと難しそうです。
ツール系は長くつかってもらいたいので、信頼度を下げないように注意したい。

結果

あくまで個人開発者目線ですが、
最も効果が高かったのが、以下の実装方法でした。
具体的に、

キッチンタイマーのアプリで、普段よく計測する時間をリスト表示する画面の、
下部に設置したダブルサイズのバナー広告

ネイティブではなく普通のバナー広告です。
おそらく前途の、ユーザーにうっとおしさを与えないという意味で、
適切な場所なのだと思います。
ダブルサイズでも、「広告が邪魔」といった内容のレビューもありません。

結局のところ、良いアプリをユーザーの気持ちになって、
丁寧に作っていくのことがなにより大切なのかもしれません。

ViewSwitcherの任意のページに飛ぶ

ViewSwitcherは2つのビューを切り替えることができますが、
切り替えるメソッドがshowPrevious()かshowNext()しかないため、
「進む」「戻る」しができず、
ページを指定して切り替えることができません。

そこで、getDisplayedChild()を呼び出すと、現在表示されているページが0か、1かを取得できるので、
その値に応じて処理を分岐することで、任意のページを表示することができます。

最初のページに飛ぶサンプル
private void jumpToPage1(){
    if (yourViewSwitcher.getDisplayedChild() == 1){
        yourViewSwitcher.showPrevious();
    } 
}

アニメーションを付加する際は、求める挙動にあわせて「進む」か「戻る」を設定します。