How to scan plain text QR code using Zxing Android Embedded - android

I already got a QR/Barcode Scanner which is working. But I have one problem. The scanner is only reading QR-Codes which contains an url but I want to scan QR-Codes with only text. Does somebody know what the problem could be?
the used library:
implementation 'com.journeyapps:zxing-android-embedded:3.4.0'
method:
private void scanCode() {
IntentIntegrator integrator = new IntentIntegrator(this);
integrator.setCaptureActivity(CaptureAct.class);
integrator.setOrientationLocked(false);
integrator.setDesiredBarcodeFormats(IntentIntegrator.ALL_CODE_TYPES);
integrator.setPrompt("Scanning Code");
integrator.initiateScan();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
...
}

hello you need to use follow configuration
compileSdkVersion 28 // Android 9 (API level 28)
minSdkVersion 24 // Android 7.0 (API level 24)
use dependency of google vision in build.gradle of app
implementation 'com.google.android.gms:play-services-vision:17.0.2'
this is the code for scan the qr code
cameraViewQR = findViewById(R.id.cameraView);
cameraViewQR.setZOrderMediaOverlay(true);
qrHolderScreen = cameraViewQR.getHolder();
barcodeQR = new BarcodeDetector.Builder(this)
.setBarcodeFormats(Barcode.QR_CODE)
.build();
if (!barcodeQR.isOperational()) {
Toast.makeText(getApplicationContext(), "Problem Occurred in Setup", Toast.LENGTH_SHORT).show();
this.finish();
}
cameraSourcePhone = new CameraSource.Builder(this, barcodeQR)
.setFacing(CameraSource.CAMERA_FACING_BACK)
.setRequestedFps(24)
.setAutoFocusEnabled(true)
.setRequestedPreviewSize(480, 480)
.build();
cameraViewQR.getHolder().addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceCreated(SurfaceHolder holder) {
try {
if (ContextCompat.checkSelfPermission(ScanActivity.this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
cameraSourcePhone.start(cameraViewQR.getHolder());
}
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
});
barcodeQR.setProcessor(new Detector.Processor<Barcode>() {
#Override
public void release() {
}
#Override
public void receiveDetections(Detector.Detections<Barcode> detections) {
final SparseArray<Barcode> barcode = detections.getDetectedItems();
if (barcode.size() > 0) {
Intent intent = new Intent();
intent.putExtra("QRCODE", barcode.valueAt(0));
setResult(RESULT_OK, intent);
finish();
}
}
});

Related

Xamarin Forms: Return String from Android Activity

I'm trying to develop a mobile app in Xamarin Forms...One of the functionalities is text recognition. I need to recognize the text and then send it to another page (xaml). So i made an activity where it does recognize the text but i don't know how to return the string "Resultados" (Results). I tried to do a little search and many suggested that the "OnActivityResult" should return the values...but it doesnt get triggered.
Can anyone help me out what i am doing wrong?
TextRecognition.cs - activity(android)
public class TextRecognition : AppCompatActivity, ISurfaceHolderCallback, IProcessor, ITextRecognition
{
private SurfaceView cameraView;
private TextView textView;
private CameraSource cameraSource;
public string Resultados;
private const int RequestCameraPermissionID = 1001;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.Main);
cameraView = FindViewById<SurfaceView>(Resource.Id.surface_view);
textView = FindViewById<TextView>(Resource.Id.txtview);
TextRecognizer textRecognizer = new TextRecognizer.Builder(ApplicationContext).Build();
if (!textRecognizer.IsOperational)
{
Log.Error("Main Activity", "Detector dependencies are not yet available");
}
else
{
cameraSource = new CameraSource.Builder(ApplicationContext, textRecognizer)
.SetFacing(CameraFacing.Back)
.SetRequestedFps(2.0f)
.SetRequestedPreviewSize(1280, 1024)
.SetAutoFocusEnabled(true)
.Build();
cameraView.Holder.AddCallback(this);
textRecognizer.SetProcessor(this);
}
Android.Widget.Button logonButton = FindViewById<Android.Widget.Button>(Resource.Id.button_send);
logonButton.Click += delegate {
button_OnClick();
};
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
{
switch (requestCode)
{
case RequestCameraPermissionID:
{
if (grantResults[0] == Android.Content.PM.Permission.Granted)
{
cameraSource.Start(cameraView.Holder);
}
}
break;
}
}
public void SurfaceChanged(ISurfaceHolder holder, [GeneratedEnum] Format format, int width, int height)
{
}
public void SurfaceCreated(ISurfaceHolder holder)
{
if (ActivityCompat.CheckSelfPermission(ApplicationContext, Manifest.Permission.Camera) != Android.Content.PM.Permission.Granted)
{
ActivityCompat.RequestPermissions(this, new string[]
{
Android.Manifest.Permission.Camera
}, RequestCameraPermissionID);
return;
}
cameraSource.Start(cameraView.Holder);
}
public void SurfaceDestroyed(ISurfaceHolder holder)
{
cameraSource.Stop();
}
public void ReceiveDetections(Detections detections)
{
SparseArray items = detections.DetectedItems;
if (items.Size() != 0)
{
textView.Post(() =>
{
StringBuilder strBuilder = new StringBuilder();
for (int i = 0; i < items.Size(); i++)
{
strBuilder.Append(((TextBlock)items.ValueAt(i)).Value);
strBuilder.Append("\n");
}
textView.Text = strBuilder.ToString();
Resultados = strBuilder.ToString();
});
}
}
async void button_OnClick()
{
Toast.MakeText(this, "Hello from " + Resultados, ToastLength.Long).Show();
Intent data = new Intent(this, typeof(TextRecognition));
SetResult(Result.Ok, data);
Finish();
}
public void Release()
{
}
public string LaunchActivityInAndroid()
{
Activity activity = Forms.Context as Activity;
var intent = new Intent(Forms.Context, typeof(TextRecognition));
activity.StartActivityForResult(intent, Convert.ToInt32(Result.Ok));
return Resultados;
}
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
switch(resultCode)
{
case Result.Ok:
break;
}
Finish();
}
public interface ITextRecognition
{
}
}
I tried to do a little search and many suggested that the "OnActivityResult" should return the values...but it doesnt get triggered.
You are using OnActivityResult a bit wrong. For example, if you have two Activity, ActivityA and ActivityB, OnActivityResult method in ActivityA, ActivityB need return some value to ActivityA, we can use activityA.StartActivityForResult() to open ActivityB,
ActivityB Use SetResult method to send data to ActivityA.
public class ActivityB: Activity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.Main);
Intent intent = new Intent();
intent.PutExtra("respond", "Hello,Alice!I'm Bob.");
SetResult(Result.Ok, intent);
}
}
Then OnActivityResultwill be triggered in the ActivityA.
I need to recognize the text and then send it to another page (xaml)
If you want to send data from Activity to Forms pages, You can use MessagingCenter to achieve it.
In Activity, we can use following code to send it.
MessagingCenter.Send<App, string>(App.Current as App, "OpenPage", "You send message:" + Resultados);
In the xamarin forms pages, you can use following code to get it.
MessagingCenter.Subscribe<App, string>(App.Current, "OpenPage", (snd, arg) =>
{
var getValue = arg;
});
Here is a link about MessagingCenter.
https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/messaging-center
===========update===========
I write a scan demo. Here is running gif.
Here is interface about dependenceService.
public interface ITextRecognition
{
void LaunchActivityInAndroid();
}
Here is achievement about dependenceService.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.Graphics;
using Android.OS;
using Android.Runtime;
using Android.Support.V7.App;
using Android.Views;
using Android.Widget;
using FormsTextRecognizer.Droid;
using Xamarin.Forms;
using static Android.Gms.Vision.Detector;
using Android.Gms.Vision;
using Android.Gms.Vision.Texts;
using Android.Support.V4.App;
using Android;
using Android.Content.PM;
using Android.Util;
[assembly: Dependency(typeof(TextRecognition))]
namespace FormsTextRecognizer.Droid
{
[Activity(Label = "ScanActivity", Theme = "#style/Theme.AppCompat.Light.NoActionBar")]
public class TextRecognition : AppCompatActivity, ITextRecognition, ISurfaceHolderCallback, IProcessor
{
// private CameraSource cameraSource;
private SurfaceView cameraView;
TextRecognizer textRecognizer;
private const int RequestCameraPermissionID = 1001;
private CameraSource cameraSource;
public string Resultados;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.Main);
cameraView = FindViewById<SurfaceView>(Resource.Id.surface_view);
Android.Widget.Button logonButton = FindViewById<Android.Widget.Button>(Resource.Id.button_send);
textRecognizer = new TextRecognizer.Builder(Android.App.Application.Context).Build();
// Android.Gms.Vision.Frame frame = new Android.Gms.Vision.Frame.Builder().SetBitmap(bitmap).Build();
if (!textRecognizer.IsOperational)
{
Log.Error("Main Activity", "Detector dependancies are not yet available");
}
else
{
cameraSource = new CameraSource.Builder(ApplicationContext, textRecognizer)
.SetFacing(CameraFacing.Back)
.SetRequestedFps(2.0f)
.SetRequestedPreviewSize(1920, 1080)
.SetAutoFocusEnabled(true)
.Build();
cameraView.Holder.AddCallback(this);
textRecognizer.SetProcessor(this);
}
logonButton.Click += LogonButton_Click;
}
private void LogonButton_Click(object sender, EventArgs e)
{
// throw new NotImplementedException();
Toast.MakeText(this, Resultados, ToastLength.Short).Show();
MessagingCenter.Send<App, string>(App.Current as App, "OpenPage", "You send message:" + Resultados);
Finish();
}
public void LaunchActivityInAndroid()
{
//string ScanText = "";
Activity activity = Forms.Context as Activity;
var intent = new Intent(Forms.Context, typeof(TextRecognition));
activity.StartActivity(intent);
// activity.StartActivityForResult(intent, Convert.ToInt32(Result.Ok));
// return Resultados;
}
public void ReceiveDetections(Detections detections)
{
//throw new NotImplementedException();
SparseArray items = detections.DetectedItems;
if (items.Size() != 0)
{
StringBuilder strBuilder = new StringBuilder();
for (int i = 0; i < items.Size(); i++)
{
strBuilder.Append(((TextBlock)items.ValueAt(i)).Value);
strBuilder.Append("\n");
}
// textView.Text = strBuilder.ToString();
Resultados = strBuilder.ToString();
// });
}
}
public void Release()
{
// throw new NotImplementedException();
}
public void SurfaceChanged(ISurfaceHolder holder, [GeneratedEnum] Format format, int width, int height)
{
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Permission[] grantResults)
{
switch (requestCode)
{
case RequestCameraPermissionID:
{
if (grantResults[0] == Permission.Granted)
{
cameraSource.Start(cameraView.Holder);
}
}
break;
}
}
public void SurfaceCreated(ISurfaceHolder holder)
{
//throw new NotImplementedException();
if (ActivityCompat.CheckSelfPermission(ApplicationContext, Manifest.Permission.Camera) != Android.Content.PM.Permission.Granted)
{
//Request Permission
ActivityCompat.RequestPermissions(this, new string[] {
Android.Manifest.Permission.Camera
}, RequestCameraPermissionID);
return;
}
cameraSource.Start(cameraView.Holder);
}
public void SurfaceDestroyed(ISurfaceHolder holder)
{
cameraSource.Stop();
}
}
}
Here is Forms page background code.
[DesignTimeVisible(false)]
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
MessagingCenter.Subscribe<App, string>(App.Current, "OpenPage", (snd, arg) =>
{
scanLabel.Text = arg;
});
}
private void Button_Clicked(object sender, EventArgs e)
{
DependencyService.Get<ITextRecognition>().LaunchActivityInAndroid();
}
}
Here is my demo, you can refer to it.
https://github.com/851265601/FormsTextRecognizer

