質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.53%

  • Java

    13742questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

  • Android

    6504questions

    Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

  • Android Studio

    3688questions

    Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

getAssetsやgetResourcesを使おうとするとエラーが発生してしまう

解決済

回答 1

投稿

  • 評価
  • クリップ 1
  • VIEW 1,146

ehyai

score 33

前提・実現したいこと

私はAndroid Studio上でGitHubにあるソースコードの中の、rmtheis氏の「android-ocr」というプロジェクトを「Checkout Project from VersionControl」からインポートして、実機での実行に成功しました。これは、紙の文書をスマートフォンのカメラで認識し、文書中の文字を認識して画面に表示するというプロジェクトです。そして次に、このプロジェクトに手を加えて、認識した文字をこちらのサイト①を参考にして、APIを用いて文字解析により単語を抜き出し、抜き出した単語をこちらのサイト②の百貨辞書のデータを利用させていただき、単語の意味を表示させる機能を追加実装させたいと思いました。
今回追加したコードは、android-ocrの「OcrRecognizeAsyncTask.java」の中に追加させようと考え、以下がそのOcrRecognizeAsyncTask.javaのソースコードです。

ソースコード

package edu.sfsu.cs.orange.ocr;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;

import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

import com.googlecode.leptonica.android.ReadFile;
import com.googlecode.tesseract.android.ResultIterator;
import com.googlecode.tesseract.android.TessBaseAPI;
import com.googlecode.tesseract.android.TessBaseAPI.PageIteratorLevel;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

final class OcrRecognizeAsyncTask extends AsyncTask<Void, Void, Boolean> {
private CaptureActivity activity;
  private TessBaseAPI baseApi;
  private byte[] data;
  private int width;
  private int height;
  private OcrResult ocrResult;
  private long timeRequired;

//私が独自に追加した箇所① goo APIを活用するために必要
static final String GOO_URL = "https://labs.goo.ne.jp/api/morph";
  String ID  = "(自分で取得したアプリケーションID)";
//①ここまで

OcrRecognizeAsyncTask(CaptureActivity activity, TessBaseAPI baseApi, byte[] data, int width, int height) {
    this.activity = activity;
    this.baseApi = baseApi;
    this.data = data;
    this.width = width;
    this.height = height;
  }

@Override
  protected Boolean doInBackground(Void... arg0) {
    long start = System.currentTimeMillis();
    Bitmap bitmap = activity.getCameraManager().buildLuminanceSource(data, width, height).renderCroppedGreyscaleBitmap();
    String textResult;
try {
      baseApi.setImage(ReadFile.readBitmap(bitmap));
      textResult = baseApi.getUTF8Text();
      timeRequired = System.currentTimeMillis() - start;

      // Check for failure to recognize text
      if (textResult == null || textResult.equals("")) {
        return false;
      }

//私が独自に追加した箇所② ここでAPIを活用し文書の形態素解析を行う
      URL url = null;

      try{
        url = new URL(GOO_URL);
        URLConnection connection =url.openConnection();
        connection.setDoOutput(true);

        connection.setRequestProperty("Content-Type", "application/json");

        OutputStream os = connection.getOutputStream();
        String postStr = "{\"app_id\": \"" + ID + "\",\"sentence\": \"" + textResult + "\"}";

        PrintStream ps = new PrintStream(os);
        ps.print(postStr); //データをPOSTする
        ps.close();

        InputStream is = connection.getInputStream(); //結果を取得
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        String s;
        while ((s = reader.readLine()) != null) {//以下、解析した文章から単語だけを抜き出す
          ArrayList<String> hoge = new ArrayList<String>();//解析した文章から抜き出した単語を入れていくための配列を用意
          try {
            JSONObject json = new JSONObject(s);

            JSONArray datas  = json.getJSONArray("word_list");
            for (int i = 0; i < datas.length(); i++) {
              JSONArray datas2 = datas.getJSONArray(i);
              for (int u = 0; u < datas2.length(); u++)
              {
                JSONArray datas3 = datas2.getJSONArray(u);
                String form = datas3.getString(0);
                hoge.add(form);
              }
            }

          } catch (JSONException e) {
            e.printStackTrace();
          }
          textResult += s;
          for (String a : hoge) {        
            String Dic = Diction(a); //単語の意味を調べるため独自に追加した箇所③で書いたDictionを呼び出す
          }
        }
        reader.close();
      }
      catch (IOException e) {
        e.printStackTrace();
      }
//②ここまで

      ocrResult = new OcrResult();
      ocrResult.setWordConfidences(baseApi.wordConfidences());
      ocrResult.setMeanConfidence( baseApi.meanConfidence());
      ocrResult.setRegionBoundingBoxes(baseApi.getRegions().getBoxRects());
      ocrResult.setTextlineBoundingBoxes(baseApi.getTextlines().getBoxRects());
      ocrResult.setWordBoundingBoxes(baseApi.getWords().getBoxRects());
   ocrResult.setStripBoundingBoxes(baseApi.getStrips().getBoxRects());

      // Iterate through the results.
      final ResultIterator iterator = baseApi.getResultIterator();
      int[] lastBoundingBox;
      ArrayList<Rect> charBoxes = new ArrayList<Rect>();
      iterator.begin();
      do {
          lastBoundingBox = iterator.getBoundingBox(PageIteratorLevel.RIL_SYMBOL);
          Rect lastRectBox = new Rect(lastBoundingBox[0], lastBoundingBox[1],
                  lastBoundingBox[2], lastBoundingBox[3]);
          charBoxes.add(lastRectBox);
      } while (iterator.next(PageIteratorLevel.RIL_SYMBOL));
      iterator.delete();
      ocrResult.setCharacterBoundingBoxes(charBoxes);
}catch (RuntimeException e) {
      Log.e("OcrRecognizeAsyncTask", "Caught RuntimeException in request to Tesseract. Setting state to CONTINUOUS_STOPPED.");
      e.printStackTrace();
      try {
        baseApi.clear();
        activity.stopHandler();
      } catch (NullPointerException e1) {
        // Continue
      }
      return false;
    }
    timeRequired = System.currentTimeMillis() - start;
    ocrResult.setBitmap(bitmap);
    ocrResult.setText(textResult);
    ocrResult.setRecognitionTimeRequired(timeRequired);
    return true;
  }

//私が独自に追加した箇所③ ここに辞書機能を置きたい
  public String Diction(String str1){
    //getAssets()メソッドでAssetManagerを取得
    AssetManager assets = getResources().getAssets();//assetsフォルダのindex.txtファイルを参照させるために必要 しかしここでgetResourcesが赤く表示され、エラーが起きる

    InputStream is = null;
    BufferedReader br = null;

    String text = "";
    try{
      //StreamReaderの新しいインスタンスを生成 次の一行分の文字を読み取る
      is = assets.open("index.txt"); //index.txtは百貨辞書のデータ
      br = new BufferedReader(new InputStreamReader(is));

      String str2 = ""; //行数調べるのに使う
      while ((str2 = br.readLine()) != null) {

        String line = str2.replace("<-|->", "\n").toString();
        if (line.contains(str1)) 
        {
          text += "-----------------------------\n";
          text += line;
        }
      }
      if (is != null) is.close();
      if (br != null) br.close();
    }
  catch (Exception e){
      // エラー発生時の処理
      text += "[エラーが発生しました]";
    }
    return text; //辞書の内容(またはエラー文)を返す
  }
//③ここまで

@Override
  protected void onPostExecute(Boolean result) {
    super.onPostExecute(result);

    Handler handler = activity.getHandler();
    if (handler != null) {
      // Send results for single-shot mode recognition.
      //シングルショットモード認識の結果を送信します。
      if (result) {
        Message message = Message.obtain(handler, R.id.ocr_decode_succeeded, ocrResult);
        message.sendToTarget();
      } else {
        Message message = Message.obtain(handler, R.id.ocr_decode_failed, ocrResult);
        message.sendToTarget();
      }
      activity.getProgressDialog().dismiss();
    }
    if (baseApi != null) {
      baseApi.clear();
    }
  }
}

