備忘録 〜プログラミング〜

プログラミングに関する事をつらつらと、、

Gsonでjsonをパースするときに出るExpected begin_array but was begin_objectエラー

サーバー:PHP
フロント:Android
使用ライブラリ:Gson

上記環境で、APIの取得をしたとき、Gsonでパースエラーが出て何とか解決したのでメモしておきます。
PHP側から取得するJSON

{  
   "event":true,
   "data":{  
      "rankings":[  
         {  
            "title":"SampleTitle",
            "image_url":"sample.jpg",
            "prefix":{  
               "latest":true
            }
         },
         {  
            "title":SampleTitle2",
            "image_url":"sample2.jpg",
            "prefix":[  

            ]
         }
      ]
   }
}

Android側でGsonを使用してパースするクラス

public class Sample implements Serializable {
  private static final long serialVersionUID = 1524843151923538548L;
  private Data data;
  public Data getData(){
    return data;
  }
  public void setData(Data data){
    this.data = data;
  }
	
  public class Data{
    private List<Ranking> rankings;
    public List<Ranking> getRankings() {
      return rankings;
    }
    public void setRankings(List<Ranking> rankings) {
      this.rankings = rankings;
    }
  }

  public class Ranking{
    private String title;
    @SerializedName("image_url")
    private String url;
    private Prefix prefix;
    public String getTitle() {
      return title;
    }
    public void setTitle(String title) {
      this.title = title;
    }
    public String getUrl() {
      return url;
    }
    public void setUrl(String url) {
      this.url = url;
    }
    public Prefix getPrefix() {
      return prefix;
    }
    public void setPrefix(Prefix prefix) {
      this.prefix = prefix;
    }
  }

  public class Prefix{
    private boolean monopoly;
    private boolean latest;
    public void setMonopoly(boolean monopoly) {
      this.monopoly = monopoly;
    }
    public boolean getMonopoly(){
      return monopoly;
    }
    public void setLatest(boolean latest) {
      this.latest = latest;
    }
    public boolean getLatest(){
      return latest;
    }
  }
}

上記のものをgsonでパース(com.android.volley.NetworkResponse使用)

private final Gson gson = new Gson();
@Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
  try {
    String json = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
    Sample result = gson.fromJson(json, Sample.class);
    return  Response.success(gson.fromJson(json, Sample.class
), enforceClientCaching(HttpHeaderParser.parseCacheHeaders(response), response));
  } catch (UnsupportedEncodingException e) {
    return Response.error(new ParseError(e));
  } catch (JsonSyntaxException e) {
    return Response.error(new ParseError(e));
  }
}

このときに、PHP側からのPrefixがArray型のときと、Object型のときがありハマってしまいました。
PHP側を修正すればいいのですが、修正は出来ないという制約もあったので、他のライブラリが使用出来るのか色々調べていたのですが、
Prefixの部分をこうする事で出来ましたー

private Object prefix;
public Object getPrefix() {
  return prefix;
}
public void setPrefix(Object prefix) {
  this.prefix = prefix;
}

キャストする必要は出てきますが、これで一旦大丈夫かなと。
他に良い方法があれば、良いのですが、、

Android Studioでファイルを作成したときに表示されるCreated Byを変更する

クラスを作成したときに自動生成されるHeader部分の「Created by...」以降を任意の名前になるように変更したのでメモしておきます。
Navigation部分から、

Android Studio > Preferences... > File and Code Templates > Includes > File Header

ここまでいくと、以下のようなものが既に記入されていると思います。

/**
 * Created by ${USER} on ${DATE}.
 */

これが、自動で生成されるものなので、あとはこのように名前をセット

#set($USER = "Hoge")

以上で、Header部分を任意に変更する事が可能になります。stackoverflow.com

Eclipse使用時に、Android Support Libraryをダウングレードする方法

Android SDK ManagerでAndroid Support Libraryを21.0.3から、22に上げたとき、
MediaRouteControllerDialogのsetVolumeControlEnabledがundefinedになる問題が発生しました。
あと、Chromecastのダイアログ表示が若干変わってしまったという事もあり、21.0.3に戻したときのメモをしておきます。
Android Studioであれば、gradleでバージョン指定をすれば良いのかもしれませんが、Eclipseの場合、
venomvendor.blogspot.jp
こちらのサイトからダウングレードしたいバージョンを選択。
インストール後に、sdkフォルダの中にある

extra > android 

このフォルダ以下にあるsupportを上書きすればOKです。
アプリリリース前などは、ライブラリのアップデートは慎重にならないとですね、、
github.com

git diffでvimdiffを使用しているときに、途中で終了する方法

以前、git diffでvimdiffを使用する方法を書きました。

git diffをvimdiffで見れるように設定する - 備忘録 〜プログラミング〜
ファイル数が少ない場合は、この方法で問題なかったのですが、vimdiffで

:wq

を叩いても、次の差分が表示されて途中で終了する事が出来ない問題が出てきたので調べてみました。
shell自体を終了させるという方法もあるようですが、自分は、vimdiffで

:cquit

こちらを叩く事で終了させています。
もっと良い方法があればいいのですが、、

vim - How do you cancel an external git diff? - Stack Overflow

AndroidプロジェクトをRepoでリポジトリ管理するときに作成する、マニフェストファイルについて

repoの詳しい使い方は、こちらを参考にさせてもらいました。git管理ツールRepoを入れてみよう - Qiita
このrepoを使用するときにマニフェストファイルを作成する事になるのですが、
どのように作成すれば良いか分からず色々調べてみたので、詳細をメモしておきます。
要素の属性に関して

