寒川アクアブログ

美容師しながらアプリ開発していて水草が趣味の私のブログです

APIレベルを取得する(処理を分ける)

APIレベルによって処理を分ける方法です。

APIレベルを取得する

わずか一行で取得可能です。

int apiInt = Build.VERSION.SDK_INT;

OSのAPIレベルを整数値で取得できます。



各レベルは、コードネームの定数で定義されています。

Build.VERSION_CODES.LOLLIPOP

同様に、APIレベル19は、 KITKAT
11は、 HONEYCOMB
等があります。
あとでコードを見渡した時に、ただの整数よりも間違いが起こりにくいはずです。


OSのバージョンによって処理をわける

上記をif文で評価することで、簡単に処理を分岐できます。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    //    Do something
};

たとえば、シークバーのツマミの色を変えるメソッドはAPIレベル21以上でしか使えません。
キットカット以下の、より多くの端末に対応するには上記の分岐処理が必要です。

◆AndroidStudio◆メモリを2G→4Gにした結果

アンドロイドスタジオがいい加減重いと感じたので、

 

メモリ増設を決断しました。

 

 

 

メモリ増設なんてやったことなかったので、不安でしたが、

 

スマホでいろいろ調べてみると、

 

意外と敷居が低そうなので、やってみることに。

 

 

まずPCのマニュアルから、適合するメモリの型と、

 

最大積載量を確認。4Gとのこと。

 

 

4Gかぁ、なんかショボそうだなと思いつつ、

 

でも今の2Gの2倍だから結構変わるであろうと。

 

 

ちなみに私のPCはデルのノートのvistaインテルコア2です。

 

・・・ちなみに未だにvista使ってると言うとだいたいみんな笑います。

 

いいんです。慣れた環境が落ち着くのです。

 

ヘタにアップデートしたりすると、それに慣れるまでに時間を要しますし、

 

スタジオとの相性や、操作性で不便なところがでちゃうとイヤだからです。

 

とはいえ、この世の中は環境適応性が大事なので、

 

ずっと同じ環境に落ち着きすぎるのも、それはそれで不安になります。

 

 

逸れましたね。

 

 

まずメモリを購入。

 

アイバッファロー製の2Gを2つ、合計一万円ちょっとでした。

 

意外と安い。

 

 

そして、はやる気持ちを抑えながら増設作業へ。

 

まずノートパソコンをひっくり返します。

 

バッテリーを外します。

 

フタっぽいやつのネジをはずす、ここは精密ドライバーがあったほうがいい。

 

(細かい手順は、写真付きの他のサイトさんに委ねます、

 

絶対そのほうがいい。リンクすら貼らなくて申し訳ありません)

 

 

既に装着されているメモリを外す。

 

静電気とか怖かったので、一応手を洗って、よく拭きました。

 

ガソリン入れる時も、あの黒いやつをしっかり触る人です。

 

外し方は参考にしたサイトさんに載ってなかったが、

 

両側のつまみを広げたら簡っ単に取れました。

 

 

新しいメモリをはめる。ナナメに入れて、水平にカチッとやる。

 

てこの原理でメモリが割れるのではと思ったがその心配は無用でした。

 

 

電源オン!

 

しばらく待って、いつものデスクトップへ。

 

ちゃんと認識され、4Gになっていました。

 

(ちなバッファローのメモリは、認識されなかった場合の補償がついているので安心です)

 

 

さっそくアンドロイドスタジオを立ち上げてみます!

 

起動の時間はそれほど変わりませんが、

 

体感的に、

 

かなりサクサクですね!

 

 

以前が重すぎたってのもあるでしょうけども。

 

プロジェクトストラクチャーを開くのに一分くらいかかっていましたから。

 

開発中にメモ帳を開くのにも、応答なし→やっと開く、って感じでしたが、

 

わりとすぐに開いてくれます。

 

 

かなりストレスが軽減されますね。

 

 

開発歴は一年ちょっとですが、

 

だいぶコードもすっきり書けるようになり、

 

ぐぐる、悩む、時間が減り、

 

開発スピードが上がってきます。

 

