Text Recognition OCR Android : Error to start Activity - android

I need to use a text recognition API from google to recognize text using the camera. I download the code, and it works perfectly. But I am developing a project that need to identifying a certain word, which is saved in a global variable. I am having a problem to start another activity when the word is identified. Here is the part of the code that makes the Text Recognition :
import android.app.Activity;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.util.SparseArray;
import com.google.android.gms.samples.vision.ocrreader.ui.camera.GraphicOverlay;
import com.google.android.gms.vision.Detector;
import com.google.android.gms.vision.text.TextBlock;
/**
* A very simple Processor which gets detected TextBlocks and adds them to the overlay
* as OcrGraphics.
* TODO: Make this implement Detector.Processor<TextBlock> and add text to the GraphicOverlay
*/
public final class OcrDetectorProcessor extends Activity implements Detector.Processor<TextBlock> {
private GraphicOverlay<OcrGraphic> mGraphicOverlay;
OcrDetectorProcessor(GraphicOverlay<OcrGraphic> ocrGraphicOverlay, String word) {
// System.out.println("VARIAVEIL GLOBAL no detector:" + word);
// System.out.println("VARIAVEIL GLOBAL no detector da classe:" +s);
mGraphicOverlay = ocrGraphicOverlay;
// String lala = receiveDetections(ocrGraphicOverlay);
}
#Override
public void receiveDetections(Detector.Detections<TextBlock> detections) {
mGraphicOverlay.clear();
System.out.println("CLEAR : " + mGraphicOverlay);
SparseArray<TextBlock> items = detections.getDetectedItems();
for (int i = 0; i < items.size(); ++i) {
TextBlock item = items.valueAt(i);
if (item != null && item.getValue() != null) {
Log.d("Processor", "Text detected! " + item.getValue());
String letra = item.getValue();
// get
// String s = ((MyApplication) this.getApplication()).getSomeVariable();
// System.out.println("Variavei global : "+s);
/*if(letra.equals(palavra))
{
System.out.println("LETRA : " +letra);
System.out.println("LETRA IDENTIFICADA");
}*/
Intent intent = new Intent(getApplicationContext(),Resultado.class);
startActivity(intent);
}
OcrGraphic graphic = new OcrGraphic(mGraphicOverlay, item);
mGraphicOverlay.add(graphic);
}
}
private String PalavraGerada() {
System.out.println("Veio no palavra gerada");
// get
String s = ((MyApplication) this.getApplication()).getSomeVariable();
return s;
}
#Override
public void release() {
mGraphicOverlay.clear();
}
}
When i try to start another activity, i get the following error:
11-03 13:23:14.347 21422-21852/com.google.android.gms.samples.vision.barcodereader E/OpenCameraSource: Exception thrown from receiver.
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()' on a null object reference
at android.content.ContextWrapper.getApplicationContext(ContextWrapper.java:106)
at com.google.android.gms.samples.vision.ocrreader.OcrDetectorProcessor.receiveDetections(OcrDetectorProcessor.java:76)
at com.google.android.gms.vision.Detector.receiveFrame(Unknown Source)
at com.google.android.gms.samples.vision.ocrreader.ui.camera.CameraSource$FrameProcessingRunnable.run(CameraSource.java:1209)
at java.lang.Thread.run(Thread.java:818)
I don't actually need to start another activity, i need to compare the text recognition with the certain word.
Also, when i try to get the value of the global variable, I get the following error:
11-03 13:29:18.029 23276-23495/com.google.android.gms.samples.vision.barcodereader E/OpenCameraSource: Exception thrown from receiver.
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.google.android.gms.samples.vision.ocrreader.MyApplication.getSomeVariable()' on a null object reference
at com.google.android.gms.samples.vision.ocrreader.OcrDetectorProcessor.receiveDetections(OcrDetectorProcessor.java:66)
at com.google.android.gms.vision.Detector.receiveFrame(Unknown Source)
at com.google.android.gms.samples.vision.ocrreader.ui.camera.CameraSource$FrameProcessingRunnable.run(CameraSource.java:1209)
at java.lang.Thread.run(Thread.java:818)
I really don't know how to fix it, and I appreciate any help.
Thanks

