Using camera with thread - android

I am trying get the image of the camera and process it continuous, so, I am using CameraKit package:
package com.example.alex.tfmobile;
import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.HandlerThread;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import com.camerakit.CameraKitView;
import java.io.InputStream;
public class MainActivity extends AppCompatActivity {
private HandlerThread backgroundThread;
private Handler backgroundHandler;
private final Object lock = new Object();
private boolean runClassifier = false;
private static final String HANDLE_THREAD_NAME = "CameraBackground";
TextView resultView;
private CameraKitView cameraView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
cameraView = (CameraKitView) findViewById(R.id.camera);
resultView = (TextView) findViewById(R.id.results);
startBackgroundThread();
}
#Override
protected void onResume() {
super.onResume();
cameraView.onResume();
startBackgroundThread();
}
#Override
protected void onPause() {
cameraView.onPause();
stopBackgroundThread();
super.onPause();
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
cameraView.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
private void startBackgroundThread() {
backgroundThread = new HandlerThread(HANDLE_THREAD_NAME);
backgroundThread.start();
backgroundHandler = new Handler(backgroundThread.getLooper());
synchronized (lock) {
runClassifier = true;
}
backgroundHandler.post(periodicClassify);
}
private Runnable periodicClassify =
new Runnable() {
#Override
public void run() {
synchronized (lock) {
if (runClassifier) {
classifyFrame();
}
}
backgroundHandler.post(periodicClassify);
}
};
private void classifyFrame() {
cameraView.captureImage(new CameraKitView.ImageCallback() {
#Override
public void onImage(CameraKitView cameraKitView, final byte[] picture) {
Bitmap bitmap = BitmapFactory.decodeByteArray(picture, 0, picture.length);
}
});
}
private void stopBackgroundThread() {
backgroundThread.quitSafely();
try {
backgroundThread.join();
backgroundThread = null;
backgroundHandler = null;
synchronized (lock) {
runClassifier = false;
}
} catch (InterruptedException e) {
Log.e("TfMobile", "Interrupted when stopping background thread", e);
}
}
}
Layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.camerakit.CameraKitView
android:id="#+id/camera"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:camera_facing="back"/>
<TextView
android:id="#+id/results"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
But the problem is in classifyFrame method, when I try to access the variable cameraView, it thrown an exception of Null pointer. I would like to know how can I use the camera with a thread to process the frames.
The error:
Process: com.example.alex.tfmobile, PID: 26659
java.lang.NullPointerException: Attempt to invoke virtual method 'int com.camerakit.CameraKitView$Size.getWidth()' on a null object reference
at com.camerakit.CameraKitView$Camera2$1$7.run(CameraKitView.java:1844)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.os.HandlerThread.run(HandlerThread.java:61)
10-06 02:07:29.848 26659-26659/? E/ViewRootImpl#3b4860a[MainActivity]: ViewRootImpl #2 Surface is not valid.

It looks you are trying to access it before surface prepare, You could try to comment out startBackgroundThread(); from onCreate. You are already calling it from onResume. Hope it should work or you can wait till surface prepared.

Related

Is there any way to remove this nullobject reference error? I am trying to open a bottom dialog from scanner activity