発生している問題・エラーメッセージ

しかし、上記のように追加を行うと、独自に追加した箇所③のうち、
百貨辞書のデータであるindex.txtをassetsフォルダの中から参照させるために必要な、
AssetManager assets = getResources().getAssets();
のところでgetResourcesが赤く表示されてしまい、実行できません。
エラーメッセージとして、

エラー: シンボルを見つけられません
シンボル: メソッド getResources()
場所: クラス OcrRecognizeAsyncTask.java

Execution failed for task ':OCRTest:compileDebugJavaWithJavac'.
>Compilation failed; see the compiler error output for details.


と表示されました。
その後、AssetManager assets = getResources().getAssets();の箇所を消し、
is = assets.open("index.txt");をis = this.getAssets().open("index.txt");に変更させたところ、今度はgetAssetsの箇所が赤くなってしまいます。
独自に追加した箇所③は、Android Studioで別に一から作ったプロジェクトのMainActivity.javaに同様のコードを書いて試すと、こちらではエラーは発生せず正しく動作しました。

このエラーを解決できるようなアドバイスをいただけたらと思いますので、何卒、よろしくお願いします。

補足情報(言語/FW/ツール等のバージョンなど)

このプロジェクトのOcrRecognizeAsyncTask.javaは、
android-ocr/OCRTest/src/main/java/edu/sfsu/cs/orange/ocr/OcrRecognizeAsyncTask
に置かれています。
また単語の意味を表示するのに使用するindex.txtは、
android-ocr/OCRTest/src/main/assets/index.txt
に置かれています。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

今これを書いているクラスにも、これの親クラスにも。この名前のメソッドは存在しません。getResources()はActivityのメソッドですので、

// コンストラクタで受け取ったActivityに対してgetResourcesを使う
AssetManager assets = activity.getResources().getAssets();


としてみては?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/10/01 02:07

    回答してくださってありがとうございます!
    swordoneさんのおっしゃる通りにコードを変更しましたところ、エラーが起こらなくなり正しく動作するようになりました。
    どこのメソッドかを書く必要があったということですね。
    本当にありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.53%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Java

    13742questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

  • Android

    6504questions

    Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

  • Android Studio

    3688questions

    Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。