そこに、開発環境の遅さはブレーキになってしまうので、

 

なにかとストレスになっていましたが、

 

これでだいぶ快適になりました。

 

 

4Gで満足しています。

 

16Gとかってどんな世界なんだろうな・・・

 

サウンドピッカーを呼び出して着信音等を取得する

着信音や通知音を取得できるサウンドピッカーを呼び出す方法と、その結果の受け取り方

黙示的インテントから、サウンドピッカーを呼び出します。
Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT,false);
startActivityForResult(intent,REQUEST_CODE_RINGTONE_PICKER);

(REQUEST_CODE_RINGTONE_PICKERは、任意の定数です。)

これを実行すると、サウンドピッカーが現れます。
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT,false);
このコードは、”サイレント”をリストに表示するかどうかをboolean型で指定します。
falseにすれば、リスト上に表示されません。
”サイレント”(端末によっては”設定しない”などと表示される)が選択された場合、
アクティビティリザルトのdataがnullになるので、エラー回避の記述を加える必要があります。
ユーザビリティや、開発しているアプリの用途に合わせて振舞いを選んでください。

サウンドピッカーからの結果を受け取る。
@Override
protected void onActivityResult(int requestCode,int resultCode,intent data){
	if (requestCode == REQUEST_CODE_RINGTONE_PICKER){
            if (resultCode == RESULT_OK){

                Uri uri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
                Ringtone ringtone = RingtoneManager.getRingtone(this,uri);
            }
        }
}

onActivityResultをオーバーライドして、返り値から、目的のオブジェクトを取得していきます。
例では、着信音です。
dataからユーザーによって選択された着信音のUriを取り出し、
それを引数にRingtoneのインスタンスを取得しています。


これで、すぐにでも音を鳴らすことができます。

独自の操作性を追求するのでなければ、
データベースやカーソルを駆使するよりも、
サウンドピッカーを利用した方がはるかに簡単だと思います。

また、サウンドピッカーから、SDカード内のデータを取得できるようにする場合は、
マニフェストに、SDカードにアクセスする権限を加える必要があるのでご注意ください。

アニメーションさせる(Canvasを使ったゲームなど)

 パズルゲームなどで、タイルを動かした時に、瞬時に移動するのではなく、
滑らかにアニメーションしながら移動したい。
 なおかつ、端末の処理速度などによって、早くなったり遅くなったりせず、どのような端末でも一貫した動きが欲しい。

 そのような機能を求めるときは、ValueAnimator が、汎用性も高く便利です。


ValueAnimatorの使い方の流れです。
ValueAnimator animator = ValueAnimator.ofFloat(0.0f,1.0f);

animator.setDuration(1000l);

animator.setInterpolator(new AccelerateInterpolator());

animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {

               float value = (float)animation.getAnimatedValue();

                invalidate();

            }
        });

animator.start();


ValueAnimatorをインスタンス化します。
パラメーターで、初期値と、変化後の値を設定します。

例では、float型で、0.0から1.0まで変化するアニメーションです。

setDuration(1000l)は、何ミリ秒間かけて変化させるか、を設定します。lは、long値であることを明確にしています。

setInterpolator(new AccelerateInterpolator())は、変化の仕方のバリエーションを指定します。
コードから記述するときは、このように匿名クラスを引数にしています。
AccelerateInterpolatorは、徐々に加速していくアニメーションです。
インターポレーターには、引っ張って離すようなものや、終着点でバウンドするものなど、様々な種類があります。


他にも、ディレイをかけたり、繰り返しを指定するメソッドがあります。


start()を呼び出すとアニメーションが開始されますが、
内部的に数値が変化しているだけで、見た目には何も変わりません。
変化した値を取得し、パズルのタイルの位置や、飛んでいる玉の座標に適用する必要があります。

animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                
                float value = (float)animation.getAnimatedValue();

        //    valueを使って何かをする

                invalidate();

            }
        });


値が変化するたびに呼び出されるリスナーをセットします。

float value = (float)animation.getAnimatedValue();

で、値を取得します。今回はfloat型のアニメーションを定義したので、float型にキャストします。
ここで得られた値を、動かしたい対象の座標などに適用して、