Error:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.swiftpass, PID: 16875
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
at com.example.swiftpass.ScanPopUpDialog.setPrompt(ScanPopUpDialog.java:47)
at com.example.swiftpass.ScanQrActivity$MyImageAnalyzer.readerBarcodeData(ScanQrActivity.java:170)
at com.example.swiftpass.ScanQrActivity$MyImageAnalyzer.access$200(ScanQrActivity.java:109)
at com.example.swiftpass.ScanQrActivity$MyImageAnalyzer$3.onSuccess(ScanQrActivity.java:142)
at com.example.swiftpass.ScanQrActivity$MyImageAnalyzer$3.onSuccess(ScanQrActivity.java:138)
at com.google.android.gms.tasks.zzn.run(com.google.android.gms:play-services-tasks##17.2.0:4)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6944)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
XML Code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/img_close"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:src="#drawable/ic_close">
</ImageView>
<TextView
android:id="#+id/txt_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="6dp"
android:text="#string/qr_type"
android:fontFamily="#font/roboto_black"
android:textSize="20dp">
</TextView>
<TextView
android:id="#+id/txt_prompt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="50dp"
android:layout_marginBottom="10dp"
android:text="#string/qr_prompt"
android:fontFamily="#font/roboto_medium"
android:textSize="18dp">
</TextView>
</RelativeLayout>
</LinearLayout>
Bottom dialog java:
package com.example.swiftpass;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
public class ScanPopUpDialog extends BottomSheetDialogFragment {
//Declaration of Variables
TextView type;
TextView prompt;
ImageView close;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.pop_up_dialog, container, false);
type = view.findViewById(R.id.txt_type);
prompt = view.findViewById(R.id.txt_prompt);
close = view.findViewById(R.id.img_close);
close.setOnClickListener(this::OnClick);
return view;
}
//This function will listen to button clicks and will call certain functions according to what is pressed by the user
private void OnClick(View view) {
switch(view.getId()){
case R.id.img_close:
dismiss();
break;
case R.id.txt_prompt:
break;
}
}
public void setPrompt(String type, String prompt){
this.type.setText(type);
this.prompt.setText(prompt);
if (type == "TEXT"){
this.prompt.setOnClickListener(this::OnClick);
}
}
}
Scanner Activity java:
package com.example.swiftpass;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.ImageAnalysis;
import androidx.camera.core.ImageCapture;
import androidx.camera.core.ImageProxy;
import androidx.camera.core.Preview;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.camera.view.PreviewView;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.FragmentManager;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.pm.PackageManager;
import android.graphics.Point;
import android.graphics.Rect;
import android.media.Image;
import android.os.Bundle;
import android.util.Size;
import android.widget.Toast;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.mlkit.vision.barcode.Barcode;
import com.google.mlkit.vision.barcode.BarcodeScanner;
import com.google.mlkit.vision.barcode.BarcodeScannerOptions;
import com.google.mlkit.vision.barcode.BarcodeScanning;
import com.google.mlkit.vision.common.InputImage;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ScanQrActivity extends AppCompatActivity {
//Declaration of Variables
private ListenableFuture cameraProviderFuture;
private ExecutorService cameraExecutor;
private PreviewView previewView;
private MyImageAnalyzer analyzer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scan_qr);
//Assigning of widgets and Setting up of listeners
initializeScan();
cameraProviderFuture.addListener(new Runnable() {
#Override
public void run() {
try {
if (ActivityCompat.checkSelfPermission(ScanQrActivity.this, Manifest.permission.CAMERA) != (PackageManager.PERMISSION_GRANTED)){
ActivityCompat.requestPermissions(ScanQrActivity.this, new String [] {Manifest.permission.CAMERA}, 101);
}else{
ProcessCameraProvider processCameraProvider = (ProcessCameraProvider) cameraProviderFuture.get();
bindPreview(processCameraProvider);
}
}catch (ExecutionException e){
e.printStackTrace();
}catch (InterruptedException e){
e.printStackTrace();
}
}
}, ContextCompat.getMainExecutor(this));
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if (requestCode == 101 && grantResults.length > 0){
ProcessCameraProvider processCameraProvider = null;
try {
processCameraProvider = (ProcessCameraProvider) cameraProviderFuture.get();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
bindPreview(processCameraProvider);
}
}
private void bindPreview(ProcessCameraProvider processCameraProvider) {
Preview preview = new Preview.Builder().build();
CameraSelector cameraSelector = new CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_BACK).build();
preview.setSurfaceProvider(previewView.getSurfaceProvider());
ImageCapture imageCapture = new ImageCapture.Builder().build();
ImageAnalysis imageAnalysis = new ImageAnalysis.Builder()
.setTargetResolution(new Size(1280, 720))
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
.build();
imageAnalysis.setAnalyzer(cameraExecutor, analyzer);
processCameraProvider.unbindAll();
processCameraProvider.bindToLifecycle(this,cameraSelector, preview, imageCapture, imageAnalysis);
}
public class MyImageAnalyzer implements ImageAnalysis.Analyzer{
private FragmentManager fragmentManager;
private ScanPopUpDialog bottomDialog;
public MyImageAnalyzer(FragmentManager fragmentManager){
this.fragmentManager = fragmentManager;
bottomDialog = new ScanPopUpDialog();
}
#Override
public void analyze(#NonNull ImageProxy imageProxy) {
scanBarcode(imageProxy);
}
private void scanBarcode(ImageProxy imageProxy) {
BarcodeScannerOptions options =
new BarcodeScannerOptions.Builder()
.setBarcodeFormats(
Barcode.FORMAT_QR_CODE)
.build();
#SuppressLint("UnsafeExperimentalUsageError") Image mediaImage = imageProxy.getImage();
assert mediaImage != null;
InputImage inputImage =
InputImage.fromMediaImage(mediaImage, imageProxy.getImageInfo().getRotationDegrees());
BarcodeScanner scanner = BarcodeScanning.getClient(options);
Task<List<Barcode>> result = scanner.process(inputImage)
.addOnSuccessListener(new OnSuccessListener<List<Barcode>>() {
#Override
public void onSuccess(List<Barcode> barcodes) {
// Task completed successfully
readerBarcodeData(barcodes);
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
// Task failed with an exception
// ...
e.printStackTrace();
}
})
.addOnCompleteListener(new OnCompleteListener<List<Barcode>>() {
#Override
public void onComplete(#NonNull Task<List<Barcode>> task) {
imageProxy.close();
}
});
}
private void readerBarcodeData(List<Barcode> barcodes) {
for (Barcode barcode: barcodes) {
Rect bounds = barcode.getBoundingBox();
Point[] corners = barcode.getCornerPoints();
String rawValue = barcode.getRawValue();
int valueType = barcode.getValueType();
switch (valueType){
case Barcode.TYPE_TEXT:
bottomDialog.setPrompt(rawValue, "CLICK TO CONFIRM");
break;
case Barcode.TYPE_CALENDAR_EVENT:
bottomDialog.setPrompt("Calendar Event", "Unsupported Type");
break;
case Barcode.TYPE_CONTACT_INFO:
bottomDialog.setPrompt("Contact Info", "Unsupported Type");
break;
case Barcode.TYPE_DRIVER_LICENSE:
bottomDialog.setPrompt("Driver's License", "Unsupported Type");
break;
case Barcode.TYPE_EMAIL:
bottomDialog.setPrompt("E-mail", "Unsupported Type");
break;
case Barcode.TYPE_GEO:
bottomDialog.setPrompt("Location", "Unsupported Type");
break;
case Barcode.TYPE_ISBN:
bottomDialog.setPrompt("Book Number", "Unsupported Type");
break;
case Barcode.TYPE_PHONE:
bottomDialog.setPrompt("Phone", "Unsupported Type");
break;
case Barcode.TYPE_PRODUCT:
bottomDialog.setPrompt("Product", "Unsupported Type");
break;
case Barcode.TYPE_SMS:
bottomDialog.setPrompt("SMS", "Unsupported Type");
break;
case Barcode.TYPE_URL:
bottomDialog.setPrompt("Link", "Unsupported Type");
break;
case Barcode.TYPE_WIFI:
bottomDialog.setPrompt("Wi-Fi", "Unsupported Type");
break;
default:
bottomDialog.setPrompt("Uknown", "Uknown Type");
}
if (!bottomDialog.isAdded()){
bottomDialog.show(fragmentManager, "");
}
}
}
}
private void initializeScan() {
previewView = findViewById(R.id.previewView);
this.getWindow().setFlags(1024,1024);
cameraExecutor = Executors.newSingleThreadExecutor();
cameraProviderFuture = ProcessCameraProvider.getInstance(this);
analyzer = new MyImageAnalyzer(getSupportFragmentManager());
}
}
I solved it and the code goes like this:
package com.example.swiftpass;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
public class ScanPopUpDialog extends BottomSheetDialogFragment {
//Declaration of Variables
TextView type;
TextView prompt;
ImageView close;
String stringType;
String stringPrompt;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.pop_up_dialog, container, false);
type = view.findViewById(R.id.txt_type);
type.setText(getStringType());
prompt = view.findViewById(R.id.txt_prompt);
prompt.setText(getStringPrompt());
if (stringPrompt == "CLICK TO CONFIRM"){
prompt.setOnClickListener(this::OnClick);
}
close = view.findViewById(R.id.img_close);
close.setOnClickListener(this::OnClick);
return view;
}
//This function will listen to button clicks and will call certain functions according to what is pressed by the user
private void OnClick(View view) {
switch(view.getId()){
case R.id.img_close:
dismiss();
break;
case R.id.txt_prompt:
break;
}
}
public void setDialog(String type, String prompt){
/**
* This method is public because it is being called fron the scan qr activity
* this will set the value for the objects stringType and stringPrompt
* this does not return any value thus, the values will be accessed through
* get method
*/
stringType = type;
stringPrompt = prompt;
}
/**
*These methods are used to access the value set by the setDialog method
*
*/
private String getStringType(){
return stringType;
}
private String getStringPrompt(){
return stringPrompt;
}
}

