AndroidでOkHttp3を利用してネットワークアクセスを行う

Javaでのネットワークアクセスを行うにはHttpClientなどいくつか方法がありますが、今回はOkHttp3を利用してみたいと思います。

事前準備1(build.gradle)

OkHttpを取り込みます。

compile 'com.squareup.okhttp3:okhttp:3.10.0'

事前準備2(AndroidManifest.xml)

ネットワークアクセスを許可してあげます。

<uses-permission android:name="android.permission.INTERNET" />

実装

yahoo商品検索APIを利用して実現したいと思います、とりあえずgetだけ。

このAPIは事前にappidが必要なので事前に取得して下さい。

import android.os.AsyncTask;
import net.kagamikarasu.pricechacker.Product;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;

public class NetworkUtils {
    private static final String yahooAppId = "******";

    public static List&lt;Product&gt; getYahooProduct(Long jan_code) {
        final Long final_jan = jan_code;
        List&lt;Product&gt; productList = new ArrayList&lt;&gt;();
        try {
            productList = new AsyncTask&lt;Void, Void, List&lt;Product&gt;&gt;() {
                @Override
                protected List&lt;Product&gt; doInBackground(Void... voids) {
                    List&lt;Product&gt; productList = new ArrayList&lt;&gt;();
                    try {
                        Request request = new Request.Builder()
                                .url("http://shopping.yahooapis.jp/ShoppingWebService/V1/json/itemSearch?appid=" + yahooAppId + "&amp;jan=" + final_jan)
                                .get()
                                .build();
                        OkHttpClient client = new OkHttpClient();
                        Response response = client.newCall(request).execute();
                        productList = Parser.getYahooProduct(response.body().string());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    return productList;
                }
            }.execute().get();
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
        return productList;
    }
}

エラー処理などはここでは省かせて頂きます。

ポイント1:非同期通信

Androidでは非同期でないネットワークアクセスは許可されていないのでAsyncTaskを使用します。

ポイント2:戻り型

Stringだけではなく、List、独自クラスなど自由に返せます。

上記コードではnew AsyncTaskでList<Product>を返しています。

AndroidでZXIngを利用してバーコードを読み取る

今回はAndroidからZXingを利用したいと思います。

何かとライフサイクルが面倒なスマートフォンですが、

ZXing Android Embeddedを活用していきたいと思います。

 

ZXing Android Embeddedの特徴

  • Intentから使用することが出来る
  • UIとロジックのカスタマイズの為に、アクティビティに埋め込むことが出来る
  • 縦及び横からスキャンをする事が出来る
  • カメラバックグラウンドで処理され、時間が短縮される

githubに書いてある通り実装していきたいと思います。

事前準備1(build.gradle)

ZXing Android Embeddedを読み込みます

dependencies {
    compile 'com.journeyapps:zxing-android-embedded:3.6.0'
}

事前準備2(AndroidManifest.xml)

ハードウェアアクセラレーションとカメラを有効にしてあげます。

android:hardwareAccelerated="true"

<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.FLASHLIGHT"/>

カメラ起動

integrator.initiateScan()をしてあげることでカメラが起動します。

それまでのsetはオプションと思って頂ければです。

IntentIntegrator integrator = new IntentIntegrator(this);
integrator.setDesiredBarcodeFormats(IntentIntegrator.ONE_D_CODE_TYPES);
integrator.setPrompt("Scan a barcode");
integrator.setCameraId(0); // Use a specific camera of the device
integrator.setBeepEnabled(false);
integrator.setBarcodeImageEnabled(true);
integrator.initiateScan();

結果取得

カメラが起動してスキャンが完了した時の動作です。

onActivityResultをoverrideしてあげることで結果を求めることが出来ます。

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
    if(result != null) {
        if(result.getContents() == null) {
            Toast.makeText(this, "Cancelled", Toast.LENGTH_LONG).show();
        } else {
            Toast.makeText(this, "Scanned: " + result.getContents(),Toast.LENGTH_LONG).show();
        }
    } else {
        super.onActivityResult(requestCode, resultCode, data);
    }
}

 

動作結果

読み込みが完了すればActivityに戻って、Toastで結果が表示されるかと思います。

Kuromojiと辞書ファイルを利用して形態素解析を行う

SOLDOUT2市場情報を開発しているのですが、ある日作業名から商品名を探したくなる事がありました。

商品名→作業名を探し出すのは簡単なのですが、

作業名→商品名を探し出すのは難しいです。

例えば『革の盾』から『革の盾を作成する』を探すのならcontainsを使えば済みますが、

『革の盾を作成する』から『革の盾』を見つける事は出来ません。

そこで形態素解析を利用して『革の盾を作成する』から『革の盾』という単語を抽出してきます。

利用環境

Spring boot 2.0.0

Kuromoji 0.9.0

事前準備(Gradle)

// https://mvnrepository.com/artifact/com.atilika.kuromoji/kuromoji-ipadic
compile group: 'com.atilika.kuromoji', name: 'kuromoji-ipadic', version: '0.9.0'

利用方法

とりあえずサンプル通りに動かしてみます。

Tokenizer.Builder builder = new Tokenizer.Builder();
builder.mode(TokenizerBase.Mode.SEARCH);
Tokenizer tokenizer = builder.build();
for (Token token : tokenizer.tokenize("革の盾を作成する")) {
    System.out.println(token.getSurface() + "\t" + token.getAllFeatures());
}

と、まぁ、『革の盾』まで綺麗に分割されてしまいます。

これでは使うことが出来ませんので、辞書を使って解決したいと思います。

辞書ファイルの作成

CSVファイルで対応します。

単語,解析後の単語,フリガナ,品詞

なので、

革の盾,革の盾,カワノタテ,商品名

と保存して、プログラムから読み込ませます。

今回は『item_dic.csv』として保存しました。

辞書ファイルをKuromojiに読ませる

辞書ファイルは事前にプロジェクト直下にでも置いてあげて下さい。

以下で読み込ませる事が出来ます。

builder.userDictionary(ClassLoader.getSystemResourceAsStream("item_dic.csv"));

builderで辞書を噛ませた後、先程と同じ様に結果を出力させます。

これで『革の盾を作成する』から『革の盾』を抽出することが出来ました。

ちなみにSpringFrameworkで辞書ファイルを読み込む場合、

上記方法では読み込むことが出来ませんのでこちらを参照して下さい。