まめーじぇんと@Tech

技術ネタに関して (Android, GAE, Angular). Twitter: @mame01122

未経験エンジニアに向けたブログを始めました。

久しぶりの投稿が宣伝ですみません。

ここ最近、未経験エンジニアを対象にしたプログラミングスクールなどが流行っています。
ここ最近はエンジニアから離れてしまってるのですが、僕も昔はプログラミングをしていた身です。

なので、そういった未経験からエンジニアになりたいと思う人の手助けをするようなブログを立ち上げました。

今はこちらのブログの更新に力を入れてやってます。
・エンジニア出身で
・UIデザインもやっていた経験があり
・商品企画やプロジェクトマネージャーをやっていた経験もある
ということで、普通のエンジニアブログよりは幅広い視野で「未経験からエンジニアになるために必要なこと」などを書いています。

僕がエンジニアのときに辛かった実体験ベースで、例えば、以下のような記事を書いています。
未経験からプログラマーになったけど辞めたいとき【実体験】 | まめブログ


また、中途採用の面接官の経験をベースに、以下の内容を書いています。
未経験エンジニアの志望動機の作り方【面接官に刺さる】 | まめブログ


未経験でエンジニアになりたい!という人はこういった記事を読んでいただけると嬉しいです。

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でした!