Translate

BTemplates.com

Powered by Blogger.

2017年11月12日日曜日

英語で調べる際の便利そうな単語リスト


備忘録用

◆~が動かない
don't work
doesn't work
not work

◆削除
remove

◆検知
detect

◆~の仕方
How to

◆~するにはどうすればいいのか?
How do I ~


参考サイト:ITエンジニアのための英語まとめ
参考サイト:Web関係の困り事を英語でググる時に知っておくと便利な単語やセンテンス


2017年11月11日土曜日

2017-11-11 到達点メモ


VoiceTimerで起きていたクラッシュログに出ていた問題の対策の続き

昨日の記事の一部抜粋

>>アプリを待機状態でローカライズの変更を行うのと
>>アプリを起動しないでローカライズを変更し、そのあとにアプリを立ち上げるのと
>>区別をつけることができていない。

ようやく何とか対策ができた。
最初は、onResumeとかonPause辺りで、プリファレンス辺りにデータを保存してその組み合わせで出来ないのかとか、バックキーを押したときにプリファレンス辺りにデータを保存してできないのか等を考えて実際試してみましたが駄目でした。

話から外れるが、Androidの三つのボタンの名称を忘れやすいのでここにメモしておく、
・ホームボタン
・戻るボタン
・メニュー・マルチタスクボタン
参考サイト:Androidの3つのボタン

検証した結果、ローケル変更を行うとアプリケーション自体にonCreateが呼び出されます。
その為、タスクから呼び出すのと、完全に終了したアプリを呼び出されるのに違いがほとんど無いようです。

今回は難しそうだったので検証はしていないのですが
調べたところ、リストから削除した方法を一応検知する方法があるみたいです。
具体的には、serviceを追加するとタスク一覧から指でスワイプして削除した場合
onTaskRemovedでそれを検知できるらしいです。

参考サイト:How to detect app removed from the recent list
参考サイト:Differentiate between Android killing the app and user swiping it off on the recent apps list

で、さんざん悩んだ結果ふと閃いたことがありまして。

Spinnerの表示元はString.xmlで宣言している内容を使っており、
Spinnerのオブジェクトの表示テキストの内容と本来の表示するべきString.xmlの内容が
一致していないことをうまく利用できるのではと思いついたので
試したところうまくいきました。

var res:Resources  = getResources()
var ta:TypedArray = res.obtainTypedArray(R.array.time_value_list)
if((paramsManager.locale_language == whenResume_local.language)||               (time_spinner.selectedItem.toString().equals(ta.getString(time_spinner.selectedItemId.toInt())))){
            Log.d(TAG,"onResume_finished")
        }else{
            Log.d(TAG,"ChangeLocale!!")
            restartFlag = true
            // アクティビティ終了
            this.finish()
}

こんな感じです。
まぁ、対処としてはどうなのよという思いはありますが
この方法だと変更箇所も多くないですし、
正直楽だったので……。
それにいつまでもクラッシュが発生する状態よりは良いかなと思っていたので
対処しました。

参考サイト:Android, arrays.xml で定義した配列を利用する
参考サイト:SpinnerとTextViewを用いたAndroidサンプルアプリ
参考サイト:スピナー (Spinner) で選択されたアイテムの取得

なんか一仕事した感があるので今日はここまで。

2017-11-10 到達点メモ


やっと、クラッシュログの内容が分かった。
前のバージョンから以下のようなクラッシュログが何度か出ていました。


java.lang.IllegalArgumentException:
  at com.aaa.nononaga.voicetimerr.MainActivity$onCreate$1.onItemSelected (MainActivity.kt)
  at android.widget.AdapterView.fireOnSelected (AdapterView.java:1319)
  at android.widget.AdapterView.dispatchOnItemSelected (AdapterView.java:1308)
  at android.widget.AdapterView.selectionChanged (AdapterView.java:1299)
  at android.widget.AdapterView.checkSelectionChanged (AdapterView.java:1480)
  at android.widget.AdapterView.handleDataChanged (AdapterView.java:1456)
(以下略)

ずっと何が原因で起こるかわからなかったのですが、ようやくアプリを起動中に
ローケルを切り替える(言語を切り替えると)と発生するのを確認しました。

もしかすると複数の公用言語を持っている国は、場合によって良く切り替えたりするのかもしれません。

前の記事にonItemSelectedにnullが入る時があるから
エラーが出るという話をしましたが