Unexpected behaviour of MediaPlayer Android

I am trying to stream mp3 file from the internet. App successfully started but showing unexpected behavior. The playback doesn't play sound, the play button doesn't changes its icon. The playback stops after showing "please wait message" when it is expected to play the file on clicking the play icon.
Here's my code:
MainActivity.java
import androidx.appcompat.app.AppCompatActivity;
import android.annotation.SuppressLint;
import android.app.ProgressDialog;
import android.media.MediaPlayer;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageButton;
import android.widget.SeekBar;
import android.widget.TextView;
import java.util.concurrent.TimeUnit;
import dyanamitechetan.vusikview.VusikView;
public class MainActivity extends AppCompatActivity implements MediaPlayer.OnBufferingUpdateListener, MediaPlayer.OnCompletionListener {
ImageButton imageButton;
SeekBar seekBar;
TextView textView;
VusikView musicView;
MediaPlayer mediaPlayer;
int mediaFileLength;
int realTimeLength;
final Handler handler = new Handler();
#SuppressLint("ClickableViewAccessibility")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
musicView = findViewById(R.id.musicView);
seekBar = findViewById(R.id.seekbar);
seekBar.setMax(99);
seekBar.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if(mediaPlayer.isPlaying()){
SeekBar seekBar = (SeekBar) view;
int playPosition = (mediaFileLength/100)*seekBar.getProgress();
mediaPlayer.seekTo(playPosition);
}
return false;
}
});
imageButton = findViewById(R.id.btn_play_pause);
imageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
final ProgressDialog mDialog = new ProgressDialog(MainActivity.this);
AsyncTask<String,String,String>mp3Play = new AsyncTask<String, String, String>() {
#Override
protected void onPreExecute(){
mDialog.setMessage("Please wait");
mDialog.show();
}
#Override
protected String doInBackground(String... strings) {
try {
mediaPlayer.setDataSource(strings[0]);
mediaPlayer.prepare();
}
catch (Exception ex){
}
return "";
}
#Override
protected void onPostExecute(String s) {
mediaFileLength = mediaPlayer.getDuration();
realTimeLength = mediaFileLength;
if(!mediaPlayer.isPlaying()){
mediaPlayer.start();
imageButton.setImageResource(R.drawable.ic_pause);
} else {
mediaPlayer.pause();
imageButton.setImageResource(R.drawable.ic_play);
}
updateSeekBar();
mDialog.dismiss();
}
};
mp3Play.execute("https://soundcloud.com/theastonshuffle/nasa-feat-kanye-west-santogold-lykke-li-gifted-aston-shuffle-long-mix");
musicView.start();
}
});
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnBufferingUpdateListener(this);
mediaPlayer.setOnCompletionListener(this);
}
private void updateSeekBar() {
seekBar.setProgress((int)((float)mediaPlayer.getCurrentPosition() / mediaFileLength*100));
if(mediaPlayer.isPlaying()){
Runnable updater = new Runnable() {
#Override
public void run() {
updateSeekBar();
realTimeLength-=1000;
textView.setText(String.format("%d:%d", TimeUnit.MILLISECONDS.toMinutes(realTimeLength),
TimeUnit.MILLISECONDS.toSeconds(realTimeLength) -
TimeUnit.MILLISECONDS.toSeconds(TimeUnit.MILLISECONDS.toMinutes(realTimeLength))));
}
};
handler.postDelayed(updater,1000);
}
}
#Override
public void onBufferingUpdate(MediaPlayer mediaPlayer, int i) {
seekBar.setSecondaryProgress(i);
}
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
imageButton.setImageResource(R.drawable.ic_play);
musicView.stopNotesFall();
}
}
activity_main.xml
<dyanamitechetan.vusikview.VusikView
android:id="#+id/musicView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<RelativeLayout
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/textTimer"
android:layout_centerHorizontal="true"
android:text="00:00"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ImageButton
android:layout_below="#id/textTimer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/btn_play_pause"
android:src="#drawable/ic_play"/>
<SeekBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/btn_play_pause"
android:id="#+id/seekbar"/>
</RelativeLayout>
you APP connect Internet ?
please check manifest is add internet permission
You can use the mediaplay.setdataSource (url);method directly to load
And setmediaplay.prepareAsync (); use asynchronous method to load music
No need to use AsyncTask