The problem is that you cannot get the Context. Try pass the Context Object as a parameter to the constructor method, like
private Context mContext;
OcrDetectorProcessor(GraphicOverlay<OcrGraphic> ocrGraphicOverlay, String word. Context context) {
mGraphicOverlay = ocrGraphicOverlay;
mContext = context;
}
Then in your method
private String PalavraGerada() {
System.out.println("Veio no palavra gerada");
//String s = ((MyApplication) this.getApplication()).getSomeVariable();
String s = ((MyApplication)mContext).getSomeVariable();
// or try some other way to get your application.
return s;
}

Related

Frida print all variables in class

Hy
my professor asked how you can print the contents of the variables within a class
he provided us with an apk to be launched and analyzed with frida:
package com.test_uni_apk.lib.proftest;
public class ProfApi{
public static class StateReady
extends ProfApi.CallState
{
public CallStateReady() {}
public CallStateReady(ProfApi.CallProc paramCallProc,
ProfApi.CallConnection[] paramArrayOfCallConnection, String
paramString, byte[] paramArrayOfByte, String[] paramArrayOfString)
{
this.printthis = paramArrayOfCallConnection;
}
}
}
I read that with frida you can hook a class but I do not understand how to print the value of printthis.
I will assume CallStateReady is an inner class of com.test_uni_apk.lib.proftest.ProfApi and you want to hook the c'tor and print the second parameter #PleaseSubmitElegantCode
function printParamArrayOfCallConnection() {
var ArrayList = Java.use("java.util.ArrayList");
var CallConnection = Java.use("com.test_uni_apk.lib.proftest.ProfApi$CallConnection");
Java.use("com.test_uni_apk.lib.proftest.ProfApi$CallStateReady") // dollar sign for inner class
.$init // init represent the constructor
// list of arguments are passed in byte code style, [B represents byte array
// when you try to hook Frida will provide an informative error with all the possible arguments for overloading
// copy & paste the right one which will look like this:
.overload("Lcom..ProfApi.CallProc;", "Lcom...ProfApi.CallConnection;", "java.lang.String", "[B", "Ljava.lang.String;")
.implementation = function(paramCallProc, paramArrayOfCallConnection, paramString, paramArrayOfByte, paramArrayOfString) {
// first we cast to list
var list = Java.cast(paramArrayOfCallConnection, ArrayList);
// iterating the list
for (var i = 0, l = list.size(); i < l; i++) {
// casting each element to the object we created earlier
var currentElement = Java.cast(list.get(i), CallConnection);
// printing to terminal
console.log(i, currentElement);
}
// executing original c'tor
this.$init(paramCallProc, paramArrayOfCallConnection, paramString, paramArrayOfByte, paramArrayOfString);
}
}
Java.perform(printParamArrayOfCallConnection);

Android, Reading blank values

I'm new to android development, I trying to create a simply Pythagorean Calculator, I need help with reading if a lines blank, but still calculates instead of failing.
Here is my code
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private EditText sideAObj;
private EditText sideBObj;
private EditText sideCObj;
private EditText outputObj;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sideAObj = (EditText) findViewById(R.id.SideAInput);
sideBObj = (EditText) findViewById(R.id.SideBInput);
sideCObj = (EditText) findViewById(R.id.SideCInput);
outputObj = (EditText) findViewById(R.id.OutputText);
}
public void calculateClick(View v){
try {
double sideA = Double.parseDouble(sideAObj.getText().toString());
double sideB = Double.parseDouble(sideBObj.getText().toString());
double sideC = Double.parseDouble(sideCObj.getText().toString());
if (sideAObj.getText().toString().equalsIgnoreCase("0")) {
double pt = Math.sqrt((sideC * sideC) - (sideB * sideB));
outputObj.setText(String.format("%.2f", pt));
}
}
catch (NumberFormatException ex){
Toast errMess = Toast.makeText(getApplicationContext(),"Enter Numbers Only",Toast.LENGTH_SHORT);
errMess.show();
outputObj.setText(String.format("%2.f",0.00));
return;
}
}
public void clearClick(View v){
sideAObj.setText("");
sideBObj.setText("");
sideCObj.setText("");
outputObj.setText("");
sideAObj.requestFocus();
}
}
My program will calculate if their is a Zero on 1 line, but if I leave it blank the program fails entirely, whats the best way to prevent that.
It will obviously fail as it doesn't know how to parse a blank value into a double. Just use something like this during instantiation itself:
double sideB = (sideBObj.getText().toString() == "") ? 0 : (Double.parseDouble(sideBObj.getText().toString()));
double sideC = (sideCObj.getText().toString() == "") ? 0 : (Double.parseDouble(sideCObj.getText().toString()));
Basically, you will be assigning the value 0 if the edit text field is 0 else, you will parse the value entered to a double.
Assuming you want to consider a 0 if there is a blank edit text field.
========================================================================
UPDATE
if(sideAObj.getText().toString() != ""){
double sideA = Double.parseDouble(sideAObj.getText().toString());
}
The simple solution for this problem would be to check each edittext whether they are blank or not and then perform the task.
Get the value of each Edittext to a int variable and then use loop and with the help of edittext.length() method verify if it is equal to 0, if yes, then assign a value to 0 to a new global variable, else assign the exact value to global variable.
and then perform the calculation with the new variables.
Sample code for better understanding :-
String a = et.getText().toString();
int l = a.length();
if (l == 0){
// set the value of global variable = 0;
} else {
// set the value of global variable = a {Actual Digit}
}

