Translate

BTemplates.com

Powered by Blogger.

2018年3月31日土曜日

2018-03-12、19、28 、29 到達点メモ


Ajaxでjqueryを使ってalertを呼び出したところ
文字化けした。
htmlファイルの文字コードをEmEditerでutf-8(BOM無し)からutf-8(BOM有り)で
保存したところ、文字化けが治った。

Chromeのディベロッパーツールのショートカットは
Shift+Ctrl+Cで立ち上がる

アクティビティを最小化させるのは
moveTaskToBack()

finish()だとメインアクティビティの上に別のアクティビティを立ち上げていた場合
そのアクティビティを終了し、メインアクティビティを表示する時がある


あと、2018-03-10 到達点メモで言っていた履歴機能が正常に働かない問題は
普通に、自分の並び替えの処理が間違っていただけだった。
他のアプリと微妙に結果が違うが、操作の実感としては大体あっていたので
これで良しとする

うーん。久しぶりにふれたが大分使わないと操作を忘れる。
それはそれとして、今延長機能を実装しているのだが
初回だけタップしてもすぐ延長ボタンを押す必要があった。
端的にいうと延長ボタンをタップした時にタップしたというフラグを保存していたのだが
どうも、押した後にフラグを保存するデータをオフに戻していなかったのが原因だった。

もう少し奇麗なやり方がある気がすると思って調べてみた
多分、状態遷移の話っぽい気がする

参考サイト:「設計」できないエンジニア
参考サイト:「設計」できないエンジニア ー2ー
参考サイト:状態遷移表を使用した設計モデル(拡張階層化状態遷移表)
参考サイト:より良いシステム開発のために、状態遷移設計のことを知ってほしい


やはりちょっとごちゃごちゃしてきた
それはそれとして、どうやら Activity() を継承しない場合で
startActivityを使う場合、いつも使っている奴と違い
三つ引数が必要になる。
具体的には、Context、Intent、Bundleだ。また、IntentのFlagに
Intent.FLAG_ACTIVITY_NEW_TASKが必要になる
Flagを設定しない場合は以下のようなエラーが出る
android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity  context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?

上記をふまえて今回は以下のように書いた

var intent = Intent(context.applicationContext, ScheduleSettingActivity::class.java)
val bundle = Bundle()
val packageName = view.findViewById(R.id.appPackageName) as TextView
intent.putExtra("packageName",packageName.text.toString())
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(context,intent,bundle)

参考サイト:Android: Activity以外からActivityを起動させる

あと、今回アプリ一覧を他のアクティビティから戻ってきたときに
自動でデータの更新をしたうえで現在の状態に並び替えしたいのをうまくできなくて悩んでいました。

で、よく見たら普通に並び替えの処理をメソッドで切り出せて引数を
与えれば普通に動きそうなことに気が付いたので
やってみたら実際に上手く行きました。

思い込みで切り出せないと勘違いしているものは結構多いのかもしれない。
今日はここまで



2018年3月10日土曜日

2018-03-10 到達点メモ


どうやって履歴時間を取得するんだろうなぁ……

下記のような実装で前面に出た時間を取得できはするのだが
結果と実感の時間が合わない     
val usageEvents = stats.queryUsageStats(UsageStatsManager.INTERVAL_DAILY,startTime,endTime)
val time = usageEvents[0].totalTimeInForeground

上記の方法だと、時差でずれるらしいので下記のサイトを参考に再計算させる方法もやってみたのだが、自分の実装方法に問題があるのかもしれないが結果としてはあまり変わりない。
tamanegisoul/ScreenTimeManager

他のアプリだと、実感のずれが少ないアプリがあるので
多分いい方法があるはず

CONFIGURATION_CHANGEは、デバイス構成が変更されたことを示すイベントタイプ。らしい。
多分調べた感じだと、デバイスの回転の時の再起動の事を指しているっぽい


参考サイト:[Android][Lollipop]UsageStatsManagerを使ってみた

調べたらグーグルの方でサンプルを公開しているのを見つけた。
googlesamples/android-AppUsageStatistics

とりあえず、集中力が切れたので
今日はここまで


2018-03-07 到達点メモ


困った。
広告が表示されない。

今までも広告が表示されなかったことはあったのだが
今回は実際の広告ではなくテスト広告が表示されない。
何でだかわからないからなおさら困ってる

参考サイト:クイックスタート
参考サイト:公式ドキュメントのバナー広告の実装の仕方

Required XML attribute "adSize" was missing
てきなエラーも出たがこれは割と対処が楽だった
単にAdSizeの指定をするだけである
というかAdViewはどうもAdSizeの指定はどうも
オートコンプリートが効かないようだ

