まめージェント

Android, GAE, AngularJSの技術ネタ中心。Twitter: @mame01112

Androidで不要な(意図しない)ストレージと連絡先のパーミッションが要求される

発端

去年作っていたAppをGoogle Playにあげようとした際、
何故かストレージと連絡先のパーミッションが要求されていることに気づきました。
でもAndroidManifestに書いているパーミッション
・INTERNET
ACCESS_NETWORK_STATE
・WAKE_LOCK
C2D_MESSAGE
あたりなので、ストレージとか連絡先の情報を取得しているわけではなさそう・・・でした。

わかったこと

・こうなってしまう原因不明は2つありそうです。

○ありうる原因その1
・targetSdkVersionが古い場合
下記によると、targetSdkVersionが古い場合は暗黙的にストレージや連絡先のパーミッションが追加されるそうです。
参考にしたのは下記。
android - AndroidStudio アクセス許可に、求めた覚えのない権限を求める - スタック・オーバーフロー

ただ、僕の場合、build.gradleに下記のように記載していたので問題ないハズ。

    defaultConfig {
        minSdkVersion 21
        targetSdkVersion 23
    }

AndroidManifestに記載していなくても、build.gradleに書いていればいいそうです。

○ありうる原因その2
・build.gradleは、使っているライブラリが古い場合であってもそのアプリで取得したパーミッションとみなされるそうです。
・ということで、対応としてはそのライブラリをどうにかする(使わないようにする or 新しいものに更新するなど)か、
 AndroidManifestのuses-permissionでremoveを指定してあげること。具体的には:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" tools:node="remove" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" tools:node="remove" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" tools:node="remove" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" tools:node="remove" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:node="remove" />

とやることでPermissionを上書きすることができるそうです。

僕の場合、この2つ目のケースに当てはまっていたようで、この対応をすることで
無事に不要なパーミッションを取得しないようにすることができました。

GCM PushのInstanceIDListenerService (onTokenRefresh)を手動でテストする方法

GCMのPush通知を実装しているAndroidアプリであればトークンが切り替わったタイミングを知ることができる
InstanceIDListenerServiceを継承したクラスを作ると思いますが、
今回はそのテスト方法に関して。

そもそもの背景

InstanceIDListenerServiceのonTokenRefreshは、正式なドキュメントにもある通り、
"Called when the system determines that the tokens need to be refreshed"とのこと。
「システムがトークンを更新する必要があると判断した場合に呼ばれます」・・・っていつだ、という話なので、
今回、この部分のテストのコマンドを調べました。

また、そもそもGCM Pushをやる方法に関しては、別の記事で書こうと思います。

テストのやり方

Step 1: 準備

基本的にInstanceIDListenerServiceは、AndroidManifest内でandroid:exported="false"に設定しているはずなので、
(でないと、外部からこのサービスを叩けてしまう)
テストのときのみ、このandroid:exported="false"をandroid:exported="true"に切り替えます。
※本当はもう少しいい方法があるのかもしれませんが、僕はそのやり方を見つけられず・・・。

Step 2: テスト実行

コマンドは、adb shellで行います。
コマンドプロンプトから下記のコマンドを叩いてください。

db shell am startservice -a com.google.android.gms.iid.InstanceID --es "CMD" "RST" -n com.your.package/com.your.package.to.InstanceIDListenerService

もちろん、com.your.packageはご自身のパッケージ名に変えてください。
com.your.package.to.InstanceIDListenerServiceの部分は、
InstanceIDListenerServiceまでのフルパッケージを記載するとうまくいきました。

以上、GCM PushのInstanceIDListenerServiceをテストする方法でした!

Android Studioでステップ数を数える方法

Android Studioでステップ数を数える方法が(少なくとも日本語のサイトは)あまり見つからなかったので、その方法を記載。ステップ数はコードを書く上でモチベーションを上げる重要な要素の1つだと思うので(笑)、書いておきたいと思います。

1: プラグインをダウンロード

下記のサイトからプラグインをダウンロードします。
http://plugins.jetbrains.com/plugin/?idea&id=4509
画面内にある"Download"のボタンを探します。
2016/07/18の時点では、2.6.1というバージョンが最新のようです。
そこから、プラグインをダウンロードしておきます。

2: Android Studioに読み込む

・続いて、Android Studioを立ち上げ、Android Studio > Preferenceを押してPreferenceのダイアログを開きます。
・そのダイアログの右下の方にある"Install plugin from disk..."をクリックします。
・さらに開いたダイアログの中から、1でダウンロードしたPlug-inを選択、Applyします。