Android zxing Embedded BarcodeView not resuming

In my android app I use a Fragment (CameraFragment see below) which uses a BarcodeView. When a Barcode is scanned(BarcodeCallBack) I check if it fits a pattern and if not I want to resume the scanning, but this does not work. The camera keeps running but no Barcode is scanned. As a quickfix I replace the entire Fragment but this is not how it has to be...
The Fragment:
package com.stickydata;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Vibrator;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.amazonaws.mobile.AWSMobileClient;
import com.amazonaws.mobilehelper.auth.IdentityManager;
import com.google.zxing.ResultPoint;
import com.journeyapps.barcodescanner.BarcodeCallback;
import com.journeyapps.barcodescanner.BarcodeResult;
import com.journeyapps.barcodescanner.BarcodeView;
import com.stickydata.AWSUtil.SDtagUtil;
import com.stickydata.events.EventResumeBarcodeScan;
import org.greenrobot.eventbus.EventBus;
import java.util.List;
import static com.facebook.FacebookSdk.getApplicationContext;
public class CameraFragment extends Fragment {
private IdentityManager identityManager;
Context mcontext;
private BarcodeView barcodeView;
final int PERMISSIONS_REQUEST_ACCESS_CAMERA=0;
View view;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view=inflater.inflate(R.layout.fragment_camera, container, false);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
getActivity().checkSelfPermission(Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.CAMERA},
PERMISSIONS_REQUEST_ACCESS_CAMERA);
} else {
barcodeView = (BarcodeView) view.findViewById(R.id.barcode_scanner);
barcodeView.decodeSingle(callback);
}
mcontext=getContext();
return view;
}
#Override
public void onResume() {
super.onResume();
barcodeView = (BarcodeView) view.findViewById(R.id.barcode_scanner);
barcodeView.resume();
barcodeView.decodeSingle(callback);
}
#Override
public void onPause() {
super.onPause();
barcodeView = (BarcodeView) view.findViewById(R.id.barcode_scanner);
barcodeView.pause();
}
private BarcodeCallback callback = new BarcodeCallback() {
#Override
public void barcodeResult(BarcodeResult result) {
if (result.getText() != null) {
barcodeView.pause();
//the vibrator on success
Vibrator v = (Vibrator) getApplicationContext().getSystemService(Context.VIBRATOR_SERVICE);
// Vibrate for 500 milliseconds
v.vibrate(200);
//after the string has been read we prozess it
String tag_string=result.getText();
AWSMobileClient.initializeMobileClientIfNecessary(getApplicationContext());
// Obtain a reference to the mobile client. It is created in the Application class.
final AWSMobileClient awsMobileClient = AWSMobileClient.defaultMobileClient();
// Obtain a reference to the identity manager.
identityManager = awsMobileClient.getIdentityManager();
SDtagUtil sdTag=new SDtagUtil(tag_string,identityManager,awsMobileClient,mcontext);
if(!sdTag.prozessTag()){//if the tag was not scanned succesfully let us start the scan again
EventBus.getDefault().post(new EventResumeBarcodeScan("bla"));
//TODO NOT WORKING
// barcodeView.resume();
// barcodeView.decodeSingle(callback);
}
}
}
#Override
public void possibleResultPoints(List<ResultPoint> resultPoints) {
}
};
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PERMISSIONS_REQUEST_ACCESS_CAMERA|| grantResults!=null) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
barcodeView = (BarcodeView) view.findViewById(R.id.barcode_scanner);
barcodeView.decodeContinuous(callback);
}
}
}
}
The fragment xml file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.journeyapps.barcodescanner.BarcodeView
android:id="#+id/barcode_scanner"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:zxing_use_texture_view="true"
app:zxing_preview_scaling_strategy="fitCenter"/>
</LinearLayout>
Changed to decodeContinous as suggested. The problem remains:
package com.stickydata;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Vibrator;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.amazonaws.mobile.AWSMobileClient;
import com.amazonaws.mobilehelper.auth.IdentityManager;
import com.google.zxing.ResultPoint;
import com.journeyapps.barcodescanner.BarcodeCallback;
import com.journeyapps.barcodescanner.BarcodeResult;
import com.journeyapps.barcodescanner.BarcodeView;
import com.stickydata.AWSUtil.SDtagUtil;
import com.stickydata.events.EventResumeBarcodeScan;
import org.greenrobot.eventbus.EventBus;
import java.util.List;
import static com.facebook.FacebookSdk.getApplicationContext;
public class CameraFragment extends Fragment {
private IdentityManager identityManager;
Context mcontext;
private BarcodeView barcodeView;
final int PERMISSIONS_REQUEST_ACCESS_CAMERA=0;
View view;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view=inflater.inflate(R.layout.fragment_camera, container, false);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
getActivity().checkSelfPermission(Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.CAMERA},
PERMISSIONS_REQUEST_ACCESS_CAMERA);
} else {
barcodeView = (BarcodeView) view.findViewById(R.id.barcode_scanner);
barcodeView.decodeContinuous(callback);
}
mcontext=getContext();
return view;
}
#Override
public void onResume() {
super.onResume();
barcodeView = (BarcodeView) view.findViewById(R.id.barcode_scanner);
barcodeView.resume();
barcodeView.decodeContinuous(callback);
}
#Override
public void onPause() {
super.onPause();
barcodeView = (BarcodeView) view.findViewById(R.id.barcode_scanner);
barcodeView.pause();
}
private BarcodeCallback callback = new BarcodeCallback() {
#Override
public void barcodeResult(BarcodeResult result) {
if (result.getText() != null) {
barcodeView.pause();
//the vibrator on success
Vibrator v = (Vibrator) getApplicationContext().getSystemService(Context.VIBRATOR_SERVICE);
// Vibrate for 500 milliseconds
v.vibrate(200);
//after the string has been read we prozess it
String tag_string=result.getText();
AWSMobileClient.initializeMobileClientIfNecessary(getApplicationContext());
// Obtain a reference to the mobile client. It is created in the Application class.
final AWSMobileClient awsMobileClient = AWSMobileClient.defaultMobileClient();
// Obtain a reference to the identity manager.
identityManager = awsMobileClient.getIdentityManager();
SDtagUtil sdTag=new SDtagUtil(tag_string,identityManager,awsMobileClient,mcontext);
if(!sdTag.prozessTag()){//if the tag was not scanned succesfully let us start the scan again
// EventBus.getDefault().post(new EventResumeBarcodeScan("bla"));
//TODO NOT WORKING
barcodeView.resume();
barcodeView.decodeContinuous(callback);
}
}
}
#Override
public void possibleResultPoints(List<ResultPoint> resultPoints) {
}
};
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PERMISSIONS_REQUEST_ACCESS_CAMERA|| grantResults!=null) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
barcodeView = (BarcodeView) view.findViewById(R.id.barcode_scanner);
barcodeView.decodeContinuous(callback);
}
}
}
}
Hi user1406731 you are using the wrong callback, we do something similar in our mobile app. Replace your decodeSingle() callback function with decodeContinuous() callback and it should work. Here is a working example from the official doc Continous Callback example. Hope it helps you.
Hi i tried to run your code & made a little change. This is what i tested and works fine for me
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.google.zxing.ResultPoint;
import com.journeyapps.barcodescanner.BarcodeCallback;
import com.journeyapps.barcodescanner.BarcodeResult;
import com.journeyapps.barcodescanner.BarcodeView;
import com.example.scanner.R;
import com.example.scanner.ui.base.BaseFragment;
import java.util.List;
/**
* Created by Rishabh Bhatia on 12/5/17.
*/
public class CameraFragment extends BaseFragment {
Context mcontext;
private BarcodeView barcodeView;
final int PERMISSIONS_REQUEST_ACCESS_CAMERA=0;
View view;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view=inflater.inflate(R.layout.fragment_camera, container, false);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
getActivity().checkSelfPermission(Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.CAMERA},
PERMISSIONS_REQUEST_ACCESS_CAMERA);
} else {
barcodeView = (BarcodeView) view.findViewById(R.id.barcode_scanner);
barcodeView.decodeContinuous(callback);
}
mcontext=getContext();
return view;
}
#Override
public void onResume() {
super.onResume();
barcodeView = (BarcodeView) view.findViewById(R.id.barcode_scanner);
barcodeView.resume();
}
#Override
public void onPause() {
super.onPause();
barcodeView = (BarcodeView) view.findViewById(R.id.barcode_scanner);
barcodeView.pause();
}
private BarcodeCallback callback = new BarcodeCallback() {
#Override
public void barcodeResult(BarcodeResult result) {
if (result.getText() != null) {
barcodeView.pause();
//after the string has been read we prozess it
String tag_string=result.getText();
Log.e("RISHABH", "pausing scanner, got some data "+tag_string);
if(!tag_string.equals("abc")){//if the tag was not scanned succesfully let us start the scan again
Log.e("RISHABH", "resuming scanner, data needed was not found");
barcodeView.resume(); //notice we don't call decodeContinuous function again
}
}
}
#Override
public void possibleResultPoints(List<ResultPoint> resultPoints) {
}
};
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PERMISSIONS_REQUEST_ACCESS_CAMERA) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
barcodeView = (BarcodeView) view.findViewById(R.id.barcode_scanner);
barcodeView.decodeContinuous(callback);
}
}
}
}
Here is my logcat
05-12 23:54:13.226 31403-31403/com.example.scanner E/RISHABH: pausing scanner, got some data ABC-abc-1234
05-12 23:54:13.226 31403-31403/com.example.scanner E/RISHABH: resuming scanner, data needed was not found
05-12 23:54:18.280 31403-31403/com.example.scanner E/RISHABH: pausing scanner, got some data ABC-abc-1234
05-12 23:54:18.280 31403-31403/com.example.scanner E/RISHABH: resuming scanner, data needed was not found
05-12 23:54:19.350 31403-31403/com.example.scanner E/RISHABH: pausing scanner, got some data ABC-abc-1234
05-12 23:54:19.350 31403-31403/com.example.scanner E/RISHABH: resuming scanner, data needed was not found
05-12 23:54:20.350 31403-31403/com.example.scanner E/RISHABH: pausing scanner, got some data ABC-abc-1234
05-12 23:54:20.350 31403-31403/com.example.scanner E/RISHABH: resuming scanner, data needed was not found
05-12 23:54:21.450 31403-31403/com.example.scanner E/RISHABH: pausing scanner, got some data ABC-abc-1234
05-12 23:54:21.450 31403-31403/com.example.scanner E/RISHABH: resuming scanner, data needed was not found
05-12 23:54:22.510 31403-31403/com.example.scanner E/RISHABH: pausing scanner, got some data ABC-abc-1234
05-12 23:54:22.510 31403-31403/com.example.scanner E/RISHABH: resuming scanner, data needed was not found
05-12 23:54:33.000 31403-31403/com.example.scanner E/RISHABH: pausing scanner, got some data abc
I figured it out and thought it might help someone.
I had exactly the same issue, then figured out that resume() method do a check if it is running on MainThread.
public class Util {
public static void validateMainThread() {
if (Looper.getMainLooper() != Looper.myLooper()) {
throw new IllegalStateException("Must be called from the main thread.");
}
}
}
Here are examples of how to run code on MainThread:
Running code in main thread from another thread
I tried to run it from #JavscriptInterface method and here is my code:
public class MyInterface {
Context mContext;
ActivityMain activityMain;
MyInterface(Context c, ActivityMain am) {
mContext = c;
activityMain = am;
}
#JavascriptInterface
public void resumeScanner() {
Toast.makeText(mContext, "resume", Toast.LENGTH_SHORT).show();
Handler mainHandler = new Handler(mContext.getMainLooper());
Runnable myRunnable = new Runnable() {
#Override
public void run() {
activityMain.barcodeView.resume();
}
};
mainHandler.post(myRunnable);
}
}