参考サイト:AndroidでAdMobのネイティブアドを横幅いっぱいに表示する

あと、ads:loadAdOnCreate="true"はもう使えないようなので
設定するとバグる

パッケージ名さえわかれば、アイコンとラベル名が取れるが
ラベル名は、此処で取らずにパッケージ名を取った時に保存して
持ってきた方がよいかもしれない
val icon = packageManager.getApplicationIcon(appPackgeName)
val appInfoList  = packageManager.getInstalledApplications(Context.BIND_AUTO_CREATE)
var labelName = ""
for (ai:ApplicationInfo in appInfoList){
if (ai.loadLabel(packageManager).toString() != null && ai.packageName.equals(appPackgeName)== true){
    labelName = ai.loadLabel(packageManager).toString()
    break
}
}

なんか詰まったので今日はここまで

2018年3月9日金曜日

2018-03-09 到達点メモ


いやぁ、何とかテスト広告が表示されるのは確認した。
というかよく見たらちゃんと載っていましたね
Banner Ads


という訳でやり方を書きます

*飽くまで登録などせずにテストとして広告が表示できるか知りたい場合

//MainActivity

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        MobileAds.initialize(applicationContext, "ca-app-pub-3940256099942544~3347511713");
        adView.loadAd(AdRequest.Builder().build())
    }
}

//activity_main.xml

    <com.google.android.gms.ads.AdView xmlns:ads="http://schemas.android.com/apk/res-auto"
        android:id="@+id/adView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginEnd="48dp"
        android:layout_marginStart="16dp"
        ads:adSize="BANNER"
        ads:adUnitId="ca-app-pub-3940256099942544/6300978111"
        ads:layout_constraintBottom_toBottomOf="parent"
        ads:layout_constraintEnd_toEndOf="parent"
        ads:layout_constraintStart_toStartOf="parent" />

dependencies {
//関係ない部分なので省略
    compile 'com.google.android.gms:play-services-ads:11.8.0'
}

という風に書けば、普通に表示されるはず。
これで表示されない場合は、ログをみれば
場合によってはViewの大きさが足りないというエラーが出ている可能性があるので
それを確認してほしい。


本番の場合
・xmlのadUnitIdとMobileAds.initializeを本番用に差し替える

未確定(以下の設定はもしかするとFireBaseを使う為の設定かもしれない。起動回数が少ないと正しい設定でも本番の広告は表示されないため、まだ確認できていない)
・Manifestファイルに以下の設定を入れる
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
・google-services.jsonをダウンロードする
Admobで登録作業を行い、アプリの設定ボタンをクリックし
アプリの設定画面に遷移する

下の画像のアイコンをクリックする

そうすると以下のようなウィンドウがでるので指示に従った後に
赤線で囲んであるリンクをクリックするとダウンロードが始まる

そして、そのファイルをappディレクトリの中に入れます。
以上で作業は終わりです。

とりあえず、テスト広告を表示できるようになったので今日はここまで

2018年3月6日火曜日

2018-03-06 到達点メモ


Inkscape使うの久しぶりすぎて操作方法を忘れたので
再度纏めなおし。

◎半円の作り方

1.丸を作る
2.直径以上の長さの長方形を作る
3.分割した際に半分になるように長方形を丸の上に移動させる
4.二つのオブジェクトを選択する
5.排他を選択
6.分割を選択
7.不要な部分を削除して、残った部分の大きさを整えれば出来上がり。

もっと簡単な方法がある気がするのでまた今度調べてみる。


◎オブジェクトの回転

自分は最初やった時はなんか色々めんどくさい手順を踏んで回転させたのだが
もっと簡単な方法があった。

1.オブジェクトを作った後に左側にあるツールバーの矢印単体のアイコンをクリック
2.オブジェクトをクリック
3.オブジェクトの周りのアイコンが回転のものになったら、回転したいアイコンをクリックしてドラッグすればよい


◎描画領域の大きさをアイコンに合わせる

1.上のツールバーにある編集をクリック
2.下の方にResize Page to Selectionをクリックする。おわり。




Androidの話に戻るが
ボタンを無効にする(非表示ではない)機能を使いたかったので調べた。
無効化するには以下のようにすればよい
button.isEnabled = false

参考サイト:4.7.押したボタンを無効にする。


SVG取り込みも久しぶりすぎて忘れてた。
まず、XMLへ変換する必要がある。
それ自体はAndroidStudioで出来る。

手順
0.あらかじめ、該当ファイルをアプリのフォルダに入れておくと話が早い
1.drawableで右クリック
2.Newを選択し、その中のVector Assetを選択する



3.Local fileを選択する
4.Pathの ... ボタンをクリックし、対象のファイルを選択する
5.プレビューの内容に問題が無ければFinsihをクリックする。終わり