invalidate()で、onDrawを発生させます。
先ほどの値のぶんだけ動いたアニメーションが実現されます。

start()を、最後に忘れないで下さいね。


注意すべきことは、0.0から1.0までの間の、全ての値が順番に呼び出されるわけではありません。
例えば、0から360の整数値で変化するアニメーションの場合、180を踏まないこともある、ということです。

アニメーションの終了を検知
    animator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
                
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                
                
            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });
        animator.start();

アニメーションの各ポイントで呼び出されます。

パズルのタイルが動いている間は、タップを受け付けない、など、
アニメーションが一通り終わるのを待たせたいとき等に便利です。

このリスナーを登録するときは、start()の前に行うことにご注意ください。



 ValueAnimatorは、ユーザーの操作のレスポンスにも向いているので、
そこまでリアルタイム性のないゲームではかなり重宝されると思います。
とくに0.0fから1.0fへの変化のアニメーションは、とても汎用性があります。
色を変化させるアニメーションもあります。
変化量を自力で計算するのは非常に大変なので、活用の場は多そうです。


 最後に宣伝っぽくなってしまいますが、
このValueAnimatorをふんだんに使ったシンプルなパズルゲームを作りました。
動き一つひとつに補間のモーションが付与されることによる視覚的な効果を実感いただけると思いますので、
よかったらチェックしてみてください!
play.google.com

f:id:kentaro198477:20160520093118p:plainf:id:kentaro198477:20160520093112p:plain

サイズをdp(dip)で指定する

ピクセル密度が異なる端末でも、対象の図形やビューをおおかた同じ大きさで表示させるには、dp値を指定します。


dp(dip)についての詳細は、ここでは省略させていただきます。

dp値から、実際のピクセル数を求める

ピクセル = getDisplayMetrics().density * (dpで指定したお好きな値);


getDisplayMetrics().densityで、倍率を取得できるようなので、dpで指定した任意の値に掛けてやることで、ピクセル数を取得できます。必要に応じて(int)にキャストします。


意外と、単純明快でわかりやすかった。


アクティビティの外から呼び出す場合は、

getResources().getDisplayMetrics()

たとえば、ゲームアプリを開発している際、ゲーム画面は画面を大きく使いたいけど、指で押すボタンは一定のサイズに固定したいとき、dpで指定することで、「小さすぎて押せない」、「大きくてかっこわるい」などが防げそうです。

また、マテリアルデザインのガイドラインではdp値が細かく決められているので、活用する機会は多そうです。

FREETEL MIYABI(雅)のレビュー

FREETEL MIYABI(シャンパンゴールド)を買ったので、さっくりとレビューします。

いいところ
  • SIMフリーであること

 当然といえば当然なんですが、なんといってもSIMフリーであることです。
大手三社以外の電話会社が選べるので、中にはとても安いところもあります。
私はフリーテルの回線にし、月額990円~というプランを利用しています。
*ここではレビューなので、”SIMフリーとはなにか”については記述しません。
**世の中には安かろう悪かろうという言い回しがありますが、フリーテル回線で多少トラブルがありました。後半で記述します。

 購入後に、某家電評価雑誌で、このMIYABIがコスパNo.1と掲載されていたのを知り、少しどや顔ができました(笑)。
 端末本体が2万円であること。大体のスマホ本体は6万以上はするのではないでしょうか。
ただ、月々割り等で端末代が実質0円だとあまり実感が無いですが、2年縛りがなく、買い切りで2万円はうれしいです。
 

  • 軽い

 店頭で持った時に、まず驚いたのがこれです。モックかと思うくらい。
他人に持ってもらうと、第一声はほぼ「軽っ」です、
寝ながら動画を見たりする時には疲れにくくて良いと思います。
ただし、この軽さは、すぐに慣れます。

  • タッチ感度が良い

 操作はまったく問題がないうえ、手袋モードという機能もあります。
これをオンにすると、バスタオルの上からでも操作ができました!
あまり使う機会はなさそうですが。

  • カメラのシャッターが速い

 カメラのシャッターを切ってから、次の写真を撮れるようになるまでが速いです。
