i have a sales summary print out and has a QR Code ,
i want to develop an app (IOS and android) that reads the QR code , extract all information,do some calculations,and display in specific form , i tried zxing library but it did not extract all information from the receipt.any tip?
You can use google vision API to achieve this. I personally used this and found it great. The below code snippets should help you.
Put this below line in the gradle.
compile 'com.google.android.gms:play-services:9.4.0'
Use BarcodeDetector and CameraSource classes to capture the QR code on real time and decode it.
barcodeDetector.setProcessor(new Detector.Processor<Barcode>() {
#Override
public void release() {
}
#Override
public void receiveDetections(Detector.Detections<Barcode> detections) {
final SparseArray<Barcode> barcodes = detections.getDetectedItems();
if (barcodes.size() != 0) {
barcodeInfo.post(new Runnable() { // Use the post method of the TextView
public void run() {
barcodeInfo.setText( // Update the TextView
barcodes.valueAt(0).displayValue
);
}
});
}
}
});
Use a SparseArray to fetch the detections and the displayValue of the elements of this sparse array returns the deocded string.
After extracting the string one can do anything, be it displaying the string or make some calculation out of it etc.
This library is the most popular and easiest of reading QR codes in your Android application.
You should also have a look at the Wiki section of this library for learning about how to integrate this library into your Android Application and how to use this library.
This is how you can use this library.
1. Add this library to your project by adding following line into your dependencies inside build.gradle(Module: app) file
compile 'com.github.nisrulz:qreader:2.0.0'
2. Then, after syncing project files, add the SurfaceView element provided by this library into your XML layout file.
<SurfaceView
android:id="#+id/camera_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
3. Declare the SurfaceView & QREader inside your Activity's Java file & then initialize it inside onCreate() method.
class MainActivity extends AppCompatActivity{
private SurfaceView mySurfaceView;
private QREader qrEader;
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Setup SurfaceView
// -----------------
mySurfaceView = (SurfaceView) findViewById(R.id.camera_view);
// Init QREader
// ------------
qrEader = new QREader.Builder(this, mySurfaceView, new QRDataListener() {
#Override
public void onDetected(final String data) {
Log.d("QREader", "Value : " + data);
text.post(new Runnable() {
#Override
public void run() {
text.setText(data);
}
});
}
}).facing(QREader.BACK_CAM)
.enableAutofocus(true)
.height(mySurfaceView.getHeight())
.width(mySurfaceView.getWidth())
.build();
}
4. Initialize it inside onResume()
#Override
protected void onResume() {
super.onResume();
// Init and Start with SurfaceView
// -------------------------------
qrEader.initAndStart(mySurfaceView);
}
There are many more possibilities you can do with this library, so I recommend you to visit the GitHub repository and check it out. It's worth a shot!
Related
I have a website which only shows one line of text which I need to extract the text form in android studio, I would prefer to get it as a string. How do I do this?
Something such as webView.getTitle() would work but than for the content of the site, is there such a quick way to get this or how should I else do it?
specific info
the site I need to get the information form is:
"<html> <head></head> <body> #4d636f </body> </html> "
from this I only need the text in the body, in this case a color as text.
You can use any Web Scraper/Crawler API to fetch data from web site.
For example:
JSOUP API For Java And Android
Update
Step By Step guide to solve the mentioned problem
Add Jsoup dependency to the app level of your build.gradle.
implementation 'org.jsoup:jsoup:1.11.1'
Add Internet permission to the Android Manifest file for internet access.
<uses-permission android:name="android.permission.INTERNET" />
Add button and text view in your app to get data from website on button click and display the result on text view.
Below is the sample code:
public class MainActivity extends AppCompatActivity {
private TextView result;
private Button fetch;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
result = (TextView) findViewById(R.id.result);
fetch = (Button) findViewById(R.id.fetch);
fetch.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
getBodyText();
}
});
}
private void getBodyText() {
new Thread(new Runnable() {
#Override
public void run() {
final StringBuilder builder = new StringBuilder();
try {
String url="http://www.example.com";//your website url
Document doc = Jsoup.connect(url).get();
Element body = doc.body();
builder.append(body.text());
} catch (Exception e) {
builder.append("Error : ").append(e.getMessage()).append("\n");
}
runOnUiThread(new Runnable() {
#Override
public void run() {
result.setText(builder.toString());
}
});
}
}).start();
}
}
This type of process is known as web scrubbing. And you could do more research to see different methods. One methd I would suggest is getting the HTML from source and searching the DOM for any tags unique to the text you want.
By getting the HTML you avoid rendering the whole page (images, javascript, ect..)
Do you have a snippet of the source code you want to scrub from?
Sure here is an example. P.S. I'm not familiar with javascript, correct him for your case.
webView.evaluateJavascript("return document.getElementById(your_id)", new ValueCallback<String>() {
#Override
public void onReceiveValue(String value) {
// value is your result
}
});
I'm developing Android app on Android studio using Opencv library and when I try to open my app it opens then right after that it closes and displaying crash message. I'm new on mobile development
Using : OpenCV310, Android Studio 3.0,
public class ScanLicensePlateActivity extends AppCompatActivity {
protected AnylineOcrScanView scanView;
private LicensePlateResultView licensePlateResultView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Set the flag to keep the screen on (otherwise the screen may go dark during scanning)
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.activity_anyline_ocr);
String license = getString(R.string.anyline_license_key);
// Get the view from the layout
scanView = (AnylineOcrScanView) findViewById(R.id.scan_view);
// Configure the view (cutout, the camera resolution, etc.) via json
// (can also be done in xml in the layout)
scanView.setConfig(new AnylineViewConfig(this, "license_plate_view_config.json"));
// Copies given traineddata-file to a place where the core can access it.
// This MUST be called for every traineddata file that is used
// (before startScanning() is called).
// The file must be located directly in the assets directory
// (or in tessdata/ but no other folders are allowed)
scanView.copyTrainedData("tessdata/GL-Nummernschild-Mtl7_uml.traineddata",
"8ea050e8f22ba7471df7e18c310430d8");
scanView.copyTrainedData("tessdata/Arial.traineddata", "9a5555eb6ac51c83cbb76d238028c485");
scanView.copyTrainedData("tessdata/Alte.traineddata", "f52e3822cdd5423758ba19ed75b0cc32");
scanView.copyTrainedData("tessdata/deu.traineddata", "2d5190b9b62e28fa6d17b728ca195776");
// Configure the OCR for license plate scanning via a custom script file
// This is how you could add custom scripts optimized by Anyline for your use-case
AnylineOcrConfig anylineOcrConfig = new AnylineOcrConfig();
anylineOcrConfig.setCustomCmdFile("license_plates.ale");
// set the ocr config
scanView.setAnylineOcrConfig(anylineOcrConfig);
// initialize with the license and a listener
scanView.initAnyline(license, new AnylineOcrListener() {
#Override
public void onReport(String identifier, Object value) {
// Called with interesting values, that arise during processing.
// Some possibly reported values:
//
// $brightness - the brightness of the center region of the cutout as a float value
// $confidence - the confidence, an Integer value between 0 and 100
// $thresholdedImage - the current image transformed into black and white
// $sharpness - the detected sharpness value (only reported if minSharpness > 0)
}
#Override
public boolean onTextOutlineDetected(List<PointF> list) {
// Called when the outline of a possible text is detected.
// If false is returned, the outline is drawn automatically.
return false;
}
#Override
public void onResult(AnylineOcrResult result) {
// Called when a valid result is found
String results[] = result.getText().split("-");
String licensePlate = results[1];
licensePlateResultView.setLicensePlate(licensePlate);
licensePlateResultView.setVisibility(View.VISIBLE);
}
#Override
public void onAbortRun(AnylineOcrError code, String message) {
// Is called when no result was found for the current image.
// E.g. if no text was found or the result is not valid.
}
});
// disable the reporting if set to off in preferences
if (!PreferenceManager.getDefaultSharedPreferences(this).getBoolean(
SettingsFragment.KEY_PREF_REPORTING_ON, true)) {
// The reporting of results - including the photo of a scanned meter -
// helps us in improving our product, and the customer experience.
// However, if you wish to turn off this reporting feature, you can do it like this:
scanView.setReportingEnabled(false);
}
addLicensePlateResultView();
}
private void addLicensePlateResultView() {
RelativeLayout mainLayout = (RelativeLayout) findViewById(R.id.main_layout);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
params.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
licensePlateResultView = new LicensePlateResultView(this);
licensePlateResultView.setVisibility(View.INVISIBLE);
mainLayout.addView(licensePlateResultView, params);
licensePlateResultView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startScanning();
}
});
}
private void startScanning() {
licensePlateResultView.setVisibility(View.INVISIBLE);
// this must be called in onResume, or after a result to start the scanning again
scanView.startScanning();
}
#Override
protected void onResume() {
super.onResume();
startScanning();
}
#Override
protected void onPause() {
super.onPause();
scanView.cancelScanning();
scanView.releaseCameraInBackground();
}
#Override
public void onBackPressed() {
if (licensePlateResultView.getVisibility() == View.VISIBLE) {
startScanning();
} else {
super.onBackPressed();
}
}
#Override
protected void onDestroy() {
super.onDestroy();
}}
source code is here.
If possible please help.
Logcat error shown here
Ideally more information regarding the error would be best i.e the opencv library version etc. Given it seems to be an Android issue, I would advise
File and issue or view issues pertaining to this error on their github page. Search for related Android errors to see if they match.
IF you cannot find a related error, file an issue there.
Good day! i'm having an issue with the qr code scanner in android marshmallow and nougat using the library that i have added as dependency in my project the camera shows white screen. Code runs perfectly in lollipop and kitkat. Please let me know if there was something i have missed or something i will do to make it work. I have paste my snippets of code down below. It is my pleasure if you give me some time to notice my concern. I have seen similar topic of my issue but it did not help me work out or i have implemented it wrong. Thank you in advance.
I have zxing jar library for generating qr code, and i used me.dm7.barcodescanner:zxing:1.8.4 for scanning qr codes:
dependency {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile files('libs/zxing-2.1.jar')
compile('me.dm7.barcodescanner:zxing:1.8.4'){
exclude group: 'com.google.zxing'
}
}
The Activity for the opening of the camera:
public class ScanQRCodeActivity extends AppCompatActivity implements ZXingScannerView.ResultHandler {
private String strDataEncrypted;
private ZXingScannerView mScannerView;
public static String strEncrypt;
public static String strEncrypted;
public static String strIV;
public static boolean isScanSuccess = false;
#Override
public void onCreate(Bundle state) {
super.onCreate(state);
mScannerView = new ZXingScannerView(this);
setContentView(mScannerView);
}
#Override
public void onResume() {
super.onResume();
mScannerView.setResultHandler(this);
mScannerView.startCamera();
}
#Override
public void onPause() {
super.onPause();
mScannerView.stopCamera();
}
#Override
public void handleResult(Result result) {
strDataEncrypted = result.getText();
Log.wtf("handleResult", strDataEncrypted);
String[] strSplit = strDataEncrypted.split("\\|\\|");
strEncrypted = strSplit[0].trim();
strIV = strSplit[1];
CryptLibHelper cryptLibHelper = new CryptLibHelper();
cryptLibHelper.decrypt(strEncrypted, strIV, new CryptLibHelper.CryptLibDecryptCallback() {
#Override
public void onDecryptFailed(String str_message) {
Log.wtf("onDecryptFailed", str_message);
}
#Override
public void onDecryptSuccess(String str_message) {
if (str_message.contains("}")) {
strEncrypt = str_message.replace("}", "");
Log.wtf("onDecryptSuccess", strEncrypt);
}
}
});
onBackPressed();
isScanSuccess = true;
mScannerView.resumeCameraPreview(this);
}
}
Have you added CAMERA permission check in your app?? Since from marshmallow onwards you need to ask user for some permissions.
You can first try to manually give permission to your app from device settings.
I was experiencing this issue on and off, my problem was that my application was requesting camera permissions too late! Make sure your application is requesting the camera permissions BEFORE an instance of ZXing qr scanner is created.
I’m using the code given here.
I put those code blocks as classes in my project’s util package. And then in the main activity class I wrote this..
class MenuActivity {
// Variable declaration
private final CompositeSubscription mConnectionSubscription = new CompositeSubscription();
#Override
protected void onCreate(Bundle savedInstanceState) {
// Some initialisation of UI elements done here
mConnectionSubscription.add(AppObservable.bindActivity(this, NetworkUtils.observe(this)).subscribe(new Action1<NetworkUtils.State>() {
#Override
public void call(NetworkUtils.State state) {
if(state == NetworkUtils.State.NOT_CONNECTED)
Timber.i("Connection lost");
else
Timber.i("Connected");
}
}));
}
My goal is to monitor the changes and change a variable MyApp.isConnected defined in the MyApp class statically whenever the network changes to true false. Help would be appreciated. Thank you 😄
You asked me for an answer in another thread. I'm answering late, because I needed some time to develop and test solution, which I find good enough.
I've recently created new project called ReactiveNetwork.
It's open-source and available at: https://github.com/pwittchen/ReactiveNetwork.
You can add the following dependency to your build.gradle file:
dependencies {
compile 'com.github.pwittchen:reactivenetwork:x.y.z'
}
Then, you can replace x.y.z with the latest version number.
After that, you can use library in the following way:
ReactiveNetwork.observeNetworkConnectivity(context)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<ConnectivityStatus>() {
#Override public void call(Connectivity connectivity) {
if(connectivity.getState() == NetworkInfo.State.DISCONNECTED) {
Timber.i("Connection lost");
} else if(connectivity.getState() == NetworkInfo.State.CONNECTED) {
Timber.i("Connected");
}
}
});
You can also use filter(...) method from RxJava if you want to react only on a single type of event.
You can create a subscription in onResume() method and then unsubscribe it in onPause() method inside Activity.
You can find more examples of usage and sample app on the website of the project on GitHub.
Moreover, you can read about NetworkInfo.State enum from Android API, which is now used by the library.
Try to use rxnetwork-android:
public class MainActivity extends AppCompatActivity{
private Subscription sendStateSubscription;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Observable<RxNetwork.State> sendStateStream =
RxNetwork.stream(this);
sendStateSubscription = AppObservable.bindActivity(
this, sendStateStream
).subscribe(new Action1<RxNetwork.State>() {
#Override public void call(RxNetwork.State state) {
if(state == RxNetwork.State.NOT_CONNECTED)
Timber.i("Connection lost");
else
Timber.i("Connected");
}
});
}
#Override protected void onDestroy() {
sendStateSubscription.unsubscribe();
sendStateSubscription = null;
super.onDestroy();
}
}
I want to have a simple gauge view where i will define the start value and the end value and have a pointer to show given variable value.
So i can show a given value like speedmeter. For example if my the value of a textView is 1300, then next to the textview i want to have this custom meter view animation like this!
It is possible? Any existing example code?
Another one i found at Evelina Vrabie's blog, used it and worked perfect!
Look at Evelina Vrabie's GitHub.
It has a gauge library and some samples to interact with.
Big thanks to the owner Evelina Vrabie!
However it is not working on XHDPI/Few versions of android devices (above 4). Problem is the text in gauge view.
For anyone looking for simple gauge view I made a library that you can clone and use/modify for your needs.
CustomGauge
All other gauges you recommended have bugs and don't run fine on Kitkat and Lollipop. Also there is no Android Studio and gradle friendly library here.
Here's git repo for the more recent one updated for Lollipop you can use with Gradle:
https://github.com/Sulejman/GaugeView
After you include library in your project add gaugelibrary to xml layout of your activity:
<io.sule.gaugelibrary.GaugeView
android:id="#+id/gauge_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
gauge:showOuterShadow="false"
gauge:showOuterRim="false"
gauge:showInnerRim="false"
gauge:needleWidth="0.010"
gauge:needleHeight="0.40"
gauge:scaleStartValue="0"
gauge:scaleEndValue="100"
/>
This will show static gauge without needle. To instantiate needle with random animation you need to do that in activity class file. See how it's done here:
package io.sule.testapplication;
import android.app.Activity;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.view.Menu;
import android.view.MenuItem;
import java.util.Random;
import io.sule.gaugelibrary.GaugeView;
public class MainActivity extends Activity {
private GaugeView mGaugeView;
private final Random RAND = new Random();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGaugeView = (GaugeView) findViewById(R.id.gauge_view);
mTimer.start();
}
private final CountDownTimer mTimer = new CountDownTimer(30000, 1000) {
#Override
public void onTick(final long millisUntilFinished) {
mGaugeView.setTargetValue(RAND.nextInt(101));
}
#Override
public void onFinish() {}
};
}
This will instantiate needle and make it animate moving to random values.
I made this one a while ago. Feel free to clone and modify. (It takes some ideas from the old Vintage Thermometer.)
github.com/Pygmalion69/Gauge
It can easily be added to your Gradle project:
repositories {
maven {
url 'https://www.jitpack.io'
}
}
dependencies {
compile 'com.github.Pygmalion69:Gauge:1.1'
}
The views are declared in XML:
<de.nitri.gauge.Gauge
android:id="#+id/gauge1"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_gravity="center"
android:layout_marginTop="10dp"
android:layout_weight="0.75"
gauge:labelTextSize="42"
gauge:maxValue="1000"
gauge:minValue="0"
gauge:totalNicks="120"
gauge:valuePerNick="10"
gauge:upperText="Qty"
gauge:lowerText="#string/per_minute" />
Here's an example of setting the values programmatically:
final Gauge gauge1 = (Gauge) findViewById(R.id.gauge1);
final Gauge gauge2 = (Gauge) findViewById(R.id.gauge2);
final Gauge gauge3 = (Gauge) findViewById(R.id.gauge3);
final Gauge gauge4 = (Gauge) findViewById(R.id.gauge4);
gauge1.moveToValue(800);
HandlerThread thread = new HandlerThread("GaugeDemoThread");
thread.start();
Handler handler = new Handler(thread.getLooper());
handler.postDelayed(new Runnable() {
#Override
public void run() {
gauge1.moveToValue(300);
}
}, 2800);
handler.postDelayed(new Runnable() {
#Override
public void run() {
gauge1.moveToValue(550);
}
}, 5600);
HandlerThread gauge3Thread = new HandlerThread("Gauge3DemoThread");
gauge3Thread.start();
Handler gauge3Handler = new Handler(gauge3Thread.getLooper());
gauge3Handler.post(new Runnable() {
#Override
public void run() {
for (float x = 0; x <= 6; x += .1) {
float value = (float) Math.atan(x) * 20;
gauge3.moveToValue(value);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
gauge4.setValue(333);
On this site you will find some free customizable gauges.
ScComponents
Very easy to install and well documented.
For example you can have for free something like this in 5 minutes following the instruction below.
Go on the above linked website. Click the GR004 and after the popup appear click on "Download for FREE".
The library will downloaded, unzip and follow the instruction to install the library (aar file) inside your Android project.
Write this code in your XML layout and your gauge will done:
<com.sccomponents.gauges.gr004.GR004
android:layout_width="match_parent"
android:layout_height="match_parent" />
You have many XML options to customize it:
sccAnimDuration
sccEnableTouch
sccInverted
sccFontName
sccLabelsSizeAdjust
sccMajorTicks
sccMaxValue
sccMinorTicks
sccMinValue
sccShowContour
sccShowLabels
sccText
sccValue
And the related function by coding.
I don't know whether the late answer is going to help or not. I also came to the same situation where i want to use a gauge to visualize data, since gauge is not given as widget in android, as a enthusiast i went for libraries like above which can be found through various links in the Internet, although it was quite helpful(thanks to the wonderful authors of it..) i find myself difficult to visualize the during certain situations, so another solution what i have done is for my app is i integreated the JavaScript gauges into my android application.
You can do that by the following steps
Create an asset folder in our project-look this link and you will see how to create an asset folder if someone don't knows about it.
Next one is you have design an html page on how your page sholud look like, for eg- header,no.of guages etc... and place it in the folder asset.
There are many sites which provide the guages like This is one site or you can browse other sites and take whatever you feel cool...!!
take it all including .js files and place it in the asset folder.
Android provides a class for handling webiview called "WebViewClient" you can browse more to know more about it in internet
This is sample code for viewing the webview content..
web = (WebView) findViewById(R.id.webview01);
progressBar = (ProgressBar) findViewById(R.id.progressBar1);
web.setWebViewClient(new myWebClient());
web.getSettings().setJavaScriptEnabled(true);
web.post(new Runnable() {
#Override
public void run() {
web.loadUrl("file:///android_asset/fonts/guage.html");
}
});
The above for loading the html & javscript.
public class myWebClient extends WebViewClient
{
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
// TODO Auto-generated method stub
super.onPageStarted(view, url, favicon);
}
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// TODO Auto-generated method stub
progressBar.setVisibility(View.VISIBLE);
view.loadUrl(url);
return true;
}
#Override
public void onPageFinished(WebView view, String url) {
// TODO Auto-generated method stub
super.onPageFinished(view, url);
progressBar.setVisibility(View.GONE);
}
}
This the webview class
You can also send data from activity to html page.. Refer This link
Kindly read through all, corrections are welcomed..!!
Use this : Sample Project
It can easily be added to your Gradle project:
repositories {
maven {
url 'https://www.jitpack.io'
}
}
dependencies {
implementation 'com.jignesh13.speedometer:speedometer:1.0.0'
}
The views are declared in XML:
<com.jignesh13.speedometer.SpeedoMeterView
android:id="#+id/speedometerview"
android:layout_width="250dp"
android:layout_height="250dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.453"
app:layout_constraintStart_toStartOf="parent"
app:backimage="#android:color/black"
app:needlecolor="#fff"
app:removeborder="false"
app:linecolor="#fff"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.079" />