SQLiteDatabase Object being passed as Null, even when Initialised at Constructor

I am having error in this for past couple of days, have tried using breakpoints to figure why is it giving null pointer exception, but i am not able to understand which value is getting stuck. How can i make db be not null, so as to run this code.
I have an abstract class that calls this method on certain conditional statement. It has to return a long value. Which is to be used for some other method.
This method long save is implemented in another class which returns a value after calling db.insert, but i am getting Null Pointer Exception
java.lang.NullPointerException: Attempt to invoke virtual method 'long android.database.sqlite.SQLiteDatabase.insert(java.lang.String, java.lang.String, android.content.ContentValues)' on a null object reference
I have following doubts :
Why is this giving error when i am using it in Fragment, but when i am using with Activity it's working fine. What can be the reason.
Also How is getWritableDatabase gets called when i pass db as an argument.
long save(SQLiteDatabase db) {
ContentValues cv = new ContentValues();
long now = System.currentTimeMillis();
cv.put(COL_CREATEDTIME, now);
cv.put(COL_MODIFIEDTIME, now);
//cv.putNull(COL_MODIFIEDTIME);
cv.put(COL_NAME, name==null ? "" : name);
//if (fromDate != null)
cv.put(COL_FROMDATE, fromDate==null ? "" :fromDate);
//if (toDate != null)
cv.put(COL_TODATE, toDate==null ? "" :toDate);
//if (rule != null)
cv.put(COL_RULE, rule==null ? "" :rule);
//if (interval != null)
cv.put(COL_INTERVAL, interval==null ? "" :interval);
cv.put(COL_SOUND, sound ? 1 : 0);
//if (sound != null)
//Log.e(TAG, "Error inserting " + now);
return db.insert(TABLE_NAME,null, cv);}
public class DosageDB extends Application {
public static DBHelper dbHelper;
public static SQLiteDatabase db;
public static final String TIME_OPTION = "time_option";
public static final String DATE_RANGE = "date_range";
public static final String DATE_FORMAT = "date_format";
public static final String TIME_FORMAT = "time_format";
public static final String VIBRATE_PREF = "vibrate_pref";
public static final String RINGTONE_PREF = "ringtone_pref";
public static final String DEFAULT_DATE_FORMAT = "yyyy-M-d";
#Override
public void onCreate() {
super.onCreate();
PreferenceManager.setDefaultValues(this,R.xml.settings, false);
sp = PreferenceManager.getDefaultSharedPreferences(this);
dbHelper = new DBHelper(this);
db = dbHelper.getWritableDatabase();
}
}
Stacktrace :
09-10 15:05:39.582 2423-2423/healerkart.com.dosage E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: healerkart.com.dosage, PID: 2423
java.lang.NullPointerException: Attempt to invoke virtual method 'long android.database.sqlite.SQLiteDatabase.insert(java.lang.String, java.lang.String, android.content.ContentValues)' on a null object reference
at healerkart.com.dosage.Delta.Alarm.save(Alarm.java:65)
at healerkart.com.dosage.Delta.AbstractModel.persist(AbstractModel.java:54)
at healerkart.com.dosage.Delta.Alarm.persist(Alarm.java:10)
at healerkart.com.dosage.Alpha.dosageFrag$2.onClick(dosageFrag.java:134)
at android.view.View.performClick(View.java:4780)
at android.view.View$PerformClick.run(View.java:19866)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5257)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Since DosageDB was extending Application, i forgot to mention the Application name attribute in the AndroidManifest.xml
Thanks anyways.