How to fix "QR scanner is not scanning QR codes"?

I'm trying to develop an Android app that can scan QR codes. But the problem is, it only auto focus on the QR code but not returning any results. Is there a way to fix this?
I'm using zxing libraries.
Hello guys, can someone help me?
I guess you dont have onActivityResult in your code and that is why you cant capture and return any result.
So I am attaching my work and it would help you.
cameraView = (SurfaceView) v.findViewById(R.id.cameraView);
textResult = (TextView) v.findViewById(R.id.textView);
barcodeDetector = new BarcodeDetector.Builder(v.getContext())
.setBarcodeFormats(Barcode.QR_CODE)
.build();
cameraSource = new CameraSource.Builder(v.getContext(), barcodeDetector)
.setRequestedPreviewSize(640, 640).build();
cameraView.getHolder().addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceCreated(SurfaceHolder holder) {
if (ActivityCompat.checkSelfPermission(v.getContext(), android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
//Request permission
ActivityCompat.requestPermissions(getActivity(),
new String[]{android.Manifest.permission.CAMERA}, RequestCameraPermissionID);
return;
}
try {
cameraSource.start(cameraView.getHolder());
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
}
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
cameraSource.stop();
}
});
barcodeDetector.setProcessor(new Detector.Processor<Barcode>() {
#Override
public void release() {
}
#Override
public void receiveDetections(Detector.Detections<Barcode> detections) {
final SparseArray<Barcode> qrcodes = detections.getDetectedItems();
if (qrcodes.size() != 0) {
textResult.post(new Runnable() {
#Override
public void run() {
//Create vibrate
Vibrator vibrator = (Vibrator) getContext().getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(1000);
textResult.setText(qrcodes.valueAt(0).displayValue);
showResultDialogue(qrcodes.valueAt(0).displayValue);
}
});
}//End if Statement
}
});
Here is the onActivityResult and I think you dont have it.
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
//We will get scan results here
IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
//check for null
if (result != null) {
if (result.getContents() == null) {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(getContext());
alertDialog.setTitle("Error");
alertDialog.setMessage("Scanning Error. Please try Again");
alertDialog.show();
} else {
//show dialogue with result
showResultDialogue(result.getContents());
}
} else {
// This is important, otherwise the result will not be passed to the fragment
super.onActivityResult(requestCode, resultCode, data);
}
}
//method to construct dialogue with scan results
public void showResultDialogue(final String result) {
final AlertDialog.Builder builder;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
builder = new AlertDialog.Builder(getContext(), android.R.style.Theme_Material_Dialog_Alert);
} else {
builder = new AlertDialog.Builder(getContext());
}
//If the text of QR Code is success then Check-in Successful.
//if(result.equalsIgnoreCase("success")){
//Stop the scanner
barcodeDetector.release();
builder.setTitle("Successfully Scan QR Code")
.setMessage("Result ---> " + result)
.setPositiveButton("DONE", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(getContext(), MainActivity.class);
startActivity(intent);
//Click ok and Back to Main Page
}
}).create().show();

