Java tutorial
/////////////////////////////////////////////////////////////////////////////// // // Project: myVision // FileName: TessActivity.java // // Adapted By: Divya Amirtharaj // // Capture the Text for OCR Engine // //////////////////////////// 80 columns wide ////////////////////////////////// /* * Copyright (C) The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package divya.myvision; import android.Manifest; import android.annotation.SuppressLint; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.hardware.Camera; import android.os.Bundle; import android.speech.tts.TextToSpeech; import android.support.annotation.NonNull; import android.support.design.widget.Snackbar; import android.support.v4.app.ActivityCompat; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.GestureDetector; import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; import android.view.ScaleGestureDetector; import android.view.View; import android.widget.Toast; import divya.myvision.ui.camera.CameraSource; import divya.myvision.ui.camera.CameraSourcePreview; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GoogleApiAvailability; import divya.myvision.ui.camera.GraphicOverlay; import com.google.android.gms.vision.text.TextRecognizer; import java.io.IOException; import java.util.Locale; /** * Activity for the multi-tracker app. This app detects text and displays the value with the * rear facing camera. During detection overlay graphics are drawn to indicate the position, * size, and contents of each TextBlock. */ public final class TessActivity extends AppCompatActivity { private static final String TAG = "TessActivity"; // Intent request code to handle updating play services if needed. private static final int RC_HANDLE_GMS = 9001; // Permission request codes need to be < 256 private static final int RC_HANDLE_CAMERA_PERM = 2; // Constants used to pass extra data in the intent public static final String AutoFocus = "AutoFocus"; public static final String UseFlash = "UseFlash"; public static final String FPS = "1"; public static final String FontSize = "40"; public static final String TextBlockObject = "String"; public static final String Orientation = "Auto"; public static final String Lang = "US English"; // Configuration config ; private CameraSource mCameraSource; private CameraSourcePreview mPreview; private GraphicOverlay<TessGraphic> mGraphicOverlay; // Helper objects for detecting taps and pinches. private ScaleGestureDetector scaleGestureDetector; private GestureDetector gestureDetector; // A TextToSpeech engine for speaking a String value. private TextToSpeech tts; /** * Initializes the UI and creates the detector pipeline. */ @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.ocr_capture); mPreview = (CameraSourcePreview) findViewById(R.id.preview); mGraphicOverlay = (GraphicOverlay<TessGraphic>) findViewById(R.id.graphicOverlay); // read parameters from the intent used to launch the activity. boolean autoFocus = getIntent().getBooleanExtra(AutoFocus, false); boolean useFlash = getIntent().getBooleanExtra(UseFlash, false); String fps = getIntent().getStringExtra(FPS); String fontSize = getIntent().getStringExtra(FontSize); String orientation = getIntent().getStringExtra(Orientation); String lang = getIntent().getStringExtra(Lang); if (orientation.equals("Landscape")) { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); } else if (orientation.equals("Portrait")) { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } else { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR); } Settings.setFontSize(Float.parseFloat(fontSize)); // Check for the camera permission before accessing the camera. If the // permission is not granted yet, request permission. int rc = ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA); if (rc == PackageManager.PERMISSION_GRANTED) { createCameraSource(autoFocus, useFlash, fps); } else { requestCameraPermission(); } gestureDetector = new GestureDetector(this, new CaptureGestureListener()); scaleGestureDetector = new ScaleGestureDetector(this, new ScaleListener()); Snackbar.make(mGraphicOverlay, R.string.info_msg, Snackbar.LENGTH_LONG).show(); setLang(lang); } public void setLang(String lang) { Locale locale; if (lang.equals("Spanish")) { // Set up the Text To Speech engine. TextToSpeech.OnInitListener listener = new TextToSpeech.OnInitListener() { @Override public void onInit(final int status) { Locale locSpanish = new Locale("spa", "MEX"); tts.setLanguage(locSpanish); } }; tts = new TextToSpeech(this.getApplicationContext(), listener); locale = new Locale("spa", "MEX"); } else if (lang.equals("French")) { // Set up the Text To Speech engine. TextToSpeech.OnInitListener listener = new TextToSpeech.OnInitListener() { @Override public void onInit(final int status) { tts.setLanguage(Locale.FRENCH); } }; tts = new TextToSpeech(this.getApplicationContext(), listener); locale = new Locale("fr"); } else if (lang.equals("Japanese")) { // Set up the Text To Speech engine. TextToSpeech.OnInitListener listener = new TextToSpeech.OnInitListener() { @Override public void onInit(final int status) { tts.setLanguage(Locale.JAPANESE); } }; tts = new TextToSpeech(this.getApplicationContext(), listener); locale = new Locale("ja"); } else if (lang.equals("Chinese")) { // Set up the Text To Speech engine. TextToSpeech.OnInitListener listener = new TextToSpeech.OnInitListener() { @Override public void onInit(final int status) { tts.setLanguage(Locale.CHINESE); } }; tts = new TextToSpeech(this.getApplicationContext(), listener); locale = new Locale("zh"); } else if (lang.equals("German")) { // Set up the Text To Speech engine. TextToSpeech.OnInitListener listener = new TextToSpeech.OnInitListener() { @Override public void onInit(final int status) { tts.setLanguage(Locale.GERMAN); } }; tts = new TextToSpeech(this.getApplicationContext(), listener); locale = new Locale("de"); } else if (lang.equals("Italian")) { // Set up the Text To Speech engine. TextToSpeech.OnInitListener listener = new TextToSpeech.OnInitListener() { @Override public void onInit(final int status) { tts.setLanguage(Locale.ITALIAN); } }; tts = new TextToSpeech(this.getApplicationContext(), listener); locale = new Locale("it"); } else if (lang.equals("Korean")) { // Set up the Text To Speech engine. TextToSpeech.OnInitListener listener = new TextToSpeech.OnInitListener() { @Override public void onInit(final int status) { tts.setLanguage(Locale.KOREAN); } }; tts = new TextToSpeech(this.getApplicationContext(), listener); locale = new Locale("ko"); } else if (lang.equals("Hindi")) { // Set up the Text To Speech engine. TextToSpeech.OnInitListener listener = new TextToSpeech.OnInitListener() { @Override public void onInit(final int status) { Locale locHindhi = new Locale("hi"); tts.setLanguage(locHindhi); } }; tts = new TextToSpeech(this.getApplicationContext(), listener); locale = new Locale("hi"); } else if (lang.equals("Russian")) { // Set up the Text To Speech engine. TextToSpeech.OnInitListener listener = new TextToSpeech.OnInitListener() { @Override public void onInit(final int status) { Locale locHindhi = new Locale("ru"); tts.setLanguage(locHindhi); } }; tts = new TextToSpeech(this.getApplicationContext(), listener); locale = new Locale("ru"); } else { TextToSpeech.OnInitListener listener = new TextToSpeech.OnInitListener() { @Override public void onInit(final int status) { tts.setLanguage(Locale.US); } }; tts = new TextToSpeech(this.getApplicationContext(), listener); locale = new Locale("en"); } Locale.setDefault(locale); Configuration config = new Configuration(); config.setLocale(locale); this.getApplicationContext().getResources().updateConfiguration(config, null); } public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu, menu); return true; } public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.settings) { super.onBackPressed(); } if (id == R.id.info) { AlertDialog.Builder dlgAlert = new AlertDialog.Builder(this); dlgAlert.setMessage(R.string.info_msg); dlgAlert.setTitle("info"); dlgAlert.setPositiveButton("OK", null); dlgAlert.setCancelable(true); dlgAlert.create().show(); } return super.onOptionsItemSelected(item); } /** * Handles the requesting of the camera permission. This includes * showing a "Snackbar" message of why the permission is needed then * sending the request. */ private void requestCameraPermission() { Log.w(TAG, "Camera permission is not granted. Requesting permission"); final String[] permissions = new String[] { Manifest.permission.CAMERA }; if (!ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) { ActivityCompat.requestPermissions(this, permissions, RC_HANDLE_CAMERA_PERM); return; } final Activity thisActivity = this; View.OnClickListener listener = new View.OnClickListener() { @Override public void onClick(View view) { ActivityCompat.requestPermissions(thisActivity, permissions, RC_HANDLE_CAMERA_PERM); } }; Snackbar.make(mGraphicOverlay, R.string.permission_camera_rationale, Snackbar.LENGTH_INDEFINITE) .setAction(R.string.ok, listener).show(); } @Override public boolean onTouchEvent(MotionEvent e) { boolean b = scaleGestureDetector.onTouchEvent(e); boolean c = gestureDetector.onTouchEvent(e); return b || c || super.onTouchEvent(e); } /** * * Suppressing InlinedApi since there is a check that the minimum version is met before using * the constant. */ @SuppressLint("InlinedApi") private void createCameraSource(boolean autoFocus, boolean useFlash, String fps) { Context context = getApplicationContext(); // A text recognizer is created to find text. An associated processor instance // is set to receive the text recognition results and display graphics for each text block // on screen. TextRecognizer textRecognizer = new TextRecognizer.Builder(context).build(); textRecognizer.setProcessor(new TessDetector(mGraphicOverlay)); if (!textRecognizer.isOperational()) { Log.w(TAG, "Detector dependencies are not yet available."); IntentFilter lowstorageFilter = new IntentFilter(Intent.ACTION_DEVICE_STORAGE_LOW); boolean hasLowStorage = registerReceiver(null, lowstorageFilter) != null; if (hasLowStorage) { Toast.makeText(this, R.string.low_storage_error, Toast.LENGTH_LONG).show(); Log.w(TAG, getString(R.string.low_storage_error)); } } // Creates and starts the camera. mCameraSource = new CameraSource.Builder(getApplicationContext(), textRecognizer) .setFacing(CameraSource.CAMERA_FACING_BACK).setRequestedPreviewSize(1280, 1024) .setRequestedFps(Float.parseFloat(fps)) .setFlashMode(useFlash ? Camera.Parameters.FLASH_MODE_TORCH : null) .setFocusMode(autoFocus ? Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE : null).build(); } /** * Restarts the camera. */ @Override protected void onResume() { super.onResume(); startCameraSource(); } /** * Stops the camera. */ @Override protected void onPause() { super.onPause(); tts.stop(); if (mPreview != null) { mPreview.stop(); } } /** * Releases the resources associated with the camera source, the associated detectors, and the * rest of the processing pipeline. */ @Override protected void onDestroy() { super.onDestroy(); if (mPreview != null) { mPreview.release(); } } /** * Callback for the result from requesting permissions. This method * is invoked for every call on {@link #requestPermissions(String[], int)}. * <p> * <strong>Note:</strong> It is possible that the permissions request interaction * with the user is interrupted. In this case you will receive empty permissions * and results arrays which should be treated as a cancellation. * </p> * * @param requestCode The request code passed in {@link #requestPermissions(String[], int)}. * @param permissions The requested permissions. Never null. * @param grantResults The grant results for the corresponding permissions * which is either {@link PackageManager#PERMISSION_GRANTED} * or {@link PackageManager#PERMISSION_DENIED}. Never null. * @see #requestPermissions(String[], int) */ @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (requestCode != RC_HANDLE_CAMERA_PERM) { Log.d(TAG, "Got unexpected permission result: " + requestCode); super.onRequestPermissionsResult(requestCode, permissions, grantResults); return; } if (grantResults.length != 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { Log.d(TAG, "Camera permission granted - initialize the camera source"); // We have permission, so create the camerasource boolean autoFocus = getIntent().getBooleanExtra(AutoFocus, false); boolean useFlash = getIntent().getBooleanExtra(UseFlash, false); String fps = getIntent().getStringExtra(FPS); String fontSize = getIntent().getStringExtra(FontSize); Settings.setFontSize(Float.parseFloat(fontSize)); createCameraSource(autoFocus, useFlash, fps); return; } Log.e(TAG, "Permission not granted: results len = " + grantResults.length + " Result code = " + (grantResults.length > 0 ? grantResults[0] : "(empty)")); DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { finish(); } }; AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("myVision").setMessage(R.string.no_camera_permission) .setPositiveButton(R.string.ok, listener).show(); } /** * Starts or restarts the camera source, if it exists. If the camera source doesn't exist yet * (e.g., because onResume was called before the camera source was created), this will be called * again when the camera source is created. */ private void startCameraSource() throws SecurityException { // Check that the device has play services available. int code = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(getApplicationContext()); if (code != ConnectionResult.SUCCESS) { Dialog dlg = GoogleApiAvailability.getInstance().getErrorDialog(this, code, RC_HANDLE_GMS); dlg.show(); } if (mCameraSource != null) { try { mPreview.start(mCameraSource, mGraphicOverlay); } catch (IOException e) { Log.e(TAG, "Unable to start camera source.", e); mCameraSource.release(); mCameraSource = null; } } } /** * onTap is called to capture the first TextBlock under the tap location and return it to * the Initializing Activity. * * @param rawX - the raw position of the tap * @param rawY - the raw position of the tap. * @return true if the activity is ending. */ private boolean onTap(float rawX, float rawY) { String ocrText; tts.stop(); ocrText = mGraphicOverlay.getAllText(); if (ocrText != null && ocrText.length() > 0) { // Log.i("DATA_READ",ocrText); tts.speak(ocrText, TextToSpeech.QUEUE_FLUSH, null, "DEFAULT"); } else { if (tts.isSpeaking()) { tts.stop(); } else { tts.speak("Sorry, no text found", TextToSpeech.QUEUE_FLUSH, null, "DEFAULT"); } } return ocrText != null; } private class CaptureGestureListener extends GestureDetector.SimpleOnGestureListener { @Override public boolean onSingleTapConfirmed(MotionEvent e) { return onTap(e.getRawX(), e.getRawY()) || super.onSingleTapConfirmed(e); } } private class ScaleListener implements ScaleGestureDetector.OnScaleGestureListener { @Override public boolean onScale(ScaleGestureDetector detector) { return false; } @Override public boolean onScaleBegin(ScaleGestureDetector detector) { return true; } @Override public void onScaleEnd(ScaleGestureDetector detector) { mCameraSource.doZoom(detector.getScaleFactor()); } } }