× [PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。 |
https://codedump.io/share/BGfGS4xRt0XA/1/error-could-not-find-comgooglegmsgoogle-services10-when-adding-google-service-plugin-in-buildgradle-in-android-studio
PR |
http://qiita.com/MovaCloud/items/ba79c33704101a662add
このページなどもあるが、どうも上手くいかない Configureを以下のように設定する(Symbolの位置は不明) で、一応新しいコンフィグとして選択できるようにはなるのだが 結局C++側コードのブレークポイントは効かない Android.mk のソースファイルディレクトリをapp/jni/ 以下に変え、cocos compile で再ビルドもしたがダメ 公式ページにも当たってみた 公式 Downloadできる。 ndk-*** のツールがいろいろあり、この中の ndk-gdb を使用する。 samples/ ディレクトリは、Eclipse前提のものだったので役に立たず (今もう一度探せばあるかも) ndk-dbg ツールを使う方法について記述してあるが これはコマンドラインツールなので使い勝手は良くない と言うか、これをAndroidStudioが使っているはずなのでは? いずれにせよ、また改めて本腰入れて調べる必要がある |
http://qiita.com/MovaCloud/items/ba79c33704101a662add
このページなどもあるが、どうも上手くいかない Configureを以下のように設定する(Symbolの位置は不明) で、一応新しいコンフィグとして選択できるようにはなるのだが 結局C++側コードのブレークポイントは効かない Android.mk のソースファイルディレクトリをapp/jni/ 以下に変え、cocos compile で再ビルドもしたがダメ 公式ページにも当たってみた 公式 Downloadできる。 ndk-*** のツールがいろいろあり、この中の ndk-gdb を使用する。 samples/ ディレクトリは、Eclipse前提のものだったので役に立たず (今もう一度探せばあるかも) ndk-dbg ツールを使う方法について記述してあるが これはコマンドラインツールなので使い勝手は良くない と言うか、これをAndroidStudioが使っているはずなのでは? いずれにせよ、また改めて本腰入れて調べる必要がある |
ドキュメント
moveTaskToBack() これは、1つ前のアプリがフォアグラウンドになる。アプリを終了させる方法としては不自然 finish() これが正しい KeyEvent event = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HOME); super.dispatchKeyEvent(event); ホームボタンを押した時と同じ処理が走るかと思ったが、そうはならなかった。 finishAndRemoveTask() 試していないが、Android5.0からこのメソッドもある ドキュメント バックボタンとホームボタンは、挙動が違う。思想も違う バックボタンは、現在のアプリを終了し、前のアプリに戻る。(正確にはアクティビティ) アプリ内から別のアプリを呼んでいて、戻るときに押すのだからそうなるだろう ホームボタンは、現状のアプリも含めて全部そのまま、バックグラウンドに置くだけ ただ単にホーム画面を表示する となると、バックボタンの場合はアプリを終了させ ホームボタンの場合はアプリをサスペンドさせる発想になるはずだ |
作成はだいぶ楽である
公式ドキュメント メッセージの他、自由にデータ(payload)を含めて送信できる SDKを入れ、permissionをmanifestに書き、google-services.json 入れたらもうそれだけで届くようになるはず。 ・起動中にpush通知を受け取った場合 FirebaseMessagingService クラスを継承し onMessageReceived(RemoteMessage remoteMessage) メソッドをオーバーライドする。この関数が呼び出される メッセージ本文は remoteMessage.getNotification().getBody() データpayloadは Map<String, String> data = remoteMessage.getData(); となる。data.get("key") みたいな感じで取得。 ・バックグラウンドでpush通知を受け取った場合 受け取った瞬間にアプリ内のどこかのコードが走るわけではない(たぶん) push通知から起動した場合、iOSのように特別なメソッドが呼び出されることはないが、 MainActivity::onStart()内で、getIntent()をすることにより、どう起動されたかがある程度判別可能。
という感じで取得できる。 |
iOSでローカル通知と呼んでいるものと同等のことをAndroidで行おうとする場合
・AlarmManager 指定時刻に処理を発動させる機能を持つクラス 自身のアプリがバックグラウンドにいても問題ない AlarmManager を作成する。 指定すべき事柄は大きく2つ 1. 時刻 発動させたい時刻。long型で、1970/1/1 からのミリ秒 2. 内容 発動させたい内容。 つまり、指定のメッセージで通知を実行するということ Intent型。起動すべきクラスの指定と(後述)、extraに随時データを格納する(メッセージ本文など) AlarmManager が発動したのを受け取るためには BroadcastReceiver を継承し onReceive() を実装する(仮にAlarmReceiverクラスとする) かつ、AndroidManifest.xmlにも記述を行う ・AlarmReceiver::onReceive() で行う内容 Notification.notifyを行う つまり、通知を送信 指定すべき事柄は ・表示内容 通知のタイトル、テキスト、アイコンなど テキストなど、毎回変わるような事柄は AlarmManager から伝達してもらうのが良い onReceiveの引数にintentがあるので、intent.getExtra()などする ・タップ時の挙動 通知をタップした時に実行させる内容 つまり、自身のアプリの起動 Intent型 自身のMainActivity クラスを引数に指定しておけば良い |
Android5.0から、VMが変わった(Darvik -> ART)
その為、過去のコードだと実行時例外がポンポン発生するように 以下のページをよく見て 公式 JNIはベンダーに依存しない。 動的にshared libraryをロードする。 時に扱いづらいが、概ね効率的だ。 JNIには、2つの重要なデータ構造がある JavaVM JNIEnv どちらも、関数テーブルやメンバー関数へのポインタを保持するクラス。 JavaVMクラスは、"invocation interface" functions を提供し、それを使ってJavaVMクラスを生成、破棄できる 理屈的には、JavaVMクラスはプロセスごとに1つ持たせることができるが、Androidは1つしか許可していない JNIEnvクラスは、JNIのほとんどのメソッドを提供している ネイティブ関数呼び出しは、必ず第1引数がJNIEnvになる JNIEnvはスレッド固有に保持する為、スレッド間共有は不可 どうしても必要な場合は、JavaVMの方を共有し、JavaVM.GetEnv()で取得すること CとC++では、JavaVM,JNIEnvの定義が異なる。 jni.hの中身を見るとわかる。 C/C++が混在する場合、ヘッダファイルからjni.hをインクルードするときは要注意 スレッドについて スレッドとは、Linuxスレッドである。 通常はコード上から作成する(java.lang.Thread.start)。 それ以外の手で作られたスレッドの場合、JNIに明示的にアタッチする必要がある(AttachCurrentThread または AttachCurrentThreadAsDaemon関数。なおすでにアタッチ済みのスレッドに対してAttachCurrentThreadを実行しても、何も起こらない)。 そうしないと、そのスレッドにはJNIEnvが生成されず、JNI呼び出しができない。 ネイティブコードからJavaオブジェクトのフィールドにアクセスする場合 FindClass GetFieldID GetIntField の順に使用する メソッドを呼び出す場合 FindClass GetMethodID の順に使用する IDとは通常ポインタのことである。 文字列比較によって検索している。最初は検索するので遅いが、2度目以降は早い はじめに一度検索しておき、結果をキャッシュしておくことは有効だ クラス参照は、クラスがアンロードされるまでは保証される。クラスがアンロードされることは滅多にないが、Androidでは起きうる。ClassLoaderに関連づいているクラスが全てガベージコレクトされた時にアンロードされる。 jclass オブジェクトは、クラス参照である フィールドやメソッドのIDをキャッシュし、クラスがアンロード&リロードされた時に再キャッシュする正しいコードは以下
LocalReference と GlobalReference ネイティブのメソッドに引数として渡ってくる変数は、ローカル参照 そのメソッドが終了すると向こうになる。普通のローカル変数と同じ。(参照元のJavaオブジェクトが生存していても、参照は無効になる) jobject の子クラスである jclass, jstring, jarray などは全てこれ。 グローバル参照は、明示的に削除しない限りずっと参照を保持し続ける 使用例
まずローカル参照を取得し、それをグローバル参照に変換する。 ローカル参照かグローバル参照かで型が変わるわけではない。 全てのJNIメソッドは、ローカル参照もグローバル参照も引数として受け付ける(型が同じだから当然だろう)。 複数の参照が同じオブジェクトを指しているかどうかを判定するには、IsSameObject メソッドを使用すること。==で判定してはいけない。 jfieldIDとjmethodIDは、オブジェクトへの参照ではないため、NewGlobalRefしてはいけない GetStringUTFChars や GetByteArrayElementsも同様である ローカル参照は、明示的にdeleteする必要がある。 ローカル参照が自動的にdeleteされるのは、スレッドが削除された時である。 UTFについて JavaはUTF16を使っている。 JNIはM-UTF8も対応している M-UTF8についてはこちら参照。簡単に言うとJava独自のUTF8。 M-UTF8は、0x0000を0xc0, 0x80という2文字に変換する。 これの利点は、通常のC文字列同様、NULL文字(0x00)を文字列の終端として扱うことができる。(0x0000のままだと、この文字をC文字列終端と認識してしまうから) 欠点は、UTF8からの変換の手間が必要な事。 可能なら、UTF16を使うのが早い。 GetStringCharsは、jstringをUnicode配列に変換する GetStringUTFChars は、jstringをMUTF8に変換する NewStringUTFに渡す文字列は、MUTF8でないといけない。 ここが要注意。ASCII文字列しかないとわかっていれば良いが、そうでなければ変換をする事 でないと、内部でUTF16変換した時、望んでいない結果になる 例外について 例外処理を怠ると、実行時エラーで落とされる
など。 |
これは、APKからのアップロードだけでなく、
ベータ版からのプロモートでも、ちゃんと設定できる |
接続しているデバイスのログ出力
$ adb logcat 自分のゲームのログだけを出力 $ adb logcat | grep System 接続しているデバイスのファイラ $ adb shell $ run-as パッケージ名 接続しているデバイスにapkをインストール $ adb install XXX.apk 接続しているデバイスのapkを削除 $adb uninstall xxx.xxx.xxx.packagename Macに接続しているデバイスの情報を取得 $ adb devices |
方法はある。
Qiita Experimental Plugin というgradleの新プラグインを使う 公式 だが、gradleの書き方自体が変わったり、対応するgradleのバージョンが限られたりと いろいろ制限付き。 ちょっとやってみたが、見たことないエラーが起きたので 一旦必要になるまで見送り。 バージョンもどんどん上がり、これらのページに書いてあるのとは状況が変わっている。 いつになったら正式に組み込まれるのか。 |