20190530のAndroidに関する記事は6件です。

Unityを使ったMultiple APKのやりかた

Multiple APK とは

App Bundleより昔にあったやりかたで、
API levelやCPU architectureなどでインストールするAPKを切り替えることができる機能のこと。

基本的にはApp Bundleで十分なので使用する必要はない。
しかし、プラグインの事情など特別な理由によりAPKファイルを切り替えたい時に使用できる。

前提知識

Google Play Consoleにアップロードするため、リリースのやり方は別途調べておく必要がある。
- 私は https://qiita.com/tsucchi13/items/11b3d9c8f99ceedb4b47 を参照しました。

手順

  1. Player Settings - Android - Publishing Settings を設定しておく
  2. Player Settings - Android - Configuration を変更する
  3. Player Settings - Android - Identification - Bundle Version Code を被らないように変更する
  4. apkを出力し、必要な分だけ2に戻る
  5. Google Play ConsoleにすべてのAPKファイルをそれぞれアップロードする image.png
  6. 公開する

要点

インストール時に使用されるAPKファイルは以下のように選択されるようなので、そこで制御を行う。
事実上、複数のAPKファイルさえ用意できればBundle Version Codeを管理できさえすれば、他には何もする必要はない。
(パックするツールがあるのかと探したが、その必要がなかった)

  1. 該当の端末で使用できるAPKファイルをフィルタリングする
    • API levelやCPU architectureなどでフィルタリングされる
  2. フィルタリングされたものの中でBundle Version Codeが一番大きいものが採用される
    • そのため、下位互換のあるもの(ARM64がARMv7のものを実行できるなど)については優先するものほど大きい値にする必要がある
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

#>>Love Problem Specialist,hus/wife,Health,Job,..Gf/Bf{ Rslt^100%}>>(+91-7837546443) in INDIA/CANADA

>>Love Problem Specialist,hus/wife,Health,Job,..Gf/Bf{ Rslt^100%}>>(+91-7837546443) in INDIA/CANADA

>>Love Problem Specialist,hus/wife,Health,Job,..Gf/Bf{ Rslt^100%}>>(+91-7837546443) in INDIA/CANADA

>>Love Problem Specialist,hus/wife,Health,Job,..Gf/Bf{ Rslt^100%}>>(+91-7837546443) in INDIA/CANADA

>>Love Problem Specialist,hus/wife,Health,Job,..Gf/Bf{ Rslt^100%}>>(+91-7837546443) in INDIA/CANADA

>>Love Problem Specialist,hus/wife,Health,Job,..Gf/Bf{ Rslt^100%}>>(+91-7837546443) in INDIA/CANADA

>>Love Problem Specialist,hus/wife,Health,Job,..Gf/Bf{ Rslt^100%}>>(+91-7837546443) in INDIA/CANADA

>>Love Problem Specialist,hus/wife,Health,Job,..Gf/Bf{ Rslt^100%}>>(+91-7837546443) in INDIA/CANADA

>>Love Problem Specialist,hus/wife,Health,Job,..Gf/Bf{ Rslt^100%}>>(+91-7837546443) in INDIA/CANADA

>>Love Problem Specialist,hus/wife,Health,Job,..Gf/Bf{ Rslt^100%}>>(+91-7837546443) in INDIA/CANADA[uploading-0]()

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

react nativeで日本語が見切れてしまう

react nativeを0.59.8に、android SDKを28にあげたら文字が見切れるようになってしまいました。

App.js
<View>
    <View style={{ borderWidth: 1 }}>
        <Text>aaaaaaaaaa{"\n"}aaaaaaaaaa{"\n"}aaaaaaaaaa{"\n"}aaaaaaaaaa</Text>
    </View>
    <View style={{ margin: 10 }} />
    <View style={{ borderWidth: 1 }}>
      <Text>ああああああああああ{"\n"}ああああああああああ{"\n"}ああああああああああ{"\n"}ああああああああああ</Text>
    </View>
</View>

before.png
英語も日本語も4行表示してますが日本語の方は4行目が切れてしまってます。
バージョンを上げる前は問題なかったのに…
ちなみにiOSはちゃんと4行表示されてました。

早速react nativeのissueを漁ると……ありました。
https://github.com/facebook/react-native/issues/24465

どうやらマルチバイト文字のlineHeightがおかしいらしい。
コメント通りにlineHeight: fontSize*1.5を設定してみると…
after.png
ちゃんと4行表示されました。
iOSでも確認しましたが表示に変化はありませんでした。

バグとして認識してもらってるので後々修正されると思いますが、それまではこれで回避することにします。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

最速で使うFlutter(Ubuntu編)

概要

とりあえずFlutterを使ってみたい方向けのシンプルな解説です。

できること

  • Flutterの導入
  • Android端末上でのシミュレート

Flutter(フラッター)は、Googleによって開発されたフリーかつオープンソースのモバイルアプリケーションフレームワークである。(Wikipedia)

公式ドキュメントを参考にしています。
英語が出来る方は、公式のドキュメント(Get started)を見たほうが早いです。

環境 :
ubuntu 18.04
AndroidStudio インストール済み