making text scanner but shows black screen instead of camera

I am trying to make a text scanner application with camera that recognizes text and shows in screen.But instead of showing camera it shows a black screen. How can I solve this.
My code is here
package com.myapp.game.easynepalirecharge;
import android.Manifest;
import android.app.ActionBar;
import android.content.pm.PackageManager;
import android.graphics.Camera;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.util.SparseArray;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.ViewGroup;
import android.widget.TextView;
import com.google.android.gms.vision.CameraSource;
import com.google.android.gms.vision.Detector;
import com.google.android.gms.vision.text.TextBlock;
import com.google.android.gms.vision.text.TextRecognizer;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
SurfaceView cameraView;
TextView textView;
CameraSource cameraSource;
final int REQUESTCAMERAPERMISSION = 105;
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull final int[] grantResults) {
switch (requestCode) {
case REQUESTCAMERAPERMISSION:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.checkSelfPermission(getApplication(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
return;
}
try {
cameraSource.start(cameraView.getHolder());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
cameraView = (SurfaceView) findViewById(R.id.surfaceView);
textView = (TextView) findViewById(R.id.textView);
TextRecognizer textRecognizer = new TextRecognizer.Builder(getApplicationContext()).build();
if (!textRecognizer.isOperational()) {
Log.v("haha", "error not operational");
} else {
cameraSource = new CameraSource.Builder(getApplicationContext(), textRecognizer).
setFacing(CameraSource.CAMERA_FACING_BACK)
.setRequestedPreviewSize(3840, 2160)
.setRequestedFps(2.0f)
.setAutoFocusEnabled(true)
.build();
cameraView.getHolder().addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceCreated(SurfaceHolder holder) {
try {
if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA}, REQUESTCAMERAPERMISSION);
cameraSource.start(cameraView.getHolder());
return;
}
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
cameraSource.stop();
}
});
textRecognizer.setProcessor(new Detector.Processor<TextBlock>() {
#Override
public void release() {
}
#Override
public void receiveDetections(Detector.Detections<TextBlock> detections) {
final SparseArray<TextBlock> items = detections.getDetectedItems();
if (items.size() != 0) {
textView.post(new Runnable() {
#Override
public void run() {
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i <= items.size(); i++) {
TextBlock item = items.valueAt(i);
stringBuilder.append(item.getValue());
stringBuilder.append("\n");
}
textView.setText(stringBuilder.toString());
}
});
}
}
}
);
}
}
}
and another thing I wanna ask. Which one is better. This or the tess two library?
have you stopped camera properly. Try to do camera functions in thread so that your single task does not be expensive. The reason i thought problem is that get your permission at run time.
try this
https://developer.android.com/training/permissions/requesting.html

