とりあえず移転してみました

ニュースねたや、IT系の記事を書いていくつもり・・・ですが、どうなるかわかりません。まあ、とりあえず やってみます。

android SQLiteでの重複データの扱い

androidでは、データベースとしてSQLiteが使うことができる。ライブラリを使えば色々なDBも使えるのだけど、それほどデータがない場合などでは、SQLiteで十分でしょう。

今回はまったのは、重複データの扱い。WEBアクセスをした結果を必要な部分だけ抽出してDBに保管するのだけど、毎回データが更新されるわけではないので、同じデータの場合もある。
それをDBには記録させたくない・・・

最初に考えたのは、DB上に同じデータがあるか?比較して、なければ書き込み。あれば何もしないというフロー。

考えただけで大変そうな気がする。そこで、色々と調べてみてもDBによってはMARGEというコマンドとかあるようだけど、SQLiteにはない。
困った・・・

DBにアクセスするのは、レコードを1件ずつ取得するので、レコードの読み込み => データと比較 => 書き込みorそのまま とい処理をレコードの数だけ実行することになる。

DBのテーブル設定で、uniqueを使えば同じ内容の書き込みが制限できるというで、これを活用することにした。実際には、2つの項目が同じ場合は書き込みをしないという設定。

例えば・・・アクセスした人のIDと時間。

create table Table (_id integer primary key autoincrement,name TEXT,time TEXT,unique(name,time))

こんな感じで、テーブルを作成。

nameとtimeが同じ場合は、データへの書き込みが行われなかった。

 

android 今更ながらレイアウトでのweight指定での注意点

レイアウトの作成時に、縦にテキストやらボタンを配置する場合が多い。その場合に、同じようなものであればドンドン配置すればいいのだけど、大きさを変えないとしっくりこない。

LinerLayout(Vertical)を配置して、その中に部品を配置する方法が一番簡単。LinerLayoutの高さを調整すれば、その中の部品の高さも変更できるから。

f:id:imsdJava:20170519111950p:plain
これを使って配置していく

基本の指定方法として、Layout:heightで「match_parent」(最大)か「wrap_content」(最小)の指定が可能だけど、細かい指定ができない。その場合は、Layout:weightで重みつけをすることになる。

ただ・・・ここで注意しなければいけないのは、他のブログとかでも沢山書かれているのだけど、weightで重みをつける場合は「Layout:height」は「0dp」と指定しなければいけない。

f:id:imsdJava:20170519112848p:plain
0dpと指定したうえで重みつけを指定

上の階層のレイアウトに、「weightSum」という項目があるので、weightの合計値を指定しておくと便利。

合計値を10としておいて、

パーツA 1
パーツB 3
パーツC 2
パーツD 4

という感じで指定すると全体のイメージがつかみやすい。
weightの値と、height(高さ)もしくはwidth(幅)を0dpにする。これが必須。

 

android permissionの位置が間違っていた

毎回のように繰り返していますが、今回はリリース用のファイルを作成する段階でエラーが発生。
実機でのテストも問題なかったのに・・・

調べてみるとuses-permissionの位置がよくないっぽい。そこで、manifestファイルを確認してみる。
今回のアプリでは、インターネットアクセスとWi-Fiでのアクセスも使うので、以下の2行が必要になる。

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

記述的には問題ないけど、位置か・・・

タグ内で書いていたのが問題らしい。今まであんまり意識してなくて、うまく行っていたのだろう。
修正したのが以下の内容

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.パッケージ名">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" tools:node="remove" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/Theme.AppCompat.Light.NoActionBar" >

もう1つ問題があって、記述を追加している。アプリを登録する段階で、プライバシーポリシーを表示しないといけないと言われた。
しかし、ユーザー情報に関連するようなパーミッションは設定していないのだが・・・

そこで、新たに追加した

<uses-permission android:name="android.permission.GET_ACCOUNTS" tools:node="remove" />

パーミッションの中で、アカウントにアクセスする部分を削除する記述らしい。これを追加する場合は、以下の記述も追加する。

xmlns:tools="http://schemas.android.com/tools"

プライバシーポリシーの表記を入れればいいのだけど、HPでの表記とアプリ内での表記が必要になるらしい。ユーザー情報にアクセスするこはないんだけどね・・・

 

プログラムの勉強も紙でもいけるよ

こんなブログがあったので読んでみた。

www.tawashix.com

今では、家にPCがあるのは当然で、スマホのほうが身近にあるのでPCを立ち上げなくなったなんて話も聞く。
メールのチェックも、PCをたちあげなくてもスマホでできるし検索もできるので問題はない。

ただ、プログラムを書くとなるとスマホでは限界があるだろう・・・