シミュレートには、Androidの実機が必要です。買いましょう…

1.インストール

1-1.ダウンロード

公式サイトからダウンロードし、解凍しましょう。
https://flutter.dev/docs/get-started/install/linux

 cd ~/development
 tar xf ~/Downloads/flutter_linux_v1.5.4-hotfix.2-stable.tar.xz

1-2.pathを通します

export PATH="$PATH:$HOME/development/flutter/bin"
source ~/.bashrc

1-3.ネット環境が不安定な方は実行してください

通常は要らないです。

 flutter precache

1-4.依存関係の確認をします

flutter doctor

lib32stdc++6とライセンスへの同意が必要です。以下のコマンドを実行してください。

sudo apt install lib32stdc++6
flutter doctor --android-licenses

1-5.AndroidStudioの設定

Android Studioを起動し、Android Studio Setup Wizardを完了させてください。

1-6.Androidデバイスの設定

開発者向けオプションからUSBデバッグを有効にします。
以下のコマンドを実行し、デバイスが正しく接続されていることを確認してください。

flutter devices

2.エディタの設定

拡張機能/プラグインを追加する必要があります。

VScodの場合:拡張機能からFlutterを追加
AndroidStudioの場合:プラグインからFlutterとDartを追加

3.アプリを作成しよう

今回はAndroidStudioを用います。

3.1 プロジェクトの作成

ファイル > 新規 > New flutter Project
Flutter Applicationを選択します。

Flutter SDK pathを以下のように設定します。

/home/[user]/development/flutter

Runをクリックし実行してみましょう。

Screenshot_20190530-122808.png

できました。

3.2 ホットリロード

Flutterの特徴の一つでもあるホットリロードを試しましょう。

lib/main.dart を開きます。
92行目にある

'You have pushed the button this many times'

を以下のように変更しましょう。

'You have clicked the button this many times'

Screenshot_20190530-123133.png

このように即反映されます。

3.3 プロファイルの方法

*ホットリロードやデバッグモードとは併用出来ません。その分、滑らかに描画できます。

flutter run --profile

4.アプリ作成のガイド

最速で使うFlutter(アプリ作成編) Part1

間違いがあったら教えてください><
最後まで、ありがとうございました。さようなら〜

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Dagger2についてメモ

Dagger2とは

依存性注入フレームワークのこと。

内容

自身の理解のために、公式ページの以下の内容を荒く訳してます。
https://dagger.dev/users-guide.html

  • Declaring Dependencies
  • Satisfying Dependencies
  • Building the Graph

@Injectアノテーションについて

Daggerがクラスのインスタンスを作成するために使用するコンストラクタに@Injectアノテーションを付与する。新しいインスタンスが要求される際に、Daggerは要求されたパラメータを取得し、このコンストラクタを呼ぶ。

class Thermosiphon implements Pump {
  private final Heater heater;

  @Inject
  Thermosiphon(Heater heater) {
    this.heater = heater;
  }

  ...
}

Daggerは@Injectが付いたフィールド変数に直接注入する。
この例では、フィールド変数のheater、pumpにHeaterインスタンスとPumpインスタンスを注入する。

class CoffeeMaker {
  @Inject Heater heater;
  @Inject Pump pump;

  ...
}

@Provides@Moduleについて

デフォルトでは、Daggerは要求された型のインスタンスを構築することで各依存関係を満たす。
しかし、@Injectはどこでも使えるわけでない。

  • インタフェースは構築できない
  • サードパーティのクラスはアノテーションを付与できない
  • 設定可能(Configurable)なオブジェクトは設定していなくてはいけない

これらのケースでは@Providesアノテーションを付与されたメソッドを使う。
返り値の型は依存関係を満たすものを定義する。
例えば、provideHeater()はHeaterが要求された時に呼ばれる。

@Provides static Heater provideHeater() {
  return new ElectricHeater();
}

@Providesメソッドは自身が依存関係を持つことを可能にする。
以下は、Pumpを要求された時にThermosiphonを返すメソッド。

@Provides static Pump providePump(Thermosiphon pump) {
  return pump;
}

全ての@Providesメソッドはモジュールに所属しなければならない。
モジュールとは@Moduleアノテーションを付与したクラスのこと。

@Module
class DripCoffeeModule {
  @Provides static Heater provideHeater() {
    return new ElectricHeater();
  }

  @Provides static Pump providePump(Thermosiphon pump) {
    return pump;
  }
}

@Componentについて

@Inject@Providesが付与されたクラスは、それらの依存関係がリンクされたオブジェクトのグラフを形成する。
アプリケーションのメインメソッドやAndroidアプリケーションのようなコードを呼び出すものは、明確に定義された一連のルートを介してグラフにアクセスする。
Dagger2では、その一連は引数を持たないメソッドを持つインターフェースによって定義され、望む型を返す。そのようなインターフェースに対して@Componentアノテーションを付与し、modulesパラメータに対して必要なモジュールクラスを渡す。
Dagger2はそのインターフェースを実装する。

@Component(modules = DripCoffeeModule.class)
interface CoffeeShop {
  CoffeeMaker maker();
}