3: Android Studioを再起動

・自動的に「再起動しますか?」と聞かれるので、そのまま再起動(聞かれなければ手動で)

4: Statisticのタブを確認

・画面の左下に"Statistic"のタブが表示されていることを確認します。
・(もし表示されていない場合は、画面上部のツールバーからViewをクリック、Tool window > Statisticを選択することで表示することができます)
・Statisticのウインドウにはおそらくデフォルトのままだと何も表示されていないので、"Refresh"のボタンを押し数秒待つと、無事にカウントが終わり、ステップ数を見ることができます。

以上、Android Studioでステップ数を数える方法でした!

CSSのbackground-sizeのオプション

Bootstrapのjumbotronに背景画像を指定する際、background-imageのオプションに関して勉強したので記載。

background-imageには、(直接パーセントやピクセル数で指定する以外に)下記3つのオプションがあるようです。

・auto
・cover
・contain

下記が、それぞれの内容です。

デフォルトはauto。この状態だと、設定した画像が表示できる領域よりも大きい場合は、そのまま切れて表示されます。

coverは、画像のアスペクト比を変更することなく、出来る限り大きくで表示するもの。

containは、画像を切り取ることなく画像を出来る限り大きく表示するもの。ただし、表示領域との差分がある場合、画像の上や横に余白が表示されることがあるもの。

勉強になりました。

マテリアルデザインのガイドラインまとめ (その1)

マテリアルデザインのガイドラインを読んでみた。

Androidアプリを作っている中で、そもそもマテリアルデザインって何だっけ?CardやデカいHeaderってどういう風に使うのが正解なんだっけ?を知らないことに気づきました。今まで何となくCardやデカいHeaderを使ってたけど、使い方って合ってるんだっけ?が気になり。ListViewとCardの使いわけ、みなさんはご存知ですか?僕は知りませんでした。ということで、Googleのマテリアルデザインのガイドラインを読んでみました。

Introduction - Material design - Google design guidelines

かなりのボリューム(しかも英語)なので、今回は1回目。Introductionから、What is material?. Animationまでをカバーしています。

  • -

Introduction

・マテリアルデザインの目標は、過去のいいデザインとイノベーションや科学の可能性を統合するようなVisual languageを作るため。

”マテリアル”とは?

・"マテリアル"は3Dの世界。なのでx、y、z軸があり、z軸方向にレイヤー状に表示される。
・光と陰を用いる。光には、Key light(一方向への陰)とAmbient light(全方向への陰)がある。

"マテリアル"の要素(Property)

・マテリアルはすべて1dpであり、それ以上の厚さを持ってはならない。
・陰は、自然な方向に向かう(自然環境であり得ないような陰の方向になってはならない)
・インプットのイベントは、マテリアルを貫通してはならない(例えばタッチイベントは、全面のマテリアルにのみ適用され、z軸方向に後ろにあるマテリアルに影響してはならない)
複数のマテリアルの要素が同じレイヤーにあってはならない(x, y軸方向に重なる場合は、陰をつける)
・Z軸方向の順番が入れ変わる際、マテリアル同士が貫通してはならない。
・マテリアルの形を変形してもよい。
・マテリアルは(折り紙のように)折れ曲がってはならない。
・Z軸方向に同じレイヤーにあるマテリアルは、2つ以上がつながってもよい。
・Z軸方向に同じレイヤーにあるマテリアルの一部の位置を入れ替える場合、入れ替えた後は再び1つのマテリアルに統合されなくてはならない。
・Z軸方向の移動は基本的にユーザのインタラクションによるものである。

階層移動と陰

・階層の大きさ(dp)は、マテリアルの種類によって決まっている。例えばDialogであれば24dp、Cardであれば8dpなど。
 ー詳細: https://www.google.com/design/spec/what-is-material/elevation-shadows.html#elevation-shadows-elevation-android-
・陰は、マテリアルごとのZ軸方向の深さ(順番)を示す重要なもの。
・マテリアルは、ユーザのインタラクションにより陰の大きさ(dpの大きさ)が大きくなる。
 つまり、ユーザがボタンなどを押すと、そのマテリアルはZ軸方向に全面に浮き上がってくる(結果、X, y軸方向に移動することができるようになる)

オブジェクト間の関係