プログラムを勉強する方法として「ドリル」という方法について書かれていたけど、自分達の世代では当然だった。そう、PCが1人1台ないんだもん。
授業でプログラムの勉強をするにしても、ホストコンピュータが立ち上がるまで待って・・・なんて時代。個人個人でPCがあるのはWindows95が普及しだしてから。

では、それまではどうしていたのか?やっぱり、紙なんです。

もう、35年以上前の話になるとソフトは磁気テープで販売されていたし、プログラムが書かれた本が多く売られていた。それを購入して、自分でその通りタイプするのだ・・・なんてアナログ。

当然、ミスタイプもあるしタイプ抜けなんてのもある。一回でプログラムが動くことなんてない。4,000行くらいのプログラムを打ち込んで動かない・・・

そこから、バグを探すのだけど今時のIDEのようにミスを指摘なんてしてくれない。自分で1行1行確認する。
なんとかバグを修正して、動かしてみると・・・くそゲームだった・・・なんてこともしばしば。

会社に入ってからも、プログラムのやっていた時は、紙にコードを印刷して確認していた。ホストコンピュータに接続されている端末は数が少ないので、ずっと使うことができないので、印刷して確認していた。

面倒なようだけど、これしかなかった。

コードを書くのは最終的な部分で、フローチャートが頭の中で作れないと結局コードは書けない。

プログラムの最初の勉強だって、本を読んで配列とか変数とか分岐とかを勉強する。別にPCなくても勉強はできる。

 

怒りすら覚えてしまう内容だ・・・

昔、少しだけ住んだことのある都市が、移住したい街ランキングなどに入っている場合あるのだけど・・・
田舎暮らしが人気があるようなのだけど、その中でも雑誌などでランキングしていたりするのだけど、住んだ経験があるので凄く違和感を感じてしまう。

少し調べてみても、「う~ん・・・ちょっとね・・・と思ってしまう」というか、怒りすら覚える内容もある。

まず、交通アクセス。
最寄の駅までの時間が書いてある。比較的大きな都市から「特急で」数時間。まあ、これくらいならね・・・しかし、この先が書いていない。特急で数時間乗れば、その街に着くのか?

着くと言えば着く。そう、その街の区域という意味では・・・市の境という意味で。
しかし、街の中心部に行くには、鉄道がないのだ・・・では、バスは???

1時間に1本あるのだろうか?というくらいの感じだ。歩いていける距離ではない・・・(歩けないこともないけど)自転車でも30分くらいかかる。信号の少ない田舎道でだ。

もっと言うと、最寄?の駅に着く特急電車も1時間に1本しかない・・・

田舎暮らしを目的にしている人だから気にしないのでは?と思うのだけど、都会に住んでいて田舎暮らしに憧れてという人だと、この現実を受け止めるのは難しいだろう。

駅からタクシーに乗っても、なかなかの距離だ。問題なのは、更に先にある。中心部に着いても、何もない。まあ、田舎だからね。
でも、移動手段がない。バスなんて、当然ない。地元の人は、当然車がある。

ところが、移住目的で下見に来る人には車なんてないだろうから、途方にくれる。

真実をもっと記載しておけばいいのに・・・電車で来ても移動手段に困るからとか、レンタカーをお勧めするとかね。

教育に力を入れているということも書かれていて、新しい図書館が出来たと綺麗な写真と中の画像があるのだけど、確かに綺麗でいい感じなのだが・・・市内の他の図書館がない・・・新しくした時に、市内の図書館を全部閉鎖したのだろう。

昔利用していた図書館は、公民館に変わっている。

市内に図書館は、1箇所・・・地方自治体の財政が厳しいのはいつものことで、大きな図書館で沢山の蔵書を管理したほうが、サービス的にもいいのは理解できる。ただ・・・この場所は移動手段がないのだ。

都内のように、バスや地下鉄などが充実していない。一番困るのは、年配の方と若者なのだ・・・一番、図書館を必要とする人達が。

近くに大きな本屋もなく、欲しい本も簡単には手に入らなかった。仕入れる本の数も少ないので、発売日から遅れると本がないというのもしばしば。

大きな本屋に行こうとしても、駅は遠い。電車も1時間に1本・・・教育という意味では、経験したものとしては薦めることはできない環境。

本当に住みやすい街だと思っているのだろうか????

 

android 画像などを透過させるには?

相変わらず、ちまちまとやっていますが、今回も少しはまった件。

透過度の指定

androidのレイアウトで、画像などを貼り付けて透過させたい場合や、色をつけて透過させたい場合の自己(事故)メモ
backgroundで色を指定する時には、色指定の段階で「#00000000」のように8桁の数字(16進数)で指定ができる。
色指定の場合は、6桁の数字(RGB)で指定するのだけど、先頭の2桁が透過度を指定している。
「#FF」からはじめると透過度0なので、下が全く見えない通常の塗りつぶし。

