忍者ブログ
  • 2024.04
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 2024.06
[PR]
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

【2024/05/13 14:28 】 |
新規プロジェクトでfirebase周りが動かない時
https://codedump.io/share/BGfGS4xRt0XA/1/error-could-not-find-comgooglegmsgoogle-services10-when-adding-google-service-plugin-in-buildgradle-in-android-studio


PR
【2016/08/13 23:34 】 | Android | 有り難いご意見(0)
NDKデバッグはできないのか
http://qiita.com/MovaCloud/items/ba79c33704101a662add
このページなどもあるが、どうも上手くいかない


Configureを以下のように設定する(Symbolの位置は不明)




で、一応新しいコンフィグとして選択できるようにはなるのだが
結局C++側コードのブレークポイントは効かない


Android.mk のソースファイルディレクトリをapp/jni/ 以下に変え、cocos compile で再ビルドもしたがダメ




公式ページにも当たってみた
公式

Downloadできる。
ndk-***
のツールがいろいろあり、この中の
ndk-gdb
を使用する。

samples/ ディレクトリは、Eclipse前提のものだったので役に立たず
(今もう一度探せばあるかも)

ndk-dbg ツールを使う方法について記述してあるが
これはコマンドラインツールなので使い勝手は良くない
と言うか、これをAndroidStudioが使っているはずなのでは?



いずれにせよ、また改めて本腰入れて調べる必要がある

【2016/08/08 18:34 】 | Android | 有り難いご意見(0)
NDKデバッグはできないのか
http://qiita.com/MovaCloud/items/ba79c33704101a662add
このページなどもあるが、どうも上手くいかない


Configureを以下のように設定する(Symbolの位置は不明)




で、一応新しいコンフィグとして選択できるようにはなるのだが
結局C++側コードのブレークポイントは効かない


Android.mk のソースファイルディレクトリをapp/jni/ 以下に変え、cocos compile で再ビルドもしたがダメ




公式ページにも当たってみた
公式

Downloadできる。
ndk-***
のツールがいろいろあり、この中の
ndk-gdb
を使用する。

samples/ ディレクトリは、Eclipse前提のものだったので役に立たず
(今もう一度探せばあるかも)

ndk-dbg ツールを使う方法について記述してあるが
これはコマンドラインツールなので使い勝手は良くない
と言うか、これをAndroidStudioが使っているはずなのでは?



いずれにせよ、また改めて本腰入れて調べる必要がある

【2016/08/07 16:33 】 | Android | 有り難いご意見(0)
androidアプリをコードから終了させるとき
ドキュメント


moveTaskToBack()
これは、1つ前のアプリがフォアグラウンドになる。アプリを終了させる方法としては不自然


finish()
これが正しい


KeyEvent event = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HOME);
super.dispatchKeyEvent(event);
ホームボタンを押した時と同じ処理が走るかと思ったが、そうはならなかった。


finishAndRemoveTask()
試していないが、Android5.0からこのメソッドもある
ドキュメント



バックボタンとホームボタンは、挙動が違う。思想も違う

バックボタンは、現在のアプリを終了し、前のアプリに戻る。(正確にはアクティビティ)
アプリ内から別のアプリを呼んでいて、戻るときに押すのだからそうなるだろう

ホームボタンは、現状のアプリも含めて全部そのまま、バックグラウンドに置くだけ
ただ単にホーム画面を表示する


となると、バックボタンの場合はアプリを終了させ
ホームボタンの場合はアプリをサスペンドさせる発想になるはずだ


【2016/07/31 13:57 】 | Android | 有り難いご意見(0)
android + Firebase のプッシュ通知概論
作成はだいぶ楽である

公式ドキュメント

メッセージの他、自由にデータ(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()をすることにより、どう起動されたかがある程度判別可能。

Intent intent = getIntent();
Bundle dataPayload = intent.getExtras();
if (dataPayload != null) {
String value = dataPayload.getString("key");
}


という感じで取得できる。


【2016/07/28 18:21 】 | Android | 有り難いご意見(0)
androidのローカル通知概論
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 クラスを引数に指定しておけば良い

【2016/07/28 18:14 】 | Android | 有り難いご意見(0)
JNI
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をキャッシュし、クラスがアンロード&リロードされた時に再キャッシュする正しいコードは以下

private static native void nativeInit();

static {
nativeInit();
}





LocalReference と GlobalReference
ネイティブのメソッドに引数として渡ってくる変数は、ローカル参照
そのメソッドが終了すると向こうになる。普通のローカル変数と同じ。(参照元のJavaオブジェクトが生存していても、参照は無効になる)
jobject の子クラスである jclass, jstring, jarray などは全てこれ。

グローバル参照は、明示的に削除しない限りずっと参照を保持し続ける

使用例

jclass localClass = env->FindClass("MyClass");
jclass globalClass = reinterpret_cast(env->NewGlobalRef(localClass));


まずローカル参照を取得し、それをグローバル参照に変換する。
ローカル参照かグローバル参照かで型が変わるわけではない。

全ての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変換した時、望んでいない結果になる



例外について

例外処理を怠ると、実行時エラーで落とされる

if (methodInfo.env->ExceptionCheck()) {
methodInfo.env->ExceptionDescribe();
methodInfo.env->ExceptionClear();
}


jclass _clazz = (jclass) env->CallObjectMethod(cocos2d::JniHelper::classloader,
cocos2d::JniHelper::loadclassMethod_methodID,
_jstrClassName);

if (nullptr == _clazz) {
LOGE("Classloader failed to find class of %s", className);
env->ExceptionClear();
}


など。

【2016/07/25 15:13 】 | Android | 有り難いご意見(0)
Androidの時間設定公開
これは、APKからのアップロードだけでなく、
ベータ版からのプロモートでも、ちゃんと設定できる
【2016/05/06 14:25 】 | Android | 有り難いご意見(0)
adbコマンド
接続しているデバイスのログ出力
$ 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

【2016/03/18 22:56 】 | Android | 有り難いご意見(0)
AndroidでJNIデバッグ
方法はある。
Qiita

Experimental Plugin というgradleの新プラグインを使う
公式

だが、gradleの書き方自体が変わったり、対応するgradleのバージョンが限られたりと
いろいろ制限付き。


ちょっとやってみたが、見たことないエラーが起きたので
一旦必要になるまで見送り。
バージョンもどんどん上がり、これらのページに書いてあるのとは状況が変わっている。

いつになったら正式に組み込まれるのか。
【2016/03/08 16:23 】 | Android | 有り難いご意見(0)
| ホーム | 次ページ>>