I'm trying to create a real time QR Code decoder which allows user to confirm/cancel data read from the camera view.
(Of course, according confirmation or cancelation, it will execute some code...)
But there's a bad point:
The app I coded keeps reading qr code data even while in dialog and I can't find a way to prevent it.
Here is my main activity:
public class MainReadActivity extends Activity {
private SurfaceView cameraView;
private TextView barcodeInfo;
private BarcodeDetector barcodeDetector;
private CameraSource cameraSource;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_read);
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
cameraView = (SurfaceView) findViewById(R.id.camera_view);
cameraView.requestFocus();
barcodeInfo = (TextView) findViewById(R.id.code_info);
barcodeDetector = new BarcodeDetector.Builder(this).setBarcodeFormats(Barcode.QR_CODE).build();
cameraSource = new CameraSource.Builder(this, barcodeDetector).build();
cameraView.getHolder().addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceCreated(SurfaceHolder holder) {
try {
cameraSource.start(cameraView.getHolder());
} catch (IOException ie) {
Log.e("CAMERA SOURCE", ie.getMessage());
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
cameraSource.stop();
}
});
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() {
ConfirmationDialogFragment myDialog = new ConfirmationDialogFragment();
myDialog.show(getFragmentManager(),"");
barcodeInfo.setVisibility(View.VISIBLE);
barcodeInfo.setText(barcodes.valueAt(0).displayValue);
}
});
}
}
});
}
And here is my DialogFragment:
public class ConfirmationDialogFragment extends DialogFragment {
public Dialog ConfirmationDialogFragment(Bundle savedInstanceState){
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
View v = inflater.inflate(R.layout.dialog_confirmation,null);
builder.setView(v);
Dialog dialog = builder.create();
return dialog;
}
}
Can anyone help me?
Bests,
P.
Stop and start camera on barcodeDetector callback
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) {
cameraSource.stop();
barcodeInfo.post(new Runnable() { // Use the post method of the TextView
public void run() {
builder
.setMessage("Are you sure you want to reset the count?")
.setNegativeButton("No", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface arg0, int arg1) {
cameraSource.start(cameraView.getHolder());
}
})
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface arg0, int arg1) {
Toast.makeText(MainActivity.this, "Did Reset!", 5).show();
}
})
.create();
barcodeInfo.setVisibility(View.VISIBLE);
barcodeInfo.setText(barcodes.valueAt(0).displayValue);
}
});
}
}
});
I think that you forget some like this.
builder.setPositiveButton(Ok, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss(); //this close the dialog.
}
});
builder.setNegativeButton(Back, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
///do another thing
}
});
I hope this help you
just call the Camera.release() method after detection
#Override
public void receiveDetections(Detector.Detections < TextBlock > detections) {
final SparseArray < TextBlock > items = detections.getDetectedItems();
if (items.size() != 0) {
mTextView.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");
}
mTextView.setText(stringBuilder.toString());
mCameraSource.release();
}
});
}
}
Related
beacon manager.addMonitorNotifier(new MonitorNotifier()
in this method, there are two methods and both are not running .... it is a small app of beacon I want to show the alert .... and that alert in my method in if condition ... but it is not running I did debugger but it is not working
import java.util.Collection;
public class WebViewScreen extends AppCompatActivity implements BeaconConsumer {
public static final String TAG="MainActivity";
private Button startbtn,stopbtn;
private BeaconManager beaconManager=null;
private static final String ALTBEACON_LAYOUT="m:2-3=beac,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25";
private Region beaconRegion=null;
private void ShowAlert(final String title, final String message){
runOnUiThread (new Thread(new Runnable() {
public void run() {
AlertDialog alertDialog = new AlertDialog.Builder(WebViewScreen.this).create();
alertDialog.setTitle(title);
alertDialog.setMessage(message);
alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
alertDialog.show();
}
}));
}
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_web_view);
Log.d(TAG,"on create called");
startbtn=findViewById(R.id.startButton);
stopbtn=findViewById(R.id.stopButton);
requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},1234);
beaconManager=BeaconManager.getInstanceForApplication(this);
beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout(ALTBEACON_LAYOUT));
beaconManager.bind(this);
startbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startBiconMonitoring();
}
});
stopbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
stopBiconMonitoring();
}
});
}
private boolean entryMessageRaised=false;
private boolean exitMessageRaised=false;
private boolean rangingMessageRaised=false;
private void stopBiconMonitoring() {
Log.d(TAG,"Stop Beacon Monitering");
try {
beaconManager.stopMonitoringBeaconsInRegion(beaconRegion);
beaconManager.stopRangingBeaconsInRegion(beaconRegion);
}catch (RemoteException e){
e.printStackTrace();
}
}
private void startBiconMonitoring() {
Log.d(TAG,"Start Beacon Monitering");
try {
beaconRegion = new Region("My Bicons",Identifier.parse("B9407F30-F5F8-466E-AFF9-25556B57FE6D"),Identifier.parse("4"),Identifier.parse("200"));
beaconManager.startMonitoringBeaconsInRegion(beaconRegion);
beaconManager.startRangingBeaconsInRegion(beaconRegion);
}catch (RemoteException e){
e.printStackTrace();
}
}
private void findID() {
}
#Override
public void onBeaconServiceConnect() {
beaconManager.addMonitorNotifier(new MonitorNotifier() {
#Override
public void didEnterRegion(Region region) {
if (!entryMessageRaised){
showAlert("didEnterRegion","Entering Region"+region.getUniqueId()+"Beacon Detected UUID/Major/Minor:"+region.getId1()+"/"+region.getId2()+"/"+region.getId3());
entryMessageRaised=true;
}
else {
Log.d(TAG,"somrething go wrong");
}
}
#Override
public void didExitRegion(Region region) {
if (!exitMessageRaised){
showAlert("didExitRegion","Exiting Region"+region.getUniqueId()+"Beacon Detected UUID/Major/Minor:"+region.getId1()+"/"+region.getId2()+"/"+region.getId3());
exitMessageRaised=true;
}
}
#Override
public void didDetermineStateForRegion(int i, Region region) {
}
});
beaconManager.addRangeNotifier(new RangeNotifier() {
#Override
public void didRangeBeaconsInRegion(Collection<Beacon> collection, Region region) {
if (rangingMessageRaised && collection != null && !collection.isEmpty()){
for (Beacon beacon:collection){
showAlert("didExitRegion","Ranging Region"+region.getUniqueId()+"Beacon Detected UUID/Major/Minor:"+beacon.getId1()+"/"+beacon.getId2()+"/"+beacon.getId3());
}
rangingMessageRaised=true;
}
}
});
}
}
I want to show the alert if the device will found bacon
I`m trying to create bar code reader for my app, and it works fine, but the problem is when I keep focusing on QR-Code, it continues to read and never stops!!!
How can I make this happen only once?
In this code, it continues to "Toast" until I close the app, and when I use Intent for for closing the current activity and open another activity, the activity opens several times!!!
Here is the code:
public class BarcodeCaptureActivity extends AppCompatActivity {
private SurfaceView camera_preview;
TextView text;
BarcodeDetector barcodeDetector;
CameraSource cameraSource;
final int requestCameraPermissionID = 1001;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_barcode_capture);
camera_preview = (SurfaceView) findViewById(R.id.camera_preview);
text = (TextView) findViewById(R.id.text);
barcodeDetector = new BarcodeDetector.Builder(this).setBarcodeFormats(Barcode.QR_CODE).build();
cameraSource = new CameraSource.Builder(this, barcodeDetector).setRequestedPreviewSize(640, 480).build();
camera_preview.getHolder().addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceCreated(SurfaceHolder holder) {
if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(BarcodeCaptureActivity.this, new String[]{Manifest.permission.CAMERA},requestCameraPermissionID);
return;
}
try {
cameraSource.start(camera_preview.getHolder());
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
cameraSource.stop();
}
});
barcodeDetector.setProcessor(new Detector.Processor<Barcode>() {
#Override
public void release() {
}
#Override
public void receiveDetections(Detector.Detections<Barcode> detections) {
final SparseArray<Barcode> qrcode = detections.getDetectedItems();
if (qrcode.size() != 0){
text.post(new Runnable() {
#Override
public void run() {
Vibrator vibrator = (Vibrator) getApplicationContext().getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(1000);
text.setText(qrcode.valueAt(0).displayValue);
String title = text.getText().toString();
Toast.makeText(BarcodeCaptureActivity.this, "" + title, Toast.LENGTH_SHORT).show();
finish();
}
});
}
}
});
}
Thank for any help...
UPDATE
Problem solved with adding onDestroy and onPause methods...
#Override
protected void onPause() {
super.onPause();
cameraSource.stop();
}
#Override
protected void onDestroy() {
super.onDestroy();
cameraSource.stop();
}
When alertDialog.show gets called, it does pop up a dialog but it remains invisible. I have to tap on the screen until I happen to click the "OK" button that's on the alert even though it is not visibly showing.
public class RecordSignals extends Activity {
private ImageView pulseOxImage;
static AlertDialog poDialog;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(saveInstanceState);
pulseOxImage = new ImageView(this);
pulseOxImage.setImageDrawable(ContextCompat
.getDrawable(this,R.drawable.pulse_ox_animation));
poDialog = new AlertDialog.Builder(this).create();
...
}
final Runnable callback = new Runnable() {
#Override
public void run() {
Thread thread = new Thread() {
#Override
public void run() {
...
runOnUiThread(new Runnable() {
#Override
public void run() {
if (pulseOxArtifact >= 2 || pulseOxOutOfTrack >= 2 || pulseOxSensorAlarm >= 2) {
pulseOxStatus();
pulseOxImage.setVisibility(View.VISIBLE);
poDialog.show();
}
}
});
}
};
}
};
public void pulseOxStatus() {
poDialog.setView(pulseOxImage);
poDialog.setButton("OK", new DialogInterface.OnClicklistener() {
#Override
public void onClick(DialogInterface dialog, int which) {
poDialog.dismiss();
}
});
}
}
Below is my utility method for showing alert dialog in my application
private void displayInternetAlert(final Context context) {
if (!((GlobalActivity) context).isFinishing() && context instanceof GlobalActivity) {
((GlobalActivity) context).runOnUiThread(new Runnable() {
#Override
public void run() {
if (Validator.isNull(internetDialog)) {
internetDialog = new AlertDialog.Builder(Util.createCustomAlertDialog(context)).create();
internetDialog.setMessage(context.getString(R.string.internet_disable));
internetDialog.setButton(DialogInterface.BUTTON_NEUTRAL, context.getString(R.string.settings), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
/*
Don't need to write onactivity result now as we try to connect every time
*/
context.startActivity(new Intent(Settings.ACTION_WIRELESS_SETTINGS));
dialog.dismiss();
}
});
internetDialog.setButton(DialogInterface.BUTTON_NEGATIVE, context.getString(R.string.ignore), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
internetDialog.setOnShowListener(new DialogInterface.OnShowListener() {
#Override
public void onShow(DialogInterface dialog) {
internetDialog.getButton(AlertDialog.BUTTON_NEUTRAL).setTextColor(context.getResources().getColor(R.color.dialog_cancel_button));
internetDialog.getButton(AlertDialog.BUTTON_NEUTRAL).setTypeface(null, Typeface.BOLD);
internetDialog.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(context.getResources().getColor(R.color.dialog_cancel_button));
}
});
}
if (!internetDialog.isShowing()) {
internetDialog.show();
}
}
});
}
}
and Below is my GlobalActivity class
public class GlobalActivity extends AppCompatActivity {
#Nullable
#Bind(R.id.adView)
public AdView adView;
public GlobalActivity() {
ExceptionHandler.getExceptionHandler().setActivity(this);
}
#Override
public void onCreate(Bundle savedInstanceState, PersistableBundle persistentState) {
super.onCreate(savedInstanceState, persistentState);
setContentView(R.layout.ad_system);
ButterKnife.bind(this);
}
#Override
protected void finalize() throws Throwable {
}
#Override
protected void onStart() {
super.onStart();
loadGoogleAdd();
}
#Override
protected void onResume() {
super.onResume();
if(Validator.isNotNull(adView)){
adView.resume();
}
}
#Override
protected void onPause() {
super.onPause();
if(Validator.isNotNull(adView)){
adView.pause();
}
Util.setSharedPreferences(this, Util.SHARED_PREFERENCE_PREFERENCES, Util.EXPOSE_GSON.toJson(Util.getPreferences(this)));
}
private void loadGoogleAdd() {
if (adView != null) {
AdRequest adRequest = new AdRequest.Builder().
addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
.build();
adView.loadAd(adRequest);
}
}
public void loadErrorActivity() {
startActivity(new Intent(GlobalActivity.this, ErrorActivity.class));
}
#Override
protected void onDestroy() {
super.onDestroy();
if(Validator.isNotNull(adView)){
adView.destroy();
}
Request.getRequest().dismissProgressDialog(this);
}
}
from which I am extending all activities and in that activity I am replacing fragments although I made check for activity finishing.
But I'm still receiving this exception in SM-G935F (Samesung Galaxy s7 edge). I'm using appcompat 23.1.1. is it platform or device specific issue or whether I'm making any mistake please help me in finding solution for this.
Any help is appreiciated.
I don't think it possible to display dialog from background thread, with assumption method displayInternetAlert is called inside activity/fragment, you can display dialog directly like this:
private void displayInternetAlert(final Context context) {
if (!((GlobalActivity) context).isFinishing() && context instanceof GlobalActivity) {
if (Validator.isNull(internetDialog)) {
internetDialog = new AlertDialog.Builder(Util.createCustomAlertDialog(context)).create();
internetDialog.setMessage(context.getString(R.string.internet_disable));
internetDialog.setButton(DialogInterface.BUTTON_NEUTRAL, context.getString(R.string.settings), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
/*
Don't need to write onactivity result now as we try to connect every time
*/
context.startActivity(new Intent(Settings.ACTION_WIRELESS_SETTINGS));
dialog.dismiss();
}
});
internetDialog.setButton(DialogInterface.BUTTON_NEGATIVE, context.getString(R.string.ignore), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
internetDialog.setOnShowListener(new DialogInterface.OnShowListener() {
#Override
public void onShow(DialogInterface dialog) {
internetDialog.getButton(AlertDialog.BUTTON_NEUTRAL).setTextColor(context.getResources().getColor(R.color.dialog_cancel_button));
internetDialog.getButton(AlertDialog.BUTTON_NEUTRAL).setTypeface(null, Typeface.BOLD);
internetDialog.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(context.getResources().getColor(R.color.dialog_cancel_button));
}
});
}
if (!internetDialog.isShowing()) {
internetDialog.show();
}
}
}
This is my VideoplayerActivity:
public class VideoPlayerActivity extends Activity {
CustomVideoView video_player_view;
DisplayMetrics dm;
SurfaceView sur_View;
MediaController media_Controller;
AlertDialog alertDialog;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.video_view);
if (getIntent().getData() != null && getIntent().getData().getPath() != null) {
getInit(getIntent().getData().getPath());
}
if (getIntent().hasExtra("file_path")) {
getInit(getIntent().getStringExtra("file_path"));
}
}
public void getInit(String file_path) {
video_player_view = (CustomVideoView) findViewById(R.id.video_player_view);
media_Controller = new MediaController(this);
video_player_view.setPlayPauseListener(new CustomVideoView.PlayPauseListener() {
#Override
public void onPlay() {
if (alertDialog != null) {
alertDialog.dismiss();
}
}
#Override
public void onPause() {
alertDialog = new AlertDialog.Builder(VideoPlayerActivity.this).create();
alertDialog.setMessage("Video has been paused");
alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
alertDialog.dismiss();
}
});
alertDialog.show();
}
});
video_player_view.setMediaController(media_Controller);
video_player_view.setVideoPath(file_path);
video_player_view.start();
}
}
and here is my CustomVideoView
public class CustomVideoView extends VideoView {
private PlayPauseListener mListener;
public CustomVideoView(Context context) {
super(context);
}
public CustomVideoView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomVideoView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public void setPlayPauseListener(PlayPauseListener listener) {
mListener = listener;
}
#Override
public void pause() {
super.pause();
if (mListener != null) {
mListener.onPause();
}
}
#Override
public void resume() {
super.resume();
if (mListener != null) {
mListener.onPlay();
}
}
#Override
public void start() {
super.start();
if (mListener != null) {
mListener.onPlay();
}
}
public static interface PlayPauseListener {
void onPlay();
void onPause();
}
}
the problem is that when i click to resume video at first it dismiss alert dialog and after second time i clicked it resume my video.
I want it to be happen on single click , kindly help me through this.
This I tested and seems to work! from this post
public void getInit(String file_path) {
video_player_view = (CustomVideoView) findViewById(R.id.video_player_view);
media_Controller = new MediaController(this);
video_player_view.setPlayPauseListener(new CustomVideoView.PlayPauseListener() {
#Override
public void onPlay() {
if (alertDialog != null) {
alertDialog.dismiss();
}
}
#Override
public void onPause() {
alertDialog = new AlertDialog.Builder(VideoPlayerActivity.this).create();
alertDialog.setMessage("Video has been paused");
alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
alertDialog.dismiss();
}
});
alertDialog.getWindow()
.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
alertDialog.getWindow()
.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
alertDialog.show();
}
});
video_player_view.setMediaController(media_Controller);
video_player_view.setVideoPath(file_path);
video_player_view.start();
}
So I'm not sure of a way to show an alert dialog and allow the user to click on ui elements not in the foreground. What you can do is add a dismiss listener that will be called if the user dismisses the dialog on an outside touch and start playback from there.
public void getInit(String file_path) {
video_player_view = (CustomVideoView) findViewById(R.id.video_player_view);
media_Controller = new MediaController(this);
video_player_view.setPlayPauseListener(new CustomVideoView.PlayPauseListener() {
#Override
public void onPlay() {
if (alertDialog != null) {
alertDialog.dismiss();
}
}
#Override
public void onPause() {
alertDialog = new AlertDialog.Builder(VideoPlayerActivity.this).create();
alertDialog.setMessage("Video has been paused");
alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
alertDialog.dismiss();
video_player_view.start();
}
});
.setOnCancelListener(new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
video_player_view.start();
}
});
alertDialog.show();
}
});
video_player_view.setMediaController(media_Controller);
video_player_view.setVideoPath(file_path);
video_player_view.start();
}