Refresh TextView in Android

I try to refresh TextView in Android. I am using ExecutorService in my code. When I pushed the "Start refresh" button, after several seconds my app has been stopped by Android system. I have read several topics in stackoverflow.com, but I still cannot understand what I am doing wrong. Here is my code:
MainActivity.java:
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class MainActivity extends Activity {
private static ExecutorService exec;
private static TextView textView;
private static Calendar cal;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.text_field);
cal = new GregorianCalendar();
exec = Executors.newSingleThreadExecutor();
}
private static class Task implements Runnable {
#Override
public void run() {
try {
while(!Thread.currentThread().isInterrupted()) {
textView.setText(cal.getTime().toString());
TimeUnit.SECONDS.sleep(1);
}
}
catch (InterruptedException e) {
return;
}
}
}
public void finish_refresh(View view) {
exec.shutdownNow();
}
public void start_refresh(View view) {
exec.submit(new Task());
}
}
activity_main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">
<Button android:layout_width="200dp"
android:layout_height="50dp"
android:text="#string/start_refresh"
android:onClick="start_refresh"/>
<Button android:layout_width="200dp"
android:layout_height="50dp"
android:text="#string/finish_refresh"
android:onClick="finish_refresh"/>
<TextView android:layout_height="200dp"
android:layout_width="200dp"
android:layout_marginTop="10dp"
android:id="#+id/text_field" />
</LinearLayout>
You need to use runOnUiThread()
Add following code in your onCreate() method:
Thread t = new Thread() {
#Override
public void run() {
try {
while (!isInterrupted()) {
Thread.sleep(1000);
runOnUiThread(new Runnable() {
#Override
public void run() {
// update TextView here!
textView.setText(cal.getTime().toString());
}
});
}
} catch (InterruptedException e) { }
}
};
t.start();

Categories

Resources