「#00」からはじめると透過度100%なので、色指定も意味がない・・・

色指定では、透過度は0から255での指定ができる。

backgroundにリソースとして登録した画像を指定すると画像表示も可能になる。その場合に、画像を透過させたい・・・


ところが、色と違い透過度が指定できないので、「alpha」で指定できるらしい。検索して透過度と同じように0から255が指定できるらしいので、数値を入れても変化がない。
layoutファイル上で指定する場合は、0から1の間で指定するという情報があったので、変更してみるとできた。

layoutファイルの数値に関しては、ビルドの段階でエラーがでない場合が多いので、何が問題なのか?を判断するのが難しい場合がある。

フォルダの作成と画像ソース

androidでは、機種ごとの解像度に応じて、自動的に画像のサイズなどを拡大、縮小してくれるのだけど、あらかじめそれぞれの解像度に合わせた画像を用意する方法もある。
解像度ごとのフォルダを用意して、そこに画像ファイルを入れるのだけど、フォルダを作成しても表示されない・・・

なんじゃこりゃ・・・

f:id:imsdJava:20170509104453p:plain

これは、できたあとの画像。このように、同じ名前のファイルがフォルダごとに存在している。

複数画像の対応については、以下のURLを参照

複数画面をサポートする | Android Developers

f:id:imsdJava:20170509105438p:plain

フォルダ

  • 「drawable-ldpi」
  • 「drawable-mdpi」
  • 「drawable-hdpi」
  • 「drawable-xhdpi」

を作成し、その中に解像度の異なる画像を同じ名前で入れることで、自動的に解像度に応じて表示してくれる・・・らしい。

だが、フォルダが表示されない。

左上のandroidと表示されている部分をクリックし「Packages」を選択すると表示された。
f:id:imsdJava:20170509104503p:plain

この表示に変えてからフォルダの作成、削除とファイルの格納を行うと「android」に変更しても表示されるようになった。
なんか、面倒・・・

「drawable/画像ファイル名」で指定することが可能になる。

解像度ごとの端末の割合についても、以下のURLに情報が。
ダッシュボード | Android Developers

f:id:imsdJava:20170509110242p:plain

解像度については、androidは機種が多いので、どこまで対応させるのか?悩ましいところ。でも、人気アプリでもないので、無問題だろう(泣)

 

ListViewAdapterではまった・・・positionが0のまま・・・

毎回のようにはまってしまう。androidでListViewというリスト形式のものを表示する場合は、ListViewAdapterという便利なものがある。List形式のものを渡せば、表示してくれて件数が多いと自動的にスクロールする機能まで付加してくれる。

使わない手はない。

難しいコードはないのだけど、はまってしまった。

ArrayAdapterを継承したカスタムクラスを作成し、以下のコード内でリストを表示する。

@Override
public View getView(int position, View convertView, ViewGroup parent) {
        CustomData item = (CustomData) getItem(position);

        if (null == convertView) {
            convertView = layoutInflater_.inflate(R.layout.listdata, null);
        }

CustomDataも独自クラスで、このクラスを使うことで色々な形式のデータを使うことができる。ArrayListとかでもいいけど、CustomDataクラスを作ることで、画像(アイコン)や文字などを一緒に使うことができる。

実行する側の処理も書いて、実行してみると1行しか表示されない・・・ここから色々とデータを確認する。
そもそも、渡しているデータが1行なのか?渡している形式が問題なのか???
など問題となりそうな事を想定して、実行中のデータなどを確認してみても、データがちゃんと数件分渡っている。データが確認できるということは、形式の問題でもない。

なんだろう・・・・

実行中の状態で確認すると、positionがずっと0のままで変化しないのだ。それでは、1件しか表示されないわけだ。本来は、データの件数に応じて、0から加算されないといけない。



問題なのは、getViewメソッド内のpositionの値。

ではやはり、受け取ったデータの件数が少ないのか?そこで、getcount()とメソッドで件数がちゃんと認識できているのか確認するとちゃんとデータ件数の数字と合っていた。

わけわかめ・・・」となって、ネットで検索してみると、ListViewの表示側の問題という内容が。
つまり、コードの中の話ではなく、レイアウトを形成しているxmlファイルのほうだと。表示サイズが最小だと表示できないとかなんとか。

そこで、レイアウトファイルを変更して、最大と指定すると・・・表示された・・・

なんだかなー・・・件数分を取得して、表示が1行分しかないとかなら理解できるけど、データも取得できないって・・・わからん。

実際には、Activity ==> TabLayout ==> PagerAdapter ==> FragmentManager ==> Fragment ==> ListView ==> ListViewAdapter という形で表示する。
Activityで取得したデータをListに表示するだけで、これだけデータの受け渡しが発生してしまう。

ここでも、色々と時間がかかってしまったで、後日まとめよう・・・