Read QR code and automatic direct to browser from result

I recently just started programming and developing app. I would appreciate if anybody can help me. I had did the QR scanner with ZXing and are able to display the result but i would like it to open the browser automatically if an URL is detected from the QR code
The following is my code for my Scanner Activity:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.Support.V7.App;
using Android.Views;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Widget;
using Android.Gms.Vision.Barcodes;
using Android.Gms.Vision;
using Android.Graphics;
using Android.Content.PM;
using Android.Support.V4.App;
using Android;
using static Android.Gms.Vision.Detector;
using Android.Util;
namespace com.xamarin.sample.splashscreen
{
[Activity(Label = "Scanner")]
public class Scanner : AppCompatActivity,ISurfaceHolderCallback, IProcessor
{
SurfaceView cameraPreview;
TextView txtResult;
BarcodeDetector barcodeDetector;
CameraSource cameraSource;
const int RequestCameraPermissionID = 1001;
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Permission[] grantResults)
{
switch(requestCode)
{
case RequestCameraPermissionID:
{
if (grantResults[0]==Permission.Granted)
{
if (ActivityCompat.CheckSelfPermission(ApplicationContext, Manifest.Permission.Camera) != Android.Content.PM.Permission.Granted)
{
ActivityCompat.RequestPermissions(this, new string[]
{
Manifest.Permission.Camera
}, RequestCameraPermissionID);
return;
}
try
{
cameraSource.Start(cameraPreview.Holder);
}
catch (InvalidOperationException)
{
}
}
}
break;
}
}
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.Scanner);
cameraPreview = FindViewById<SurfaceView>(Resource.Id.cameraPreview);
txtResult = FindViewById<TextView>(Resource.Id.txtResult);
barcodeDetector = new BarcodeDetector.Builder(this)
.SetBarcodeFormats(BarcodeFormat.QrCode).Build();
cameraSource = new CameraSource.Builder(this, barcodeDetector)
.SetRequestedPreviewSize(640, 480).Build();
cameraPreview.Holder.AddCallback(this);
barcodeDetector.SetProcessor(this);
}
public void SurfaceChanged(ISurfaceHolder holder, [GeneratedEnum] Format format, int width, int height)
{
}
public void SurfaceCreated(ISurfaceHolder holder)
{
if (ActivityCompat.CheckSelfPermission(ApplicationContext, Manifest.Permission.Camera) != Android.Content.PM.Permission.Granted)
{
ActivityCompat.RequestPermissions(this, new string[]
{
Manifest.Permission.Camera
}, RequestCameraPermissionID);
return;
}
try
{
cameraSource.Start(cameraPreview.Holder);
}
catch (InvalidOperationException)
{
}
}
public void SurfaceDestroyed(ISurfaceHolder holder)
{
cameraSource.Stop();
}
public void ReceiveDetections(Detections detections)
{
SparseArray qrcodes = detections.DetectedItems;
if(qrcodes.Size()!=0)
{
txtResult.Post(() =>
{
Vibrator vib = (Vibrator)GetSystemService(Context.VibratorService);
vib.Vibrate(1000);
txtResult.Text = ((Barcode)qrcodes.ValueAt(0)).RawValue;
});
}
}
public void Release()
{
}
}`enter code here`
}`enter code here`
I would like it to open the browser automatically if an URL is detected from the QR code
When you get the ZXing.Result from the QR code, you could use Patterns.WebUrl.Matcher method to confirm whether this is a URL.
When you use Patterns.WebUrl.Matcher(result.Text).Matches() method, this regular expression pattern to match most part of RFC 3987 Internationalized URLs, aka IRIs.
Code like this :
private void HandleScanResult(ZXing.Result result)
{
string msg = "";
if (result != null && !string.IsNullOrEmpty(result.Text))
msg = "Found Barcode: " + result.Text;
else
msg = "Scanning Canceled!";
Intent resultIntent = new Intent();
Bundle bundle = new Bundle();
bundle.PutString("result", result.Text);
resultIntent.PutExtras(bundle);
this.SetResult(Result.Ok, resultIntent);
if (Patterns.WebUrl.Matcher(result.Text).Matches())
{
//If this result get from the QR code is an URL, open the browse.
Intent intent = new Intent();
intent.SetAction("android.intent.action.VIEW");
Android.Net.Uri content_url = Android.Net.Uri.Parse(result.Text);
intent.SetData(content_url);
StartActivity(intent);
}
else
{
this.RunOnUiThread(() => Toast.MakeText(this, msg, ToastLength.Short).Show());
}
}