こうしてできたファイルを読み込もうとしたのだが
何度やっても表示できなかった。
以下のサイトを参考にしてみたが
手順はおかしくないように見える
参考サイト:Android で VectorDrawable を利用する
参考サイト:VectorDrawable対応まとめ
参考サイト:Material DesignのsvgアイコンをAndroid StudioでVector Asset Studioを使ってVectorDrawableのxml形式に変換する方法

なお、幾つかのサイトでbuild.gradleのdefaultConfigの中に
vectorDrawables.useSupportLibrary = trueの記述をしなくても
出来たことを付け加えておきます。


というか、アイコン出なくてimageViewで表示しようとしたら
アプリそのものが落ちた

VoiceTimerのアプリのアイコンは何故か表示できるので
おかしいと思いながら調べてみたところ

ファイルの以下の部分が悪さをしていたようである
少なくとも以下の部分を削除したら動くのは確認できた。
    <path android:fillAlpha="1" android:fillColor="#cccccc"
        android:pathData="" android:strokeAlpha="0.23684214"
        android:strokeColor="#0000ff" android:strokeWidth="2.85714293"/>

恐らくであるが、 android:pathData="" android:strokeAlpha="0.23684214"
此処の部分が悪さをしていたのではないかと思っている。
恐らく削除なりしたデータの消し忘れなのだろうが
困ったことにInkscape上だとこの情報を確認できないので
最終的には、xmlファイルそのものを見る必要がある。

何かそれをやるつもりはなかったのだが凄くアイコンの作成に時間をかけてしまった。
色合いの調整など細かい修正は入れる予定だが大まかデザインはこれになりそう。



しかし、外国の方はこの形で禁止とかの連想は出来るんだろうか…?
といっても他に思い付いたアイコンのデザインが下のやつらぐらいしか
なかったわけであって……。

   

改めて見比べてみると、採用するとしても一番左か、左から二番目のアイコンだなぁ
それらも採用予定のアイコンと比べたらごちゃごちゃしてるし
冷静に考えれば、アイコンの形とアプリの内容を連想しにくいアプリがあると考えれば
このアイコンの形はまだマシなのではないだろうか・・・?

プログラムはあまり進めなかったが
時間がかかりそうなやつの作業は大まかには終えたので今日はここまで。

2018年3月5日月曜日

2018-03-05 到達点メモ


昨日まで、ずっと起動しているアプリが時間になっても
制限表示画面が立ち上がらないというバグがあったが
案外あっさりと対策できた。

方法は簡単で、UsageEventsでアプリの起動ログを取っているのだが
これを10秒から12時間に変更すればいいだけである。
流石に12時間もスリープ無し、アクティビティ移動無しはないと思ったので……

あと、データの先祖返りが起きていたので
それも解決した。

事例を具体的に上げると、ダイアログで時間を設定した後にスケジュール設定アクティビティに戻り、各曜日のON/OFFやリミットフラグのON/OFFといったデータのセーブ処理を挟むことをやると、時間変更前の設定に戻ることが起きた。

原因は、最初アクティビティを起動したときに、データをロードするのだが
ダイアログで時間を保存すると、ダイアログのデータとアクティビティ起動時の
データが一致しない為、最終的に保存されるアクティビティ起動時の
データが優先されるため先祖返りが起きた。

対策としては、パラメーター代入前にデータを再度ロードすればいいだけなのだが
関数にまとめた際にそのままコピペすると同じ名前を再定義することなって
バグのもとになったので今後は気を付けたい。

直近の重要な難所が案外簡単に解決できたので
今日はここまで。

2018年3月4日日曜日

2018-03-04 到達点メモ


DialogFragmentを呼び出す際にOKボタンとCancelボタンを追加したい場合は
        return builder.setTitle("timeSetting")
                        .setView(view)
                        .setCancelable(false)
                        .setPositiveButton("OK", DialogInterface.OnClickListener { dialog, which ->
                        //処理を書く
                        })
                        .setNegativeButton("Cancel",DialogInterface.OnClickListener { dialog, which -> })
                        .create()

画面外タップした際にキャンセル処理を働かせないようにするには
DialogFragmentのbuilderでbuilder.setCancelable(false)にするではなく
DialogFragmentを生成した先で
以下のようにdialog.isCancelable = falseという設定をする
val dialog = SelectTimeDialogFragment()
val args = Bundle()
dialog.arguments = args
dialog.isCancelable = false
dialog.show(fragmentManager,"test")

ちょっとしか進んでいないが今日はここまで



2018-03-03 到達点メモ


日付の処理は下のライブラリを使うのが楽そう(*本格的に使う前の感想)

KotlinMoment