改めて調べなおしたところ、赤字の部分の引数が
nullが入る時があるらしいと分かりました
            override fun onItemSelected(parent: AdapterView<*>, view: View,
                                        position: Int, id: Long) {

ですので、結果としては以下のようにViewをNullable型に変えてやれば解決します
            override fun onItemSelected(parent: AdapterView<*>, view: View?,
                                        position: Int, id: Long) {

これでクラッシュは起こらなくなるのですが、問題があります。
それは、他の文字は新しい言語に翻訳されるのですが
このSpinnerだけ元の言語のままという問題が起こります。

参考サイト:KotlinでParameter specified as non-null is null

というか見直したら、通知のテキストも更新されてなかった。
で、試行錯誤した結果、ローケルを変えてアプを復帰した時に
アクティビティを立ち上げる命令を出した元のアクティビティを完全に終了させることで
完全に翻訳された状態にすることができました。

機能が少ないアプリなので再起動してもあまり時間がかからないので
この手段が使えますがロードするデータが多いゲーム系や
複雑なアプリだと起動時間が長くなるため、やばい気がします

◆現在のローケルの取得方法
Locale.getDefault().language
これで、現在何語かを取得することができる。

参考サイト:Androidアプリで現在選択されているロケールを取得する

◆ローケルが変更したことを確認する

ローケルが変更したことを認識するようなメソッドがあれば早かったのだが
どうも見つからなかったので別な手段をとった。
具体的にはアプリが復帰する際に、予め保存したデータと
現在のローケルを見比べるという方法をとった。

また、注意事項として完全にアプを終了しないで呼び出した場合でも
onCreateがよびだされているようなので
アプリの初回起動時と、アプから離れたときと
アプを復帰させた場合のそれぞれのケースを考慮して
書かないといけない。
具体的には、
・アプリの初回起動時、もしくはローケルの保存データがない場合は、現在のローケルを保存する
・アクティビティから離れた場合、現在のローケルを保存する
*もしかするといらないかも
・アクティビティから復帰した場合、現在のローケルと保存したデータを見比べて
違う場合ならアプリの再起動。一緒なら無視。また、変更後のローケルを保存する


◆アプリの完全に終了方法。

簡単にいうとSystem.exit(0)を使った。
書いた場所はonDestroyの一番最後
無論これが推奨されていないのは知っているが
finishとかだとどうも完全に終了できないようなので
また、公式ドキュメントを見た感じだと
そもそもアプリを終了させること自体に
余り好意的でないように感じる

参考サイト:アクティビティをシャットダウンする


ただ、現状だと何処かロジックに問題があるようで
アプリを待機状態でローカライズの変更を行うのと
アプリを起動しないでローカライズを変更し、そのあとにアプリを立ち上げるのと
区別をつけることができていない。

煮詰まった感があるので今日はここまで





2017年11月10日金曜日

Adwordsの広告でスタイルと表現というポリシー違反に引っ掛かった話。


今、複数の言語で広告を出しているのですが
今日、メールで以下のようなものをもらいました


(前略)
平素より AdWords をご利用いただき誠にありがとうございます。

お客様の一部のユニバーサル アプリ キャンペーンでポリシー違反が見つかりました。この違反はキャンペーンの掲載結果に影響している可能性がございます。以下のレポートで詳細をご確認のうえ、記載されたリンクからポリシーに関する説明をご覧ください。


----------------------------------------------
キャンペーン: 「VoiceTimer#英語」
自分の広告のURL
----------------------------------------------

- スタイルと表現
  https://support.google.com/adwordspolicy/answer/6021546?&hl=ja#327
---------------------
(以下省略)

で、困ったことに実際のサイトに行ってみても
最初はどれが原因なのかいまいちわかりませんでした。

何故かというと、宣伝をする際に四種類のテキストが指定できるのですが
そのうちのどのテキストがおかしいのかの指摘がなかったためです。

四種類のテキストのうち一つのテキストは無理やりな文章だと自分でも思っていたので
それを修正したのですがエラーマークが消えませんでした。

そこでGooglePlayストアの英語の説明文をじっくり見直したところ
どうも説明文に使っていない単語を使ったため
エラーが出たようでした。

具体的にいうと、Simple and Easy Useみたいなテキストにしていたのですが
説明文にSimpleという単語はどこにも使っていなかったのです。

で、テキスト文を説明文にある単語で書き直したところ、
エラーマークが無事消えました。

AdWordsのテキストは25文字に抑えるのがきつく、割と雑に作っていたので
もう一度見直す必要がありそうです。

2017年11月7日火曜日

2017-11-07 到達点メモ


忘れやすいのでメモ
gimpでオブジェクトの整列を行いたい場合は
赤枠で囲んだ部分をクリックし


基準をアクティブなレイヤーに変更し



レイヤーで基準にしたいレイヤーを選択した後に、
並び替えたい整列ボタンをクリックする


googleConsoleの方を見たら、クラッシュの報告が来ているのを確認したので
テストをしてみたのですが、どうも再現できない。
一応、エラー文をそのまま検索をかけたところそれっぽいのは見つかったのですが……
参考サイト:Kotlin crashes on Android when selected item view is null
によると、AdapterView.OnItemSelectedListenerの中で宣言したonItemSelected()
の引数が、nullを取得する時があるらしい。
……まじかよ。
参考サイト:43.2.15 その他の例外のjava.lang.IllegalArgumentExceptionの項目部分
多分、上記の参考サイトと合わせて考えるに
nullが入っていることは案外ありそうだなと思った。

で、そういう訳で自動テストの方を試してみたいと思って
メモをしていなかったので忘れていたのだが
FirebaseにTestLabがあるので、それを使えばよい。

また、色々あってFirebaseがきちんと組み込んでいなかったので
組み込もうとしたら以下のようなエラーが出た

Error:Execution failed for task ':app:processDebugGoogleServices'.
> Please fix the version conflict either by updating the version of the google-services plugin (information about the latest version is available at https://bintray.com/android/android-tools/com.google.gms.google-services/) or updating the version of com.google.android.gms to 9.0.0.

困ったので検索したところ
以下のページを見つけた。
参考サイト:AndroidでGoogle Play 開発者サービス 8.4.0を導入したらversion conflictが起きた


どうも  apply plugin: 'com.google.gms.google-services'は
   compile 'com.google.android.gms:play-services-ads:11.0.4'を呼び出した後に
書かないとエラーが出るようである。


そして、どうしても減少が再現できないので変な動作をしていたら
新たなバグを発見してしまった……。
具体的にいうとバックキーを押すと、アプリが終了するのだが
その際にタイマーが働いていると、前のタイマーの時間が保持された状態なので
新しくタイマーを動かすと、前のタイマーと新しいタイマーが
同時に動き、表示がおかしくなります。
バックキーで終了的な事は基本は自分はしないのですが
他の人がこのような動作をする可能性はあり得るので、直します。

で、色々調べた結果、まずバックキーを検知する方法は

    override fun onBackPressed() {

    }
で、行うことができました。

一方で、原因は完全にわかり切っているわけではないのですが
    override fun onBackPressed() {
        super.onBackPressed()
        Log.d(TAG,"Pressed_BackKey")
        moveTaskToBack(true)
    }
にすると、super.onBackPressed()以降の文が全部無視されるので書かないようにしましょう。
どうも、参考サイトによると、super.onBackPressed()でデフォルトの動作を行っているようで、それがアクティビティを終了させる動作だから、そこで処理が止まってしまって以下の動作が無視されたのかもしません。

参考サイト:Android Overriding onBackPressed()


同時並行で終了させる方法も調べていたのですが、
finishAndRemoveTask()でバックタスクを残さずに
終了させることができるのですが
この場合、どうも全部の内容を削除しているわけではないようで
具体的には、バックキーを押したときと同様の現象が発生します。

参考サイト:Activity#finish() でアプリが終了できないときは
参考サイト:公式ドキュメント-オーバービュー画面-AppTask クラスを使用してタスクを削除す
参考サイト:公式ドキュメント-タスクとバックスタック


応急処置的な手法であれなのですが、
バックキーを押したときに、バックタスクにするという風な仕様にすることにしました。
と言っても最初はバックキーを押したときにバックタスクに残っていたこともあり、こっちの方がある意味操作感が変わらなくていいかもしれない。

具体的には以下のように書きます。
    override fun onBackPressed() {
        moveTaskToBack(true)
    }

参考サイト:Android で System.exit() を使ってはいけない理由と、終了方法のまとめ

ザっと動作確認をした限りでは、大丈夫そうなので
明日また確認したらアプリを上げる予定です。

今日はここまで。


2017年11月6日月曜日

2017-11-05~06 到達点メモ


久しぶりに画像の加工をやったら、動作を忘れていたのでメモ
gimpでオブジェクトを整列させたい場合は、以下のとおりにやること
https://docs.gimp.org/ja/gimp-tool-align.html


Androidアプリを公開した後に追加実装をしたい場合に真っ先にやっておいた方がいい事として、Gradleのアプリのバージョンコードを上げておくこと

何故かというと、GooglePlayに上げてあるバージョンのコードだと
実装のテスト中にクラッシュした場合
GooglePlayConsoleに報告が行くからです。

一人のクラッシュ数が掲載順位とかにそんなに影響はしないとは思うのですが
気分が悪いですし、一瞬勘違いするし、紛らわしいので
テストをしたい場合は、バージョンコードを上げておきましょう

今回、対応でフィリピン語を追加した際に、混乱したので載せておきますが
グーグル翻訳、Youtubeだとタガログ語
GooglePlayConsoleだとフィリピノ語
Adwordsだと、フィリピン語になります。

ネットに繋がっていると、問答無用で全部報告が行くみたいです。

adwordsで広告を打つために公用語一覧を作っていたのだが
複数の公用語がある場合があるので場合分けとかが面倒である。

今回データをグーグルスプレッドシートの方で立ち上げたのだが
iframeの方だとどうも、フィルターが効かないようである

埋め込む際に参考にしたサイト:GoogleスプレッドシートをBloggerに埋め込む(練習)

参考サイト:ネイティブスピーカーの数が多い言語の一覧

現状で対応しているのは、ドイツ語、フランス語、スペイン語、ポルトガル語のみです。




自分としては、わざわざエクセルを立ち上げなくても
アクセスできるようにしたいのでこうしたのだが、いまいち目的にあっていない
リンクを張るぐらいでしょうか?

国別公用語一覧

……編集者以外はフィルターが掛かっていないのでダメみたいですね。
ただ、閲覧者でもフィルターは作れるので(その際に見ている人のみがフィルターにかかった状態になっている)
見るたびにフィルターを作って並べ替えたり抜き出したりするといいでしょう。

あと、自分はフィルターをかける際に分からなくて悩んだので載せておきますが、
例えば、スペイン語だけをフィルターでかけたい場合
スペイン語以外の選択を解除して、値でフィルターをかけるの横にある
右向き横三角マークをクリックすると、OKボタンが表示されるので
そこでOKを押すと、フィルターが掛かります。

宣伝用の画像とか、色々やろうと思ったのですが
遅くなったので今日はここまで。

2017年11月4日土曜日

2017-11-04 到達点メモ


*kotlinで書いてます

VoiceTimerの新たな機能として音量調整を機能を作っていたのだが
意外に面倒。

よくあるシークバーによる音量調整機能をつけようと思ったのだが
調べたところ、一先ず公式ドキュメントにSeekBarPreferenceというのがあるのを見つけた。

途中で詰まったのでほおっておいたのだが、調べなおしたところ
普通にxml上で<android.support.v7.preference.SeekBarPreference/>
という風に使えば使えそうである。
明日辺り試す。

参考サイト:Styling android.support.v7.preference.SeekBarPreference

で、今回自分が試したのは
MaterialSeekBarPreferenceというライブラリである。

サンプルだけだとどうにも理解できなかったため
大分悩んだのですが、こう書きました

xmlファイル
<?xml version="1.0" encoding="UTF-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <com.pavelsikun.seekbarpreference.SeekBarPreference
        android:key="@string/key_name"
        android:title="@string/pref_title"
        app:msbp_interval="1"
        app:msbp_maxValue="100"
        app:msbp_minValue="0"
        app:msbp_measurementUnit="%"
        app:msbp_dialogEnabled="false"
        />

</PreferenceScreen>

kt.ファイル

class SettingPreferences : PreferenceFragment(), SharedPreferences.OnSharedPreferenceChangeListener {
//中略
        val volumeAdjustment = findPreference(seekBarKey)
        volumeAdjustment.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { preference, any ->
            val volume_persent = any as Int
            //処理内容
          false
        }
        volumeAdjustment.setDefaultValue(default_value)
//以下略

簡単に解説するとSeekBarPreferenceに型変換をする必要はなく
findPreferenceでとってくることができます
値が変化した時に値を保存するなり好きに処理すればいいと思います
デフォルト値は、setDefaultValueで代入できます。

ひとまず7.0で動作することが確認できたので
今日はここまで。