・それぞれのオブジェクトは、1つの親を持つ
・それぞれのオブジェクトは、1つ以上の子を持つことができる。
・子のオブジェクトは親の移動に追従する(親の移動の際に子だけがその位置において行かれることはない)
・兄弟は同じレイヤーにあるオブジェクトのことを指す。
・ただし、Side nav drawer, Action bar, Dialogは例外。

アニメーション

・自然な加速と減速をすること
・画面から出て行くアニメーションで減速すると、画面の外にそのオブジェクトがあるように見え、ユーザを混乱させてしまうのでやってはならない。

レスポンシブなインタラクション

・タッチ、声、マウスなどすべてのインプットが重要。
・触ったことが分かるようなビジュアルフィードバックを行うこと。
 ー触った場所からrippleと呼ばれるビジュアルフィードバックを行うこと。
・ユーザのインタラクションに応じて新しいマテリアルを表示する際、ユーザが触った場所からアニメーション付きで表示すること(違う場所から表示してはならない)

意味のあるトランジション

・2つのステートを移行する際のトランジションは明確で、ステートが変更したことが明確に分かること。途中でアニメーションが切れてはならない。
・このトランジションのタイプは下記のものがある
 ーIncoming elements: 次のステートに移行した際に新しく生成されるエレメント
 ーOutgoing elements: 次のステートに移行した際に不要となるエレメント
 ーShared elements: Galleryのように、アイコンをタップして全画面で拡大して表示するようなエレメント
 ーアニメーションの方向や順番は意味を持っているべき。意味のない方向や順番のアニメーションをしてはならない。

  • -

次回はStyleから読んでみます!

JavaScriptでデザインパターン (その9: Revealing module pattern)

今回は、Javascript独自のパターン

ここしばらく他のいろんなことに時間をとられてしまい、なかなかコードを書く時間がとれなかったのですが、久しぶりに時間が空いたので、JavaScriptデザインパターンシリーズの続き。今回は、Revealing module patternです。

Revealing module patternとは?

これに関してはWikipediaでの記述が見つけきれなかったので、僕の理解のみ。
このパターンは、
・要するにオブジェクト指向でいうカプセル化のこと。
JavaScriptの思想的にカプセル化はあまり適さないのかもしれないけど、外部から使われる予定のない変数やprivateメソッド的なものを、意図せずglobalに使われないためのパターン。
です。

サンプルコード

今回のものは非常にシンプルなので、一気に書いてしまいます。

var Module = function() {

	var a = 0;
	var b = 1;
	var c = 2;

	function innerMethodA(){
		var result = a + b + c;
		console.log("innerMethodA: " + result);
	}

	function innerMethodB(){
		var result = a - b- c;
		console.log("innerMethodB: " + result);
	}

	return {
		outerMethodA : innerMethodA,
		outerMethodB : innerMethodB
	};

}();


console.log(Module.a);		//undefined
Module.innerMethodA();		// Module.innerMethodA is not a function
Module.innerMethodB();		// Module.innerMethodB is not a function
Module.outerMethodA();		// innerMethodA: 3
Module.outerMethodB();		// innerMethodB: -3

ここでのキモは、一番下でreturnしているouterMethodAとouterMethodBのみが外部から見えるオブジェクトとなり、その他のinnerMethodやa, b, cといった変数には外部からアクセスできない状態となります。このパターンを取り入れれば、内部だけで使うメソッドや変数を定義できますね。

要するにクロージャを使えばこのパターンになる?

必要なメソッドだけをreturn内部に書くのって、要するにクロージャを使うってことじゃない?と思い、多少調べてみました。その結果は・・・
クロージャで必要なメソッドだけを外部に使わせるパターンは、Module patternという。
・Revealing module patternは、このModule patternの一種である。
・Privateをどのように(どのような名前で)外部に公開するかは、return内部の一行のみで指定/変更できるのがRevealing module pattern。Module patternだと、オブジェクトの定義本体にも影響が及ぶ。

ということのようです。

以上、 Revealing module patternでした!

「『つまりこういうことだ!』ブランドの授業」まとめ

ここしばらく、ビジネス系のインプットを続けています。

今回読んだのは、「つまりこういうことだ!」ブランドの授業、という本。これも5年くらい本棚で眠っていたのをひっぱり出してきました。何故この本を買ったのか、全く覚えておらず・・・。

www.amazon.co.jp

ブランドとは何か?を体系的に勉強したい初学者にはいいかも、な本です。本の後半になるにつれ、少しずつ深い話になるのかな・・・と思いきや、意外と本の始めのあたりのペースで最後まで流れてしまいます。ということで、本の後半、ブランドとは何かを知るためにあまり必要ではなさそうな部分は多少は省略しています。
ブランドとは何かを勉強したことがあったり、マーケティングなどをやっていた人にとってはもしかすると、当たり前の話なのかもしれません。

  • -