using Object... in codenameone

I'm using Codenameone to develop application in mobile. I want to create a method to show an error message on Screen. But I got an error:
This is my code
public class Common {
public static boolean checkNullOrEmpty(String value){
return !(value != null && !value.equals(""));
}
public static void showMessage(String title,String msgID, Object... params){
String result = String.format(msgID, params);
Dialog.show(title, result, "OK", "Cancel");
}
}
And this is the way I call that method:
Common.showMessage("Error", "Item %s ; Item %s","01","02");
This is error message:
error: cannot find symbol
String result = String.format(msgID, params);
symbol: method format(String,Object[])
location: class String
Can anybody help me? Thanks a lot.
String.format isn't supported by the Codename One subset of the Java API. You should be able to use something like StringUtil.replaceAll etc. to replace entries e.g. for this:
Common.showMessage("Error", "Item {0} ; Item {1}","01","02");
You should be able to do something like this:
String result = msgID;
for(int iter = 0 ; iter < params.length ; iter++) {
result = StringUtil.replaceAll(result, "{" + iter + "}", params[iter]);
}

Cannot save null column value in ActiveAndroid

To make it simple, I have this model:
#Table(name = "Items")
class TItem extends Model {
#Column(name = "title")
private String mTitle;
public String getTitle() { return mTitle; }
public void setTitle(String title) { mTitle = title; }
}
And I'm failing in my testings doing that:
//Create new object and save it to DDBB
TItem r = new TItem();
r.save();
TItem saved = new Select().from(TItem.class).where("id=?", r.getId()).executeSingle();
//Value for saved.getTitle() = null --> OK
r.setTitle("Hello");
r.save();
saved = new Select().from(TItem.class).where("id=?", r.getId()).executeSingle();
//Value for saved.getTitle() = "Hello" --> OK
r.setTitle(null);
r.save();
saved = new Select().from(TItem.class).where("id=?", r.getId()).executeSingle();
//Value for saved.getTitle() = "Hello" --> FAIL
It seems I cannot change a column value from anything to null in ActiveAndroid. Very strange. Is it a bug? I didn't find anything about it, but looks pretty basic this functionallity.
If I debug the app and follow the saving method, the last command it reaches is in SQLLiteConnection.java:
private void bindArguments(PreparedStatement statement, Object[] bindArgs) {
....
// It seems ok, as it is really inserting a null value in the DDBB
case Cursor.FIELD_TYPE_NULL:
nativeBindNull(mConnectionPtr, statementPtr, i + 1);
....
}
I cannot see further, as "nativeBindNull" is not available
Finally I found what happened, and the problem is in ActiveAndroid library.
The null value is saved propertly to DDBB, but is not retrieved correctly. As ActiveAndroid uses cached items, when getting an element, it gets an "old version" and updates it with the new values. Here is where the library fails, because is checking that if not null replace the value, otherwise, nothing.
To solve this, we'll have to change it from the library, in the class Model.java:
public final void loadFromCursor(Cursor cursor) {
List<String> columnsOrdered = new ArrayList<String>(Arrays.asList(cursor.getColumnNames()));
for (Field field : mTableInfo.getFields()) {
final String fieldName = mTableInfo.getColumnName(field);
Class<?> fieldType = field.getType();
final int columnIndex = columnsOrdered.indexOf(fieldName);
....
if (columnIsNull) {
<strike>field = null;</strike> //Don't put the field to null, otherwise we won't be able to change its content
value = null;
}
....
<strike>if (value != null)</strike> { //Remove this check, to always set the value
field.set(this, value);
}
....
}
....
}

Categories

Resources