ただしこれは光量がじゅうぶんの時に限られ、ナイトモード時等では一般的な速さです。

悪いところ
  • 背面のカバーがすぐ壊れそう

 背面カバーは一枚のプラスチックで、下部の隙間に爪などを引っ掛けて外します。
装着するときはパチッパチッと押し込む感じですが、ショップの店員さんもSIMカードを入れる際、けっこう苦戦しているようでした。SDカードスロットもこの中にあります。
あまり頻繁に脱着しないほうがよさそうです。

  • ケースが売ってない

 普段アンドロイドを使っている方は慣れっこかもしれませんが、やはりケースは少ないです。
雑誌掲載を機に普及してくれることを期待します。

  • 内臓マイクの音質は良くない

 音楽をやっているので個人的に残念だったのが、音声レコーダーで録音したときの音質が悪いということ。カラオケでは、聞きとるのには問題ないものの、大きい音だと割れてしまいます。クリアな音質とはお世辞にも言えません。
会議などの録音では問題ないレベルです。

  • 既存アプリのアイコンデザインが古くさい

 電話、カレンダー、ギャラリーetc、既存のアプリのアイコンは、アンドロイド2.x系風の、少し古い感じがするデザインです。フリーテルの半額でんわのアイコンも然り。

  • イヤホンジャックとUSBジャックの距離が近い

 それぞれ同時に差すとお互いの距離が2ミリくらい。
ゴツめのイヤホンジャックだと干渉してしまうかもしれませんが、一般的なイヤホンなら問題ないでしょう。「なんか近いな~」くらい。私は、個人的に好きな設計ですが。

微妙なところ

 あえて言うなら、という感じのところです。

  • 名前は和だけど、端末は普通

 外箱はコンパクトで、かなり「和」を全面的に打ち出している(開ける時のわくわく感は大☆)ものの、端末デザインの「和」感は薄い。
(購入したのはシャンパンゴールド)
背面に、日の丸を連想させるような赤いロゴ、その下にアルファベットでFREETELとあり、パっと見、「郵便局っぽい」感じがしていました。ただしFREETELをよく見ると、意外と凝ったフォントということに気づき、今では気に入っています。


 好きなSIMを選べて、会社によっては基本料金をかなり安く押さえられるSIMフリー端末ですが、フリーテルのSIMを使っていてトラブルがありました。
 前半で触れましたが、フリーテルの回線はNTTの回線を借りて運営されているようですが、安定性という意味ではやはり大手に劣る部分があります。
自宅でwi-fiを使い、そのまま外出したとき、通信が全く繋がらないことがありました。LINEのやりとりもできません。
いろいろ試してみて、機内モードをオン→オフと切り替えたら復帰しましたが、これにすぐに気づかず、結局待ち合わせに20分遅れてしまいました。
 3月23日にフリーテルの回線でデータ通信障害があったようで、フリーテルからその旨のメールが届いています。誠意が感じられる内容です。今後改善されることを期待します。

FREETEL SAMURAI MIYABI 雅 フリーテル (シャンパンゴールド)

FREETEL SAMURAI MIYABI 雅 フリーテル (シャンパンゴールド)


 

NotSiblingエラー

is not a sibling in the same relativelayout [NotSibling]のようなエラー文が出た場合の対処方法

 アプリケーションのAPKファイルを作成する際に、上記のようなエラーが発生しました。
原因としては、レラティブレイアウトの相対関係において、基準となるビューの参照先が見当たらないときにエラーになるようです。

たとえば、レイアウトxml内に、android layout_adove = "@+ID/〇〇〇"と記述したが、
@+ID/〇〇〇がレラティブレイアウトの外に配置されていた場合にエラーになります。

対処法ですが、android layout_adove = "@+ID/〇〇〇"の部分を削除するか、
ルールに従って参照先のビューを配置します。

デバッグの時に問題なく動作し、ビルド時のみエラーになるのであれば、
上記の1つめの方法で大丈夫だと思います。


 やっと完成~。という時にこのようなエラーメッセージは、精神面によくありませんね。
デバッグ時に警告してほしいものです。。。