ブランドとは何か?

・ブランドとは旗のこと
 ー何をやっているか、あるいは何がやりたいのか、自分が世の中に問うものの宣言
  ートレードマークはブランドを構成する1つの要素。
・ブランドは約束である
 ーいつも同じ売りが保証されていること。一貫性がある、毎度おなじみのxxx。
 ーブランドは人からの評価で成り立っている
・ブランドは人のこころの中に生まれる
 ーブランドを構成する要素が統合されてできるイメージ
 ーなので、旗をたてることはブランドづくりの第一ステップ。
 ーブランドの構成要素一つひとつが統合されてはじめて、ブランドになるためのメッセージを発信する。

ブランドを構成する要素

・下記5がある
 ーブランド・ゾーン
 ーイメーコ
 ーネーミング
 ー価格
 ーパッケージ
・目に見える要素が顧客と接触し、接触印象(インプレッション)の積み重ねによってブランドが創られて行く
・ブランドゾーン
 ー商品はその商品のしてくれること、すなわち「機能」とプラスの「付加価値」の部分の2つの属性から成り立っている
 ーそれぞれを機能ゾーン、ブランドゾーンと呼ぶ(ことにする)
  ー雨が降ったときに濡れない(傘の機能ゾーン)
  ーデザインがしゃれている(傘のブランドゾーン)
・ブランドゾーンを設計する
 ー商品設計のためには「この商品で世の中に提案したい価値」をしっかり決める必要がある
 ー100円ショップの場合は、機能ゾーンを満たすことが必要かつ十分条件で、ブランドゾーンはわずか。
 ー高級ブランドの場合は、機能ゾーンとブランドゾーンがほぼ同等の大きさで設計されている(=機能ゾーンはブランドゾーンと同等か、少し大きいくらいでないといけない)

ブランドづくり(1) / 「価値」を創る

・ブランド作りのステップ
 ーステップ1: 価値を創る
 ーステップ2: とんがらせる
 ーステップ3: とんがりを魅せる
・価値とは?
 ー「自分はこの商売で何を世の中に訴えたいか」という「思い」をメッセージにして伝わるようにした「中身」のこと
・「親しいイメージを創る」ことが大事
 ー親しみがある、安心できる、いつ行っても間違いがない、人にオススメができる
・サービスは「ブランドゾーン」によって選ばれる
・ブランドがどのようなイメージを持っているかで、見込み客が手にとってくれるかどうかが決まる。
 ー例: 銘柄指定ではなく、「缶コーヒーを買おう」とだけ思ってコンビニにいく。
 ーテレビ、コマーシャル、電車の広告といった宣伝広告の他、商品パッケージがイメージ作りに役立つ
・価値ととんがりの違い
 ー価値の中にとんがりがある(価値がとんがりを包含している)。
 ー価値は、One of them.とんがりは、Only one

ブランド作り(2) / とんがらせる

・とんがらせるとは、それぞれのカテゴリーにある「xxxであればyyyであるべき」を打ち破ること。
 ー「氷結」は、それまで焼酎がメインだったチューハイを、果汁をメインにした + パッケージもこれまでにないダイヤカット缶にして主張した。
・また、別の言い方であれば「絞り込む」「フォーカスする」ということ。つまり、ターゲットをしぼり、それ以外は捨てる。その分野でのダントツを追求する。
・ブランドの一番の役割は、心に刺さること
・とんがらせるときには顧客の意見をきく必要はない。返って来るのは、印象批評にすぎない。逆にいうと、それだけマイナスの批評があるということは可能性があるということ。
・提案するのは、時代の半歩先くらい。一歩先だと「早すぎる」ものとなってしまう。
・とんがらせるときにステレオタイプはNG。価値観が多様化している。
・優先順位の第一にくるのは、常に「絞り込む」「研ぎすます」の2つ。
・ネーミングの極意
 ーずばり価値を言い得ていること
 ー耳に心地よく響くこと
 ー記憶に残っていつまでも心に刺さっていること
・ネーミングセンスを磨くには映画や文学などが参考になる。
・プライシングは、「宣伝する」、「責任を持つ」、「自分が納得する」の3段階で考える。

ブランド作り(3) / とんがりを魅せる1 - 価格

