Android

久しぶりにAndroid開発したらAndroidStudioになってた。

Activityライフサイクル

  • onCreate()
  • onStart()
  • onResume→onSaveInstanceState()→onCreate→onRestoreInstanceState()
  • onPause()→onResume()
  • onStop()→onRestart()→onStart()
  • onStop()→onCreate()
  • onDestroy()

Fragmentライフサイクル

  • onAtach()
  • onCreate()
  • onCreateView()
  • onActivityCreated()
  • onStart()
  • onResume()
  • onPause()
  • onStop()
  • onDestroyView()→onCreateView()
  • onDestroy()
  • onDetach()

4.4.2

バグ
Intent.FLAG_ACTIVITY_REORDER_TO_FRONTを使って、startActivityするとホームボタンと同じ挙動になる?

バージョン違い

インターネット接続処理を作成したら、Android2.3だと問題なかったのだが、
Android4で実行したところエラーが発生した。
どうやら描画スレッドで時間のかかる処理はNGとするようになっているみたい。
本来なら別スレッドで動かしてうんぬんする必要があるのだが、
とりあえず、動作確認するだけなら以下の一文を追加すると制限が解除されるようなので、
onCreate()に追加して試したところ、エラー無く動いた。


StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().permitAll().build());

カメラ

Android2.2まではCamera.open()だけでしたが、
Android2.3からは複数カメラに対応しているので、
Camera.open(),Camera.open(0),Camera.open(1)が使用できる。
NEXUX7ではCamera.open()を使用するとnullが返却されるので、
Camera.open(0)を使用しないとカメラが取得できない。
なので、自分のアプリではAndroid-8からAndroid-9をminSdkVersionにする。

メニューボタン

Android3.0から物理的なメニューボタンがなくなった。
Manifest.xml
をandroid:targetSdkVersion="10"
に設定

プロジェクト構成

私の開発環境では、一つのアプリにつき、以下のプロジェクトを用意します。
hogehoge(メインアプリ)
hogehoge-foc(広告設置無料アプリ)
hogehoge-pay(有料アプリ)
hogehoge-test(テストケースなど)
Android consoleからアプリを公開すると、
一度無料に設定したアプリは有料に変更できないと説明にあるので、
有料バージョンと無料バージョンでプロジェクトを分けます。
でも共通のアプリは一つのプロジェクトです。
また、広告設置無料アプリの場合は、広告会社のライブラリを取り込む必要があるのですが、
有料アプリの場合は広告会社のライブラリを取り込みたくありません。
どうしているかというと、メインアプリ内部でフラグを用意し、
フラグを判定してリフレクションを用いて広告Viewをインスタンスしています。
i-mobileの場合は、以下のメソッドを用意しました。


    /**
     * 広告表示用の処理
     */
    @SuppressWarnings("unchecked")
    private void advertise() {
        try {
            //クラス
            Class<View> classObj = (Class<View>) Class.forName("jp.co.imobile.android.AdView");
            //メソッド
            Method createMethod = classObj.getMethod("create",
                                                  new Class[] {Context.class, int.class, int.class });
            //インスタンス生成
            Object adView = createMethod.invoke(classObj, this, Integer.valueOf(<メディアID>), Integer.valueOf(<スポットID>));

            //高さ設定
            DisplayMetrics metrics = new DisplayMetrics();
            ((WindowManager) this.getSystemService(Context.WINDOW_SERVICE))
            .getDefaultDisplay().getMetrics(metrics);
            int height = (int)(50 * metrics.density);

            //レイアウト設定
            LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, height);
            ((LinearLayout)findViewById(R.id.rootLayout)).addView((View)adView, 0, layoutParams);

            //処理開始
            Method startMethod = classObj.getMethod("start", (Class<?>)null);
            startMethod.invoke(classObj, (Object[])null);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }

テスト

大抵の場合は試験をする際にUSBでAndroid端末を接続して、直接確認します。
ですが、実際にリリースしてみると動かない場合がありました。
リソースの各プロジェクト間の参照の関係ですが、注意が必要です。

広告

i-mobileとかadMovとかある。

Android SDK Manager

SDKのアップデートがうまくいかないときは、管理権限でプログラムを起動すると、うまくいきました。
eclipseも管理権限で実行するほうが安全。

api level 19 以降はswitch String, try sourceが使える?

ダウンロードについて

DownloadManagerは内部ストレージにダウンロードできない。 内部ストレージにダウンロードする場合はHttpURLConnectionとかで頑張る。

アプリアップデート

方法は2つ、ダウンロードして、パッケージマネージャでインストールする。この場合はインストール確認ダイアログが表示されて、タップしないとインストールできない。
もう一つは、DeviceOwner権限を付与してサイレントインストールする。PackageInstaller.createSessionなど。ただし試したところ自分自身のインストールをすると強制終了した。
とりあえず、AlermManagerで再起動する。

DeviceOwner権限

NFC端末から初期設定時にインストールと付与が可能、ただしRC-S380を購入して気が付いた、試用端末にNFCがない。。
結局adbコマンドでDeviceOwner権限を付与した。

adb shell dpm set-device-owner com.uchicom.receiver.dev/com.uchicom.receiver.HogeDeviceAdminReceiver
  • Android5.0から使える
  • 1端末につき1アプリしか付与できない。
  • adb及び端末初期化時の特殊な方法でしか付与できない。
  • APIを使って解除可能

Dialogのフルスクリーン化

画面をフルスクリーン化しても、ダイアログを表示するとナビバーが表示される。以下で対処可能。(参考サイト)


        Dialog dialog = new Dialog(context);
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(R.layout.layout_dialog);
        dialog.setCancelable(false);
        //フォーカスなし
        dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);