その実装はDaggerの接頭辞を持つインタフェースと同じ名前を持つ。
実装上ではbuilder()メソッドを呼ぶことでインスタンスを取得し、返されたbuilderを使い、依存関係をセットし、新しいインスタンスをビルドする。

CoffeeShop coffeeShop = DaggerCoffeeShop.builder()
    .dripCoffeeModule(new DripCoffeeModule())
    .build();

デフォルトコンストラクタでアクセスできる全てのモジュールはもし何も設定されていなければビルダーが自動的にインスタンスを構築するので削除できる。
モジュールの@Providesメソッドが全て静的なら、その実装はインスタンスを全く必要としない。
もし、ユーザーが依存関係インスタンスを作成することなく、全ての依存関係が構築できるなら、生成された実装にはcreate()メソッドが用意される。これを使用し、ビルダーを処理せず新しいインスタンスを取得できる。

CoffeeShop coffeeShop = DaggerCoffeeShop.create();

CoffeeAppは注入されたCoffeeMakerを取得するためにCoffeeShopのDaggerに生成された実装を使用できる。

public class CoffeeApp {
  public static void main(String[] args) {
    CoffeeShop coffeeShop = DaggerCoffeeShop.create();
    coffeeShop.maker().brew();
  }
}

グラフが構築され、エントリポイントが注入されたので、Coffee Maker Appが実行できる。

$ java -cp ... coffee.CoffeeApp
~ ~ ~ heating ~ ~ ~
=> => pumping => =>
 [_]P coffee! [_]P

以上です。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ViewPagerとPagerAdapterでスワイプビューを作ってみる

内容

ViewPagerをとPagerAdapter使って、右に左にひゅいっとスワイプして遷移するビューの練習です。
Tabによる遷移も加えておきました。

作るもの

すごく単純。ネズミさんから始まりイノシシさんで終わります。
数字の表示が崩れているのはご勘弁を。
zodiac.gif

ポイント

ViewPagerとTabLayoutを定義

ポイントと言うほどのものでもないですが、ViewGroupとTabLayoutを定義します。

activity_zodiac_pager.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.viewpager.widget.ViewPager
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    <com.google.android.material.tabs.TabLayout
            android:id="@+id/tab_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

</androidx.viewpager.widget.ViewPager>

PagerAdapterをセット

スワイプビューを作成するためにPagerAdapterをViewPagerにセットします。
adapterなので、RecyclerView.Adapterにちょっと似てますね。
PageAdapterには3つのメソッドが定義されています。

  • getCount()
    全体の数を取得する

  • getItem(position)
    指定した位置にあるFragmentを返す

  • getPageTitle(position)
    指定した位置にあるTab用の表示を返す

FragmentPagerAdapterの特徴

ここではPageAdapterの実装として FragmentPagerAdapter を使っています。
役割をほぼ同じですが、一方で FragmentStatePagerAdapter というのもあります。
これらの違いと使い方は以下のような感じ。

特徴 使い所
FragmentStatePagerAdapter 前後のページ以外はメモリから破棄される 表示する数が多いもの(とりあえずこっちが安全かも)
FragmentPagerAdapter メモリが破棄されず残る 固定で少ないもの(Tab系はこっちが良さげ?)

今回は12個で固定だったので、FragmentPagerAdapterを使いました。
(12個は多い部類説?)

FragmentStatePagerAdapterにおいてデフォルトでは前後の1ページですが、setOffscreenPageLimit(int) によってロードする前後のページ数を調整できます。

ZodiacPagerActivity.kt
class ZodiacPagerActivity : AppCompatActivity() {

    private lateinit var mViewPager: ViewPager

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_zodiac_pager)

        mViewPager = findViewById(R.id.view_pager)

        val fragmentManager = supportFragmentManager
        mViewPager.adapter = object : FragmentPagerAdapter(fragmentManager) {
            override fun getItem(i: Int): Fragment {
                val fragment = ZodiacFragment()
                fragment.arguments = Bundle().apply {
                    putInt(ARG_OBJECT, i)
                }
                return fragment
            }

            override fun getCount(): Int {
                return 12
            }

            override fun getPageTitle(position: Int): CharSequence? {
                return "${position + 1}"
            }

        }
    }
}

private const val ARG_OBJECT = "object"

class ZodiacFragment : Fragment() {

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.fragment_zodiac, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        val textView: TextView = view.findViewById(R.id.zodiacText)
        val i = arguments?.getInt(ARG_OBJECT)
        textView.text = getAnimalName(i)
    }

    private fun getAnimalName(i: Int?): String {
        return when (i) {
            0 -> "子"
            1 -> "丑"
            2 -> "寅"
            3 -> "卯"
            4 -> "辰"
            5 -> "巳"
            6 -> "午"
            7 -> "未"
            8 -> "申"
            9 -> "酉"
            10 -> "戌"
            11 -> "亥"
            else -> "神"
        }
    }
}

参考

Create swipe views with tabs
Android Programming: The Big Nerd Ranch Guide (3rd Edition) (Big Nerd Ranch Guides)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む