name:プロジェクト要素で、どのリモートのプロジェクトかを明確にするために使用します
fetch:リモートのURL

要素の属性に関して

remote:remote要素のnameを指定(どのリモートURLを元にするか)
revision:取得するバージョンをブランチ名、タグ名、コミットIDで指定
sync-j:repo syncコマンドの実行時に割り当てるジョブ数(任意)

要素の属性に関して

remote:remote要素のnameを指定(どのリモートURLを元にするか)
name:gitレポジトリ名(.gitを抜いたもの)
revision:取得するバージョンをブランチ名、タグ名、コミットIDで指定
path:ダウンロードしたソースコードの配置先(repo syncコマンドを実行したディレクトリからの相対パス)

project要素で属性を指定しなかった場合、default要素で指定した属性が割り当てられます。
自分が作ったものは、こちら

<?xml version="1.0" encoding="UTF-8"?>
<manifest>
  <!-- Remote -->
  <remote name="sample_google" fetch="https://android.googlesource.com/" />
  <remote name="sample_repo" fetch="ssh://hoge@sample/" />
  <remote name="sample_arms" fetch="ssh://hogehoge@sample/" />
  <remote name="sample_hub" fetch="git://github.com/sample/" />
  
  <!-- Default -->
  <default revision="develop" remote ="hoge" />

  <!-- Project -->
  <project path="Path" name="sample01" remote="sample_repo" />
  <project path="Path" name="sample02" remote="sample_repo" />
  <project path="Path" name="sample03" remote="sample_arms" />
  <project path="Path" name="sample04" remote="sample_arms" />
</manifest>

repo、便利です、です。

AndroidStudioでRunしたときもSignedAPKを使いたい

先日、Android開発環境をeclipseからAndroidStudioに変更しました。
移行は何とか無事に完了したのですが、リリース済みのアプリをインストールした実機でRunをすると、

Failure [INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES]

このようなエラーが出て一度アプリを削除しないとインストール出来ないという事態が発生しました。
このままアプリのアップデートをしたら、ユーザーには一度アプリを削除してもらわないといけないのかな、、と思ったのですが、そんな事はなく。
自分の環境の場合は、debug用のapkがインストールされていたようなので、debug用のapkを作成するときにも以下のようにkeyを使用するように変更
build.gradleファイル

Properties releaseProps = new Properties()
if(rootProject.file("release.properties").exists()){
    releaseProps.load(new FileInputStream(rootProject.file("release.properties")))
} else {
    println("release.propertiesファイルをプロジェクトルートに作成してください。")
}

android {
    compileSdkVersion Integer.parseInt(project.ANDROID_BUILD_SDK_VERSION)
    buildToolsVersion project.ANDROID_BUILD_TOOLS_VERSION

    defaultConfig {
        applicationId 'sample'
        minSdkVersion Integer.parseInt(project.ANDROID_BUILD_MIN_SDK_VERSION)
        targetSdkVersion Integer.parseInt(project.ANDROID_BUILD_TARGET_SDK_VERSION)
        versionCode {versionCode}
        versionName "versionName"
    }

    signingConfigs {
        debug {
            storeFile rootProject.file(releaseProps.STORE_FILE)
            storePassword releaseProps.STORE_PASSWORD
            keyAlias releaseProps.KEY_ALIAS
            keyPassword releaseProps.KEY_PASSWORD
        }

        release {
            storeFile rootProject.file(releaseProps.STORE_FILE)
            storePassword releaseProps.STORE_PASSWORD
            keyAlias releaseProps.KEY_ALIAS
            keyPassword releaseProps.KEY_PASSWORD
        }
    }
}

ちなみに、release.propertiesファイルと、gradle.propertiesファイルは、プロジェクト直下に置いています。
gradle.propertiesのファイル内容は、こちら

ANDROID_BUILD_MIN_SDK_VERSION=9
ANDROID_BUILD_TARGET_SDK_VERSION=21
ANDROID_BUILD_TOOLS_VERSION=21.1.1
ANDROID_BUILD_SDK_VERSION=21

これをbuild.gradle内で

project.ANDROID_BUILD_MIN_SDK_VERSION

このように呼び出します。
release.propertiesのファイル内容は、こちら

STORE_FILE=releasekey.keystore
STORE_PASSWORD=password
KEY_ALIAS=releasekey
KEY_PASSWORD=password

注意点としては、セミコロンとか、コロンはいらないという事ですね。
もっと他に方法ありそうですが、これでいちいちアプリの削除をしなくてもRunでアプリのインストールが出来るようになりました。

Android Studio - Run signed apk on emulator - Stack Overflow

gitでremoteにあるtag一覧を確認する

アプリをリリースするとき、アプリのバージョン毎に、tagをつけて管理しています。
いつものように

$ git tag release_1_3_1
$ git push —tags

このようにタグをつけて、リモートにプッシュしていたのですが、ふとローカルにあるtag一覧はどうやって確認するのだろうと思ったので調べてみました。
結論としては、こちらのコマンドを

$ git ls-remote --tags

ls-remoteというのは、リモートリポジトリの一覧を出力するコマンドのようです。
コミットIDも一緒に出力されるので、便利ですね。
今まで、push前に

$ git pull --tags

などして確認したりしていたのですが、今後はこちらで確認しようと思っています。
他にいい方法があるのかもしれませんが、とりあえず解決

git-ls-remote(1)