・プライシングの三段階
 ーステップ1: 宣言する。価格はブランドが自分のとんがりを世界に向けてする宣言。 
 ーステップ2: 責任を持つ。価格以上の価値を提供する。責任がある。
 ーステップ3: 自分が納得する。自分の宣言と責任の間のバランスに納得できるかどうか。
・顧客は提供される価値に対して、「お金」、「時間」、「応援表としてのひいきの気持ち」を対価として払っている。
・そもそも価格とは、顧客との「思いのすりあわせ」
 ー上記の3ステップであれば「1, 価格を理解する(1000円なんだ)、2, 責任を負って頑張っているな、3, 価格に見合った、もしくは価格以上の価値だ」
・値引きは、上記3つのうちどれかが納得できないものとなった場合に行われる。顧客との思いのすりあわせができていれば値引く必要はない。
 ーまた、こうなってしまった場合、値引き以外にもとんがり型を変えたり、魅せ方を変えたりすることで価格に見合うものを提供する手段もある。
・ブランド戦略では、顧客に訴求すべきなのは「価格の安さ」ではなく、「ストーリー」や「哲学」
・「一番の安さ」を売りにするのは、「とんがったブランドを魅せる」という目的には役立たない。
 ープライシングは世界への宣言なので、「市場で一番安い」ということは、「市場で一番価値が低い」という宣言に他ならない。
・顧客は価値を目に見えるわかりやすい判断指標で測る。すなわち、「安い価格は安い価値」となる。
・高級ブランドは高くなければ意味がない。
 ー高いから人は買う。人はブランドを自分に投影する。

ブランド作り(3) / とんがりを魅せる1 - パッケージ

・ブランドにおけるパッケージとは一言でいうと、「ブランドの魅せ方の全体」のこと。
・音楽がただ単に音を推すだけだと音楽にならないのと同じように、顧客はネーミング、価格、ロゴ、バイライン、タグラインなどを統合した全体で認識する。
 ー高級レストランの例。
・オフィスの場所も、「場所の持つイメージ」が大事。
・商品デザインもパッケージの重要な要素の1つ。
・ロゴはブランド立ち上げと同時に創るべき
・バイラインとタグライン
 ー倍ラインは自分が何者かの自己紹介、タグラインは何ができるかの役割紹介
 ーバイライン: そのブランドが何をやっているのか、何をやりたいのかを顧客に分かってもらう役目
 ータグライン: ブランドが約束する価値を要約して説明するもの。サントリー南アルプス天然水であれば「山の神様がくれた水、サントリー天然水

ブランド作り(3) / とんがりを魅せる1 - 広告

・広告の極意は、絞り込んで、旗を魅せること。
 ー絞り込むとは、「メッセージを絞り込む」、「ターゲットを絞り込む」、「媒体を絞る」の3つ。
・広告の最大の目的は、「ブランド資産を増やすこと」
 ーブランド資産とは、「ブランドへの愛」や「親しみ」、「いい感じ」といった感情に根ざすもの
・とにかくシンプルに。
・チラシはブランドの姿勢を決めてから
 ーブランドの姿勢とは、「顧客がブランドを見上げるか」、「ブランドが顧客を見上げるか」のどちらか。
・媒体選択は慎重に行う。
 ー媒体はブランドの服であり、人間と同じくTPOに会わせて考えて行く姿勢が重要。

営業なくしてブランドなし

・営業は売るだけではなく、ブランドづくりにとっても非常に重要。
 ーブランドにとっての営業の役割は、「売り込み」ではなく、「価値伝達」。
・ブランドの価値は営業の人間力で決まる
・ブランドと市場とをつなぐ窓としてフィードバックする

スローなブランドを創ろう

・「ほんもの」のこと。
 ーブランドに、「愛と哲学」があるかどうかが重要。
・「顧客への愛」とは、「顧客を読む」こと。
 ー商品をただ提供するだけでなく、顧客のこころをしっかり観察して、読み取ったフィードバックとしての商品を開発すること。
 ー顧客をただ盲目的に愛するのではなく、あくまでもブランドとの関わりの中で価値を軸として考える。自社のブランドが何の価値によって顧客から愛されているかを観察し、現代版にアップデートしていく。
・美学とは、「誇り」や「こだわり」のこと。
 ーこれだけは譲れない、という点。ブランドの旗や約束がくっきり明確であるほど、美学がある。
 ー美学は、「これはやる」「これはやらない」というものさしになる。
 ーブランドの隅々まで美学が一本通ってなければならない。

  • -

以上、「『つまりこういうことだ!』ブランドの授業」のまとめでした!