onActivityResult not calling in Fragment's

Hi I am new for android and in my app I am using Z-bar library for scanning barcode.
For this I am using ZbarScannerActivity class like below, so after scanning the barcode I am getting those barcode results where ever I want using onActivityResult method.
Here my problem is when I am scanning the barcode I want to get this result in my Fragment, but here onActivityResult not calling in my Fragment.
But it's calling in my Activities please help me.
How can I solve this problem?
ZbarScanner Activity:-
public class ZBarScannerActivity extends ActionBarActivity {
private Camera mCamera;
private CameraPreview mPreview;
private Handler autoFocusHandler;
ImageScanner scanner;
ImageView backButton;
private boolean barcodeScanned = false;
private boolean previewing = true;
CustomTextview navigation_title;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scanner_view_layout);
ActionBar actionBar = getSupportActionBar();
String header = "<font color=\"#ffffff\">" + "BarCode Scanner"
+ " </font>";
CommonUtils.actionbarHeader(this, actionBar, header);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
autoFocusHandler = new Handler();
mCamera = getCameraInstance();
/* Instance barcode scanner */
scanner = new ImageScanner();
scanner.setConfig(0, Config.X_DENSITY, 3);
scanner.setConfig(0, Config.Y_DENSITY, 3);
mPreview = new CameraPreview(this, mCamera, previewCb, autoFocusCB);
FrameLayout preview = (FrameLayout) findViewById(R.id.cameraPreview);
preview.addView(mPreview);
navigation_title = (CustomTextview)findViewById(R.id.navigationTitle_id);
navigation_title.setText("Barcode Scanner");
backButton = (ImageView)findViewById(R.id.navigationbackbutton_id);
backButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
}
static {
System.loadLibrary("iconv");
}
public void onPause() {
super.onPause();
releaseCamera();
}
/** A safe way to get an instance of the Camera object. */
public static Camera getCameraInstance() {
Camera c = null;
try {
c = Camera.open();
} catch (Exception e) {
}
return c;
}
private void releaseCamera() {
if (mCamera != null) {
previewing = false;
mCamera.setPreviewCallback(null);
mCamera.release();
mCamera = null;
}
}
private Runnable doAutoFocus = new Runnable() {
public void run() {
if (previewing)
mCamera.autoFocus(autoFocusCB);
}
};
PreviewCallback previewCb = new PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera camera) {
Camera.Parameters parameters = camera.getParameters();
Size size = parameters.getPreviewSize();
Image barcode = new Image(size.width, size.height, "Y800");
barcode.setData(data);
int result = scanner.scanImage(barcode);
if (result != 0) {
previewing = false;
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
SymbolSet syms = scanner.getResults();
for (Symbol sym : syms) {
System.out.println("------->"+sym.getData());
barcodeScanned = true;
finishActivivtyWithResult(sym.getData());
}
}
}
};
// Mimic continuous auto-focusing
AutoFocusCallback autoFocusCB = new AutoFocusCallback() {
public void onAutoFocus(boolean success, Camera camera) {
autoFocusHandler.postDelayed(doAutoFocus, 1000);
}
};
/**
*
* #param barCodeResult
*/
private void finishActivivtyWithResult(String barCodeResult){
if (barCodeResult.contains("//b")) {
String replacedString = barCodeResult.replace("//b", "");
System.out.println("One========>" + replacedString);
barCodeResult = replacedString;
}
if (barCodeResult.contains("/t")) {
String replacedString = barCodeResult.replace("/t", "-");
System.out.println("After========>" + replacedString);
barCodeResult = replacedString;
}
Bundle conData = new Bundle();
conData.putString("barCodeResult", barCodeResult);
Intent intent = new Intent();
intent.putExtras(conData);
setResult(RESULT_OK, intent);
finish();
}
#Override
public boolean onSupportNavigateUp() {
finish();
return true;
}
}
my fragment:-
//Camera Button Action Event:-
/**
* #return
*/
private View.OnClickListener cameraDetails() {
return new View.OnClickListener() {
#Override
public void onClick(View v) {
BAR_CODE_SCANNER_CODE = 100;
checkCameraPermission();
}
};
}
//BarCode Scanner Result:-
private void checkCameraPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
checkManifestPermissionSets();
} else {
scanProductCode();
}
}
#TargetApi(23)
private void checkManifestPermissionSets() {
int cameraPermission = ContextCompat.checkSelfPermission(getActivity(),
Manifest.permission.CAMERA);
List<String> permissions = new ArrayList<String>();
if (cameraPermission != PackageManager.PERMISSION_GRANTED) {
permissions.add(Manifest.permission.CAMERA);
}
if (!permissions.isEmpty()) {
requestPermissions(
permissions.toArray(new String[permissions.size()]),
REQUEST_CODE_SOME_FEATURES_PERMISSIONS);
} else {
scanProductCode();
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE_SOME_FEATURES_PERMISSIONS: {
for (int i = 0; i < permissions.length; i++) {
if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
//Log.d("Permissions", "Permission Granted: "+ permissions[i]);
scanProductCode();
break;
} else if (grantResults[i] == PackageManager.PERMISSION_DENIED) {
//Log.d("Permissions", "Permission Denied: " + permissions[i]);
//CommonUtils.showToastMessage(StockTransfer.this, "You've disabled the App required Permissions");
break;
}
}
}
break;
default: {
super.onRequestPermissionsResult(requestCode, permissions,
grantResults);
}
}
}
private void scanProductCode() {
if (isCameraAvailable()) {
CommonUtils.showToastMessage(getActivity(),
"Please Scan Your Product BarCode");
callThreadScannerActivity();
} else {
Toast.makeText(getActivity(), "Rear Facing Camera Unavailable",
Toast.LENGTH_SHORT).show();
}
}
private void callThreadScannerActivity() {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
// dialog.dismiss();
callScannerActivity();
}
}, 700);
}
// Call Scanner Activity:-
private void callScannerActivity() {
Intent intent = new Intent(getActivity(), ZBarScannerActivity.class);
startActivityForResult(intent, BAR_CODE_SCANNER_CODE);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
System.out.println("result code------>" + requestCode);
}
private boolean isCameraAvailable() {
PackageManager pm = getActivity().getPackageManager();
return pm.hasSystemFeature(PackageManager.FEATURE_CAMERA);
}
}
Simple logic connected to general life
activity : father(parent)
fragment : child
if child wanna money than he ask to him/ her father.
technical way if fragment(child) wanna data from onActivityResult it always VIA Activity(father).
ohk .. lets look on code side
stuff at
yourActivity (Parent)
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
try {
List<Fragment> fragments = getSupportFragmentManager().getFragments();
if (fragments != null) {
for (Fragment fragment : fragments) {
fragment.onActivityResult(requestCode, resultCode, data);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
this list of fragment(child) of activity said to him activity(father) for data
when activity received data it gives as fragments(childs) demands.
In fragment whenever we start activity for any result then that result in received in onActivityResult of activity then we have to pass this result to fragment's onActivityResult
Write this to your activitys's onActivityResult
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Logg.e("RESULT ", " " + resultCode);
if (resultCode != RESULT_OK)
return;
switch (requestCode) {
case 100:
Fragment YourRfargment= getFragmentManager().findFragmentByTag("Your Fragment TAG");
updateproFragment.onActivityResult(requestCode, resultCode, data);
break;
}
}
by this you will get your result in fragment's onActivityresult.

Android: NPE happens when getting picture from camera

I have a problem on my Android app. I'm using MediaStore.ACTION_IMAGE_CAPTURE intent to take picture from camera. It worked all most of devices but I got the following crash errors on DroidX device from android market.
I think imageCaptureUri can not be null in this case. So it is not the cause.
Do you have any ideas? Is it a firmware error?
java.lang.NullPointerException at
android.content.ContentResolver.openInputStream(ContentResolver.java:286)
at
com.eb.android.activity.AddActivity.getBase64Receipt(AddActivity.java:193)
at
com.eb.android.activity.AddActivity.publishReceipt(AddActivity.java:204)
at com.eb.android.activity.AddActivity.access$0(AddActivity.java:203)
at com.eb.android.activity.AddActivity$1.run(AddActivity.java:50) at
java.lang.Thread.run(Thread.java:1102)
java.lang.NullPointerException at
android.content.ContentResolver.openInputStream(ContentResolver.java:288)
at
com.eb.android.activity.AddActivity.getBase64Receipt(AddActivity.java:193)
at
com.eb.android.activity.AddActivity.publishReceipt(AddActivity.java:204)
at com.eb.android.activity.AddActivity.access$0(AddActivity.java:203)
at com.eb.android.activity.AddActivity$1.run(AddActivity.java:50) at
java.lang.Thread.run(Thread.java:1096)
This is my implementation:
public class AddActivity extends Activity {
public static final int TAKE_RECEIPT = 2;
private Uri imageCaptureUri;
private Runnable submitReceiptRunnable = new Runnable() {
public void run() {
publishReceipt();
}
};
private ProgressDialog progressDialog;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.add);
registerListeners();
}
public void onActivityResult(int reqCode, int resultCode, Intent data) {
super.onActivityResult(reqCode, resultCode, data);
switch (reqCode) {
case (TAKE_RECEIPT):
takeReceiptCallback(resultCode, data);
break;
}
}
private void registerListeners() {
ImageView addReceiptButton = (ImageView) findViewById(R.id.AddReceiptButton);
addReceiptButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
takePictureFromCamera();
}
});
}
private void takePictureFromCamera() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
imageCaptureUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(), "tmp_receipt_"
+ String.valueOf(System.currentTimeMillis()) + ".jpg"));
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, imageCaptureUri);
intent.putExtra("return-data", true);
startActivityForResult(intent, TAKE_RECEIPT);
}
private void takeReceiptCallback(int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
submitReceipt();
}
}
private void submitReceipt() {
Thread thread = new Thread(null, submitReceiptRunnable);
thread.start();
progressDialog = ProgressDialog.show(this, "Please wait...", "Publishing receipt ...", true);
}
private String getBase64Receipt() {
try {
InputStream inputStream = getContentResolver().openInputStream(imageCaptureUri);
byte[] bytes = CommonUtil.getBytesFromInputStream(inputStream);
return Base64.encodeBytes(bytes);
} catch (IOException e) {
Log.e(TAG, e.getMessage(), e);
}
return null;
}
private void publishReceipt() {
String receipt = getBase64Receipt();
...
}
}
Are you sure that image crop mode forcing
intent.putExtra("return-data", true);
works correctly for the device you use. Correct me if I am wrong, but it is not safe and not well documented approach. Here you can find example of working code without cropping.
UPDATE: Issue you are facing with has long history, also at SO:
https://stackoverflow.com/questions/3904685/unable-to-find-com-android-camera-cropimage-activity-in-android
Issue I experienced was using crop immediatelly after image was taken by the camera. Also, it is not compatible through different Android versions, so if you get it working for 1.5 maybe it will not work for 2.3. Definitely something is wrong, as may be concluded from the Android Developer Group posts:
http://groups.google.com/group/android-developers/browse_thread/thread/2dd647523926192c/569f36b5b28f2661?lnk=gst&q=Crop+image+intent#569f36b5b28f2661
http://groups.google.com/group/android-developers/browse_thread/thread/2dd647523926192c/dcbe5aef29eddad6?lnk=gst&q=Crop+image+intent#dcbe5aef29eddad6
http://groups.google.com/group/android-developers/browse_thread/thread/d7b6a133c164aa17/184bf3b85da2ce58?lnk=gst&q=Crop+image+intent#184bf3b85da2ce58

Categories

Resources