参考サイト:KotlinMomentを使ってkotlinで日付を楽して扱う

というかデフォルトのメソッドに素直に加算する処理と代入する処理を入れてほしいのだが……

上記のライブラリを使うにあたって
日付操作の際に一つ気を付ける点がありまして
var moment = Moment() //2017-11-20-20-30だと仮定する
moment.add(1,TimeUnit.DAYS)
view.text = moment.date.toString

この場合、本来ならば2017-11-21-20-30と出てほしい所を
2017-11-20-20-30と出てしまう。

で、調べてみたところ、どうもaddは本来の変数自体はいじらないようなので
中身自体を更新したい場合は以下のようにする必要がある

moment = moment.add(1,TimeUnit.DAYS)

条件があっているはずなのに、どうやってもうまくいかないので
条件の内容のデータをToastで出力して値を確認したら
今日の日付はそのままなのに分解して再度Date型のデータにまとめたとき
纏めたデータがひと月分進んでいた。

調べたところ、今回使ったライブラリのMoment型は
monthで出力する場合、1~12になり、Date型のmonthは
0~11のようなのである。

今回ずれた原因がそれだった。初めてライブラリに苦しめられた気がする

あと、Dateクラスの比較が分かりにくくてつらかった
正直今も良くわかってない。
ただ比較をするときは

DateA.compareTo(DateB)>0
DateA.compareTo(DateC)<0

とかでやったほうが良いという事だけはわかった。
参考サイト:【Java入門】Dateクラスで日付の比較(compare)まとめ

一先ず、形にはなったが問題が続出して心が折れたので
今日はここまで




2018年3月2日金曜日

2018-03-02 到達点メモ


データロードセーブのテストするときは空データの状態を一度試さないと
特定のデータがある場合は動くが、無い場合は動かないという事が起きる

プログラミングをするうえで、重複内容をメソッドなどで纏めるのもそうだが
正しい名前を付けることを意識しないといけない。
具体的には、リストのインデックスと数字が一緒であれば
Valueとかでよいだろうが、違くなった場合はPositionにしてあげないと
あとで見直したときに混乱するのでないだろうか?

あと、メソッドで複数の処理の動きを持たせるのは
やはりバグの元かもしれない。

具体的には、戻り値でデータの有無の判定とロードしたデータを取得するは
自分の場合ではあるが、バグのもとになった。
冷静に考えて、データ有無の判定はきちんとメソッドで行うようにし
データの取得ができなかった場合は、空データ(名称はこれでいいのだろうか?nullではない)を返すようにした。

あと、メモとして連番でのリストの作り方をメモしておく
素直にレンジをListやArray化みたいなことができれば早かったんだけど
自分の調べた範囲ではわからなかったので以下のようにした。

var list0to23: MutableList<Int> = mutableListOf()
(0..23).forEach {
      list0to23.add(it)
}

しかし、それにしてもいじっていると
最初考えたレイアウトはあんまり使い物にならないなぁ……
割とちょいちょい変更したくなる

まぁ、とりあえず、今日はここまで

2018-03-01 到達点メモ


*Kotlinで開発しています


FragmentClassでcontextを使いたい場合は
*今回の場合はDialogFragment

activity.applicationContext

と宣言すればよい。
api23からならcontextを呼び出せるのだが
それ以前は不可なのでわざわざバージョン別けするぐらいなら
上記のように呼び出した方が明らかに楽である

参考サイト
Android フラグメントでcontextを使用する


ダイアログにデータを渡したい場合

◆渡す方

val dialog = SelectTimeDialogFragment()
val testString = "AAA"
val args = Bundle()
args.putString("testString", testString)
dialog.arguments = args
dialog.show(fragmentManager,"testString")


◆受け取る方

appPackgeName = arguments.getString("testString")


参考サイト
Android DialogFragmentで引数を扱う


今回自作クラスをつくったので
クラス作成時に引数を取りたかったので
調べたところ以下のようにすればよかったらしい

class UserInfoSaveAndLoad(appContext: Context) {
    val applicationContext = appContext
    val prefs = PreferenceManager.getDefaultSharedPreferences(applicationContext)
    val gson = Gson()
    val userInfoString:String? = prefs.getString("TEST", null)
//以下略

別にわざわざinitを宣言しなくても
代入くらいなら普通に上記のようにコンストラクタとして書けるようである

参考サイト:Kotlinでコンストラクタを書く

データの読み書き用の自作クラスを作ったので
割と時間がかかったがとりあえず時間の保存・読み込みができるようにはなった。
使っていてTimePickerが内部の処理的にも、使い勝手的にもめんどくさいので
結局、ライブラリに回帰するかもしれない。

最低限の目標は達成したので今日はここまで。