no risk no life

技術、投資、時事など

Essential PhoneでBuild PPR1.180905.036アップデートを適用するとInvalid Sim Cardになる

Essential Phone PH-1 にて、Android PのアップデートであるBuild PPR1.180905.036を適用した。 結果、Invalid Sim Cardとなりモバイル通信できなくなったので、解決方法の備忘録。

前提

  • SprintキャリアのEssential Phone

公式から購入したものは大丈夫っぽい…?

現象

  • Essential TelephonyがInvalid Sim Cardという通知を出してモバイル通信できなくなる
  • 前ビルドをインストールするも、タッチパネルがきかなくなる
  • Android O(8.1)をインストールしても同様。

多分Sprint版に対応してないアップデートがかかってしまって、SIMロックかけられちゃった感じ。

タッチパネルが死んだのはなんでかな。

解決方法

Android N(7.1)までダウングレードする必要がある模様。 開発者オプションのブートローダOEMロック解除やfastboot flashing unlock_criticalは適宜行うこと。

参考にしたページはここ。

www.reddit.com

Developer Overview

ここのPrevious BuildsからNMK24Bビルドのfastbootをダウンロードし、flashallする。

modemst.zip - Google ドライブ

ここからzipを落として、

fastboot flash modemst1 modemst1.img
fastboot flash modemst2 modemst2.img

それぞれflashする。 modemstたちの身元がわからないですね。やけくそで焼いちゃったけど。 恐らくSIMロック解除したSprint版から引っこ抜いたんでしょう。

Developer Overview

今度はCurrent BuildsからRelease 1 - PPR1.180610.091を落としてflashallする。

Release 2は、Open Market / TelusとなっているのでSprint端末には対応してないんでしょうね。

あとがき

タッチパネルが効かなくなったときはiPhone Xを買いに行こうかと思ったが、なんとかなった。

Sprint版使ってる人は気をつけましょう。

AndroidアプリのKeyStore(署名鍵)をコマンド1行で生成する

Androidアプリをリリースする際に使用するKeyStoreファイルを一発で生成するコマンド。

Android Studio上で作成する方法はパスワードを記憶しておいたり便利だけど、今回のコマンドはプログラムから叩きやすい形で。

keytoolを使用するのでJDKのPATHを通しておく。

$ keytool -genkey -v -keystore ./test.keystore -keyalg RSA -keysize 2048 -validity 10000 -alias jp.hatenablog.earshttp.test -storepass hogeStorePassword -keypass fugaKeyPassword  -dname "CN=earshttp, OU=hatena blog, O=no risk no life, L=XX-ku, ST=Tokyo, C=jp"

keytoolの鍵生成コマンドはよく見かけるが、全項目を引数として渡すのはなかなか見つからず。

このうちaliasオプション以降の一部の引数を覗いて実行すると、その項目だけ対話式で質問される。

なお、dname内でコンマを使いたい場合はエスケープする必要がある。

rubyで叩いてみる

とりあえずすべての項目を変数にしてshした。

sh("keytool -genkey -v -keystore #{$output_keystore_path} -keyalg RSA -keysize 2048 -validity #{$validity} -alias #{$keystore_alias} -storepass #{$keystore_password} -keypass #{$key_password}  -dname \"CN=#{$keystore_certificates_name}, OU=#{$keystore_organizational_unit}, O=#{$keystore_organization}, L=#{$keystore_locality}, ST=#{$keystore_state}, C=#{$keystore_country}\"")

CIなどで利用できそう…。

Retrofit2+GsonでJsonのint型で返却される真偽値をPOJOでboolean型に置き換える

発端

SerializedNameアノテーションを書いてもFieldNamePolicyを設定してもオブジェクトが正しく変換されなかった。

Jacksonに変えてもうまくいかない…。

と思ったらintで返却されている真偽値を、javaPOJOでbooleanを指定していた。

フィールドをintにしたら動いたが、気持ち悪いのでGsonでよしなにしてもらう。

gradle

...

    // network library
    compile 'com.squareup.retrofit2:retrofit:2.3.0'
    compile 'com.squareup.retrofit2:converter-gson:2.3.0'
    compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
    compile 'com.squareup.okhttp3:okhttp:3.9.0'
    compile 'com.squareup.okhttp3:logging-interceptor:3.9.0'

    // Rx
    compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
    compile 'io.reactivex.rxjava2:rxjava:2.1.3'

    // gson
    compile 'com.google.code.gson:gson:2.8.2'

...

Retrofit

public class ApiClient {
    static private Context mContext;
    static private Retrofit retrofit;

    public static void init(Context context){
        mContext = context;

        OkHttpClient httpClient = new OkHttpClient.Builder()
                .addNetworkInterceptor(new HttpLoggingInterceptor().setLevel(BuildConfig.DEBUG ? HttpLoggingInterceptor.Level.BODY : HttpLoggingInterceptor.Level.NONE))
                .addInterceptor(new AppCustomInterceptor())
                .addInterceptor(new AddCookiesInterceptor())
                .addInterceptor(new ReceivedCookiesInterceptor())
                .readTimeout(30, SECONDS)
                .writeTimeout(30, SECONDS)
                .connectTimeout(30, SECONDS)
                .build();

        Gson gson = new GsonBuilder()
                .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
                .registerTypeAdapter(boolean.class, new BooleanTypeAdapter())
                .create();

        retrofit = new Retrofit.Builder()
                .client(httpClient)
                .baseUrl(BuildConfig.API_ENDPOINT)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();
    }

    public static <V> V getApi(Class<V> clazz){
        return retrofit.create(clazz);
    }

}

BooleanTypeAdapter

public class BooleanTypeAdapter implements JsonDeserializer<Boolean>
{
    public Boolean deserialize(JsonElement json, Type typeOfT,
                               JsonDeserializationContext context) throws JsonParseException
    {
        int code = json.getAsInt();
        return code == 0;
    }
}

を追加してGsonにregisterするだけ。

これでPOJO側でbooleanを指定していても勝手にintから変換してくれる。

vagrant provision時、ホスト上でコマンドを実行する

vagrant-host-shellプラグインを導入

$ vagrant plugin install vagrant-host-shell

Vagrantfileに実行したいコマンドを記述する

Vagrant.configure("2") do |config|

...

    config.vm.provision :host_shell do |host_shell|
      host_shell.inline = 'echo hogehoge'
    end

...
end

プラグインを入れないと他の人が使えないので、どこかに注記しておきましょう。

git管理対象から一括で除外する際、日本語ファイルが存在するとエラーが発生する。

git管理対象から一括で除外する方法は以下を参照

Git:.gitignoreに後から追記したファイルを一括で管理対象からはずす

関連投稿: git rm –cachedした後、他の人が除外commitをgit pullしたときにファイルが消える

概要

これを実行する

git rm --cached `git ls-files --full-name --ignored --exclude-standard`

と、

fatal: pathspec '\343\203\225\343\202\241\343\202\244\343\203\253' did not match any files

こんな感じでエラーが出てしまう。

gitのconfigが原因

git config --global core.quotepath false

で日本語も通るようになる