I have started learning reactive programming using spring boot and when I tried execute the below piece of code from route function, the mono subscribe part of logic is not executing.
#SpringBootApplication
public class MonotopayloadApplication {
public static void main(String[] args) {
SpringApplication.run(MonotopayloadApplication.class, args);
}
#Bean
RouterFunction<ServerResponse> videoEndPoint() {
return route()
.path("/test", builder -> builder
.POST("", this::handle)
).build();
}
private Mono<ServerResponse> handle(ServerRequest serverRequest) {
serverRequest.bodyToMono(String.class)
.subscribe(result -> {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("subscribe thread : " + Thread.currentThread().getName());
});
System.out.println("Thread : " + Thread.currentThread().getName() + " is leaving");
return Mono.empty();
}
}
I do not want to call the block/blockFirst/blockLast(). I understand the main thread is leaving the subscribe thread. Kindly help.
I'm currently trying to migrate an EAR Project
-The old Project-
EJB 2.0
Jboss 5.0.1
-New Project-
EJB 3.0
Wildfly 13.0.0Final
Its session beans which I have managed to create and I can call upon it. the logic in it self seems to work. The issues I'm having is one of the follow ups seems to forget what it was doing.
the current issue I'm seeing is the following:
In the Web application in an class we are creating an object of Another class which we then trigger its parent method. this parent method then calls upon a class with it self as an argument which then checks which type it is and then stars a session bean depending on what type. which then calls on the arguments function performExecute() in this function we call upon a Query and actually get the correct results, we then add the resultsets values to a private dto member. and then performExecute is done. and we are back at the web applications class and we then try to access the same dto member with a get function. this returns a nullpointer. I'm wondering if I've forgotten something in my session beans?
Old sessionbean:
public class TxNotSupportedCommandServerBean implements SessionBean {
SessionContext sessionContext;
public void ejbCreate() throws CreateException {}
public void ejbRemove() {
sessionContext = null;
}
public void ejbActivate() {}
public void ejbPassivate() {}
public void setSessionContext(SessionContext sessionContext) {
this.sessionContext = sessionContext;
}
public void executeCommand(TargetableCommand cmd) throws CommandException {
try {
cmd.performExecute();
}
catch (CommandException ex) {
throw ex;
}
}
}
The new one:
#Stateless
#Remote
#TransactionManagement(value=TransactionManagementType.CONTAINER)
#TransactionAttribute(value=REQUIRED)
public class TxNotSupportedCmdServerBean implements TxNotSupportedCmdServerRemote{
/**
* Default constructor.
*/
public TxNotSupportedCmdServerBean() {
// TODO Auto-generated constructor stub
}
public void executeCommand(TargetableCommand cmd) throws CommandException {
try {
cmd.performExecute();
}
catch (CommandException ex) {
throw ex;
}
}
}
Both these are in the EJB.Jar
the interface is implemented in the EJBClient.jar
The old Interface:
public interface TxNotSupportedCommandServerLocal extends EJBLocalObject {
public void executeCommand(TargetableCommand cmd) throws CommandException;
}
The new Interface:
public interface TxNotSupportedCmdServerRemote {
public void executeCommand(TargetableCommand cmd) throws CommandException;
}
Now here come s the next set of files that is also in the EJBClient.jar
TargetableCommand:
public abstract class TargetableCommand implements Command {
private boolean constraintViolated;
protected RequestContext requestContext;
protected String dataSourceName;
public TargetableCommand(RequestContext requestContext, String dataSourceName) {
this.requestContext = requestContext;
this.dataSourceName = dataSourceName;
}
public TargetableCommand(RequestContext requestContext) {
this.requestContext = requestContext;
}
public TargetableCommand(String dataSourceName) {
this.dataSourceName = dataSourceName;
}
public TargetableCommand() {
}
public void setConstraintViolated(boolean constraintViolated) {
this.constraintViolated = constraintViolated;
}
public boolean isConstraintViolated() {
return constraintViolated;
}
public abstract void performExecute() throws CommandException;
public void execute() throws CommandException {
CommandTarget.executeCommand(this);
}
}
Command:
public interface Command extends Serializable {
public void execute() throws CommandException;
}
The commented code is the old session beans.
CommandTarget:
public class CommandTarget {
public CommandTarget() {
}
/**
* Exekverar ett kommando i rätt miljö, t.ex. med eller utan transaktionshantering
* #param cmd TargetableCommand Kommandot som ska utföras
* #throws CommandException
*/
public static void executeCommand(TargetableCommand cmd) throws CommandException {
Context context = null;
try {
ServiceLocator sl = ServiceLocator.getInstance();
// if (cmd instanceof TxRequired) {
// TxRequiredCommandServerLocalHome cmdSrvHome = (TxRequiredCommandServerLocalHome) sl.getEJBLocalHome("TxRequiredCommandServer");
// TxRequiredCommandServerLocal cmdSrv = cmdSrvHome.create();
// cmdSrv.executeCommand(cmd);
// }
// else if(cmd instanceof TxNotSupported) {
// TxNotSupportedCommandServerLocalHome cmdSrvHome = (TxNotSupportedCommandServerLocalHome) sl.getEJBLocalHome("TxNotSupportedCommandServer");
// TxNotSupportedCommandServerLocal cmdSrv = cmdSrvHome.create();
// cmdSrv.executeCommand(cmd);
// }
// else {
// throw new CommandException("Cannot instanciate command server");
// }
//
System.out.println("CT: Inside commandTarget. about to diffrientate what instance");
context = JNDILookupClass.getInitialContext();
if (cmd instanceof TxRequired) {
System.out.println("CT: TxRequired");
TxRequiredCmdServerRemote cmdSrv = (TxRequiredCmdServerRemote)context.lookup(JNDILookupClass.getLookupName("TxRequiredCmdServerRemoteBean", TxRequiredCmdServerRemote.class.getName()));
cmdSrv.executeCommand(cmd);
}
else if(cmd instanceof TxNotSupported) {
System.out.println("CT: TxNotSupported");
System.out.println("CT: cmd: " + cmd.getClass());
TxNotSupportedCmdServerRemote cmdSrv = (TxNotSupportedCmdServerRemote)context.lookup(JNDILookupClass.getLookupName("TxNotSupportedCmdServerBean", TxNotSupportedCmdServerRemote.class.getName()));
cmdSrv.executeCommand(cmd);
}
else {
throw new CommandException("Cannot instanciate command server");
}
}
catch (CommandException ex) {
throw ex;
}
// catch (CreateException ex) {
// throw new CommandException(ex);
// }
//new catch
catch(NamingException ex) {
throw new CommandException(ex);
}
catch (ServiceLocatorException ex) {
throw new CommandException(ex);
}
}
}
Phew ...
Ok now that's the important parts from EJBClient. now onwards to the Web.war
I'm only pasting the part that actually runs and were it returns a nullpoint
public class ActionIdentitetKonsultCommand implements Command {
private static Logger logger = Logger.getLogger(ActionIdentitetKonsultCommand.class);
public ActionIdentitetKonsultCommand() {
}
public String execute(RequestContext requestContext) throws CommandException {
GetPersonByPersnrEJBCommand personCmd;
logger.info("execute()");
try {
UserBean user = (UserBean) requestContext.getSession().getAttribute("user");
String kstnr = requestContext.getParameter("kstnr");
//Tilldela konsultuppgifter
personCmd = new GetPersonByPersnrEJBCommand();
personCmd.setPersnr(user.getPersnr());
System.out.println("AI: Before execute DTO " + personCmd.dto);
personCmd.execute();
System.out.println("AI: After execute DTO " + personCmd.dto);
logger.info("person hamtad med personnummer (EJB):");
logger.info(personCmd.getPerson().toString());
So the personCmd.getPerson().tostring() is what causes the nullpointer. GetPersonByPersnrEJBCommand():
public class GetPersonByPersnrEJBCommand extends TargetableCommand implements TxNotSupported {
public PersonDTO dto;
private long persnr;
public GetPersonByPersnrEJBCommand() {
}
public void setPersnr(long persnr) {
this.persnr = persnr;
}
public PersonDTO getPerson() {
return this.dto;
}
public void performExecute() throws CommandException {
try {
QueryPersonByPersnrCommand cmd = new QueryPersonByPersnrCommand();
cmd.setPersnr(persnr);
cmd.execute();
if(cmd.next()){
this.dto = new PersonDTO();
System.out.println("GP: inside PerformExecute DTO: " + dto);
dto.setPersnr(cmd.getPersnr());
dto.setEfternamn(cmd.getEfternamn());
dto.setFornamn(cmd.getFornamn());
dto.setEpostAdress(cmd.getEpostAdress());
dto.setKonsult((cmd.getKonsult() == 1));
dto.setAnsvarig((cmd.getAnsvarig() == 1));
System.out.println("GP: Inside Perform Execute DTO: " + dto);
}
}
catch (DataAccessCommandException ex) {
System.out.println("GetPersonByPersnrEJBCommand.performExecute misslyckades " + ex.getMessage());
throw new CommandException(ex);
}
}
}
So that's it; I don't understand why it forgets it. when we do sysouts inside the last class we see that both the dto and the cmd has data in them, but once the function ends and we are back in the class that called on this the data is empty.
I'm suspecting its something to do with my session beans, I'm missing an property or something. because this code works with the old beans in the old JBOSS server. Hopefully someone can help me and others can learn from this as well as me.
I managed to solve this issue. Since the scope of the project is to get this to work. Its not a beautiful solution and with more time rewriting this would have been better. so onwards to the solution:
We need to change in both the bean, targetableCommand, CommandTarget and in the GetPersonByPersnrEJBCommand
TargetableCommand - add method:
public TargetableCommand execute(TargetableCommand cmd) throws CommandException
{
return CommandTarget.executeCommand(cmd);
}
CommandTarget - We change the method executeCommand to return a TargetableCommand, and make sure that after the bean is done we return that cmd.
public static TargetableCommand executeCommand(TargetableCommand cmd) throws CommandException {
Context context = null;
try {
context = JNDILookupClass.getInitialContext();
if (cmd instanceof TxRequired) {
TxRequiredCmdServerRemote cmdSrv = (TxRequiredCmdServerRemote)context.lookup(JNDILookupClass.getLookupName("TxRequiredCmdServerRemoteBean", TxRequiredCmdServerRemote.class.getName()));
cmd = cmdSrv.executeCommand(cmd);
}
else if(cmd instanceof TxNotSupported) {
TxNotSupportedCmdServerRemote cmdSrv = (TxNotSupportedCmdServerRemote)context.lookup(JNDILookupClass.getLookupName("TxNotSupportedCmdServerBean", TxNotSupportedCmdServerRemote.class.getName()));
cmd = cmdSrv.executeCommand(cmd);
}
else {
throw new CommandException("Cannot instanciate command server");
}
}
catch (CommandException ex) {
throw ex;
}
catch(NamingException ex) {
throw new CommandException(ex);
}
}
return cmd;
}
The bean - cange the method Execute command to return Targetablecommand
public TargetableCommand executeCommand(TargetableCommand cmd) throws CommandException {
try {
cmd = cmd.performExecute();
}
catch (CommandException ex) {
throw ex;
}
return cmd;
}
Then lastly to get it all to work I had to create a new method in the classes that needed to do the perform execute so in the GetPersonByPersnrEJBCommand class i created the method wf13Layer(); wich is a just an extra step:
public void wf13Layer() throws CommandException
{
GetPersonByPersnrEJBCommand tmp;
try{
tmp = (GetPersonByPersnrEJBCommand) execute(this);
dto = tmp.getPerson();
} catch (Exception ex) {
throw new CommandException(ex);
}
}
This is what i did to make it work. as i said its not a beautiful solution but it works. IT seems to be a combination that once we cross between the projects the scope vanishes. and to obtain it futher we need to layer it like this. I really hope this helps someone at some point since theres till alot of old code running around out there.
Kind regards
VeryTired
I have a problem to solve - I was trying everything and nothing is working.
I am writing an application which should take picture every minute (period between pictures might be longer in future, but that isn't important) and upload it to ftp server. I am trying to open camera only for a while before taking photo and after taking photo release it and stop preview. But that doesn't work - there isn't even one picture taken. Opening camera etc. is doing by handler. If I put in handler only takePicture method - app works fine (and open camera once and keep it open in onCreate method), but I want to release camera and open it before taking picture to save battery.
I attach my source code and logcat.
MainActivity.java
public class MainActivity extends ActionBarActivity {
private Camera mCamera;
private CameraPreview mPreview;
private File pictureFile;
private File mediaStorageDir;
private Context context;
private Handler handler;
public Camera.PictureCallback mPicture = new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
pictureFile = getOutputMediaFile();
if (pictureFile == null) {
Log.d("TAG", "Error creating media file, check storage permissions: ");
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.d("TAG", "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d("TAG", "Error accessing file: " + e.getMessage());
}
Log.d("ftp", "photo taken: " + pictureFile);
mCamera.release();
startFTP();
}
};
private Runnable runnable = new Runnable() {
#Override
public void run() {
try {
mCamera = Camera.open();
} catch (Exception e) {
}
Camera.Parameters params = mCamera.getParameters();
params.setPictureSize(1920, 1080);
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
params.set("orientation", "portrait");
params.set("rotation", 90);
}
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
params.set("orientation", "landscape");
}
mCamera.setParameters(params);
mPreview = new CameraPreview(context, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mPreview);
mCamera.startPreview();
mCamera.takePicture(null, null, mPicture);
try {
this.wait(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.postDelayed(this, 60000);
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = getApplicationContext();
handler = new Handler();
Button captureButton = (Button) findViewById(R.id.button_capture);
captureButton.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
handler.post(runnable);
}
}
);
}
public void startFTP() {
new Thread(new Runnable() {
#Override
public void run() {
Log.d("ftp", "photo uploading started: " + pictureFile);
String sendingPictureName = pictureFile.getName();
String serverAddress = "1111111";
String userId = "111111";
String password = "111111";
FTPClient ftp = new FTPClient();
try {
ftp.connect(serverAddress);
ftp.login(userId, password);
int reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
}
ftp.setFileType(FTP.BINARY_FILE_TYPE);
ftp.enterLocalPassiveMode();
ftp.changeWorkingDirectory("/111111");
InputStream input;
input = new FileInputStream(pictureFile);
if (ftp.storeFile(pictureFile.getName(), input)) {
File fileToDelete = new File(mediaStorageDir.getPath() +"/"+ sendingPictureName);
//Log.d("ftp", "sciezka do usuwanego pliku: " + fileToDelete.getAbsolutePath());
fileToDelete.delete();
}
input.close();
Log.d("ftp", "photo uploading ended: " + sendingPictureName);
ftp.logout();
ftp.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private File getOutputMediaFile() {
mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyCameraApp");
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_"+ timeStamp + ".jpg");
return mediaFile;
}
public void cancelTimer(View view) {
handler.removeCallbacks(runnable);
}
}
CameraPreview.java
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
public CameraPreview(Context context, Camera camera) {
super(context);
mCamera = camera;
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
try {
mCamera.setPreviewDisplay(holder);
mCamera.setDisplayOrientation(90);
mCamera.startPreview();
} catch (IOException e) {
Log.d("TAG", "Error setting camera preview: " + e.getMessage());
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
if (mHolder.getSurface() == null){
// preview surface does not exist
return;
}
try {
mCamera.stopPreview();
} catch (Exception e){
}
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e){
Log.d("TAG", "Error starting camera preview: " + e.getMessage());
}
}
}
activity_main.xml - it's layout only for testing and it isn't perfect
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<FrameLayout
android:id="#+id/camera_preview"
android:layout_width="500px"
android:layout_height="500px"
android:layout_weight="0.1"
android:layout_above="#+id/button_capture" />
<Button
android:id="#+id/button_capture"
android:text="start timer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:layout_alignParentEnd="false"
android:layout_alignParentStart="false"
android:layout_centerVertical="true" />
<Button
android:id="#+id/timer_button"
android:text="stop timer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:layout_below="#+id/button_capture"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="false"
android:onClick="cancelTimer" />
Logcat:
08-24 09:42:42.828 8935-8935/? E/Zygote﹕ MountEmulatedStorage()
08-24 09:42:42.828 8935-8935/? I/libpersona﹕ KNOX_SDCARD checking this for 10185
08-24 09:42:42.828 8935-8935/? E/Zygote﹕ v2
08-24 09:42:42.828 8935-8935/? I/libpersona﹕ KNOX_SDCARD not a persona
08-24 09:42:42.828 8935-8935/? I/SELinux﹕ Function: selinux_compare_spd_ram , priority [2] , priority version is VE=SEPF_SM-A500FU_5.0.2_0023
08-24 09:42:42.838 8935-8935/? E/SELinux﹕ [DEBUG] get_category: variable seinfo: default sensitivity: NULL, cateogry: NULL
08-24 09:42:42.838 8935-8935/? I/art﹕ Late-enabling -Xcheck:jni
08-24 09:42:42.878 8935-8935/? D/TimaKeyStoreProvider﹕ TimaSignature is unavailable
08-24 09:42:42.878 8935-8935/? D/ActivityThread﹕ Added TimaKeyStore provider
08-24 09:42:42.988 8935-8935/com.example.dawid.camerabezpodgladu D/PhoneWindow﹕ *FMB* installDecor mIsFloating : false
08-24 09:42:42.988 8935-8935/com.example.dawid.camerabezpodgladu D/PhoneWindow﹕ *FMB* installDecor flags : -2139029248
08-24 09:42:43.108 8935-8951/com.example.dawid.camerabezpodgladu D/OpenGLRenderer﹕ Render dirty regions requested: true
08-24 09:42:43.118 8935-8935/com.example.dawid.camerabezpodgladu D/PhoneWindow﹕ *FMB* isFloatingMenuEnabled mFloatingMenuBtn : null
08-24 09:42:43.118 8935-8935/com.example.dawid.camerabezpodgladu D/PhoneWindow﹕ *FMB* isFloatingMenuEnabled return false
08-24 09:42:43.138 8935-8935/com.example.dawid.camerabezpodgladu D/SRIB_DCS﹕ log_dcs ThreadedRenderer::initialize entered!
08-24 09:42:43.138 8935-8951/com.example.dawid.camerabezpodgladu I/Adreno-EGL﹕ <qeglDrvAPI_eglInitialize:379>: EGL 1.4 QUALCOMM build: SKARAJGA_AU_LINUX_ANDROID_LA.BR.1.1.2_RB1.05.00.02.031.018+PATCH[ES]_msm8916_32_refs/tags/AU_LINUX_ANDROID_LA.BR.1.1.2_RB1.05.00.02.031.018__release_ENGG (I856e09677e)
OpenGL ES Shader Compiler Version: E031.25.03.02
Build Date: 04/06/15 Mon
Local Branch:
Remote Branch: refs/tags/AU_LINUX_ANDROID_LA.BR.1.1.2_RB1.05.00.02.031.018
Local Patches: 112c106f3772623daa7b4181c6cf23491044ead1 Revert "Disable ASTC on A405"
58a118cb818fdc906095a49a90977c15f9d3b223 Remove ASTC
08-24 09:42:43.138 8935-8951/com.example.dawid.camerabezpodgladu I/OpenGLRenderer﹕ Initialized EGL, version 1.4
08-24 09:42:43.158 8935-8951/com.example.dawid.camerabezpodgladu D/OpenGLRenderer﹕ Get maximum texture size. GL_MAX_TEXTURE_SIZE is 4096
08-24 09:42:43.158 8935-8951/com.example.dawid.camerabezpodgladu D/OpenGLRenderer﹕ Enabling debug mode 0
08-24 09:42:43.258 8935-8935/com.example.dawid.camerabezpodgladu I/Timeline﹕ Timeline: Activity_idle id: android.os.BinderProxy#3d659231 time:4110726
08-24 09:42:44.648 8935-8935/com.example.dawid.camerabezpodgladu D/ViewRootImpl﹕ ViewPostImeInputStage ACTION_DOWN
08-24 09:42:45.678 8935-8935/com.example.dawid.camerabezpodgladu I/Choreographer﹕ Skipped 34 frames! The application may be doing too much work on its main thread.
08-24 09:43:45.138 8935-8935/com.example.dawid.camerabezpodgladu W/CameraBase﹕ An error occurred while connecting to camera: 0
08-24 09:43:45.498 8935-8935/com.example.dawid.camerabezpodgladu D/AndroidRuntime﹕ Shutting down VM
08-24 09:43:45.498 8935-8935/com.example.dawid.camerabezpodgladu E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.dawid.camerabezpodgladu, PID: 8935
java.lang.RuntimeException: startPreview failed
at android.hardware.Camera.startPreview(Native Method)
at com.example.dawid.camerabezpodgladu.CameraPreview.surfaceCreated(CameraPreview.java:31)
at android.view.SurfaceView.updateWindow(SurfaceView.java:682)
at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:200)
at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:921)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2226)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1239)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6752)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:777)
at android.view.Choreographer.doCallbacks(Choreographer.java:590)
at android.view.Choreographer.doFrame(Choreographer.java:560)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:763)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6145)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
08-24 09:43:48.818 8935-8935/com.example.dawid.camerabezpodgladu I/Process﹕ Sending signal. PID: 8935 SIG: 9
Even once method takePicture isn't called. Error is getting from bad realesing camera and reopening it after minute (next handler action).
I will be very thankful for even one tip
Dawid
Finally figured out how to set the phone to take timed pics without any screen display.
There were 2 main issues I struggled with. First, I wanted to take the pics without displaying to screen. Along those lines, I found an example where they used :
mCamera.setPreviewTexture(new SurfaceTexture(10));
and nothing showed on the screen when using this preview method. It appears that some sort of preview is required. Another method was to set the preview to 1 pixel. This method had examples online which appeared to work as well, but I did not try it.
The second and bigger problem had to do with 'onPictureTaken' method. This method processes your picture after the 'takePicture' call. This is where the first answer (above) was tripping me up.
It seemed that no matter what looping method I used, or where in the code the call to 'takePicture' was located, all of the 'onPictureTaken' methods were queued up and called one after another once the parent of the 'takePicture' caller ended.
Although the picture data processed by onPictureTaken were in a proper time sequence, I could see that having several hundred pics stored and waiting to process could cause problems, and a method needed to be found where on pic was processed and stored before the next pic was taken.
Along those lines, I stumbled upon the AlarmManager and coupled that with the BroadcastReceiver and Future classes to solve the problem.
What I've done is set the alarmManger to go off at a set time or time frequency. The BroadcaseReceiver captures this call & in turn calls a method which creates
a thread where a 'Future' object makes the call to take a picture.
'Future' object is nice, because it will wait for the physical camera to take the picture (takePicture) and then process it (onPictureTaken). This all occurs in one thread, then terminates. So no queuing of pics to process and each picture sequence is handled separately.
Code is contained below. Note that some of the default 'Overrides' have been left out to save space. Also, the visible screen was basically a button which captured the click event...very basic.
MainActivity.java:
package myTest.com.test;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class MainActivity extends Activity {
CameraHandler cameraHandler;
public BroadcastReceiver br;
public PendingIntent pi;
public AlarmManager am;
final static private long LOOPTIME = 20000;
private static final ExecutorService threadpool = Executors.newFixedThreadPool(3);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setup();
}
private void setup() {
try{
cameraHandler = new CameraHandler();
br = new BroadcastReceiver() {
#Override
public void onReceive(Context c, Intent i) {
//Toast.makeText(c, "Taking a pic!", Toast.LENGTH_LONG).show();
TryAThread();
}
};
registerReceiver(br, new IntentFilter("com.timedActivity.activity") );
pi = PendingIntent.getBroadcast(this, 0, new Intent("com.timedActivity.activity"), 0);
am = (AlarmManager)(this.getSystemService( Context.ALARM_SERVICE ));
}
catch (Exception e){ }
}
private void TryAThread() {
try{
CameraCaller cameraCaller = new CameraCaller(cameraHandler);
Future future = threadpool.submit(cameraCaller);
while (!future.isDone()) {
try {
Thread.sleep(5000);
} catch (Exception ex) { }
}
}
catch (Exception e){ }
}
#Override
protected void onDestroy() {
am.cancel(pi);
unregisterReceiver(br);
super.onDestroy();
}
public void onClickListener(View view){
try{
am.setRepeating(am.ELAPSED_REALTIME,SystemClock.elapsedRealtime(), LOOPTIME, pi);
}
catch (Exception e){ }
}
}
CameraCaller.java:.
package myTest.com.test;
import java.util.concurrent.Callable;
public class CameraCaller implements Callable {
private CameraHandler cameraHandler;
public CameraCaller(CameraHandler ch){
cameraHandler = ch;
}
#Override
public Object call() throws Exception {
cameraHandler.takeAPic();
return true;
}
}
CameraHandler.java:.
package myTest.com.test;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.os.Environment;
import android.util.Log;
import junit.runner.Version;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class CameraHandler implements Camera.PictureCallback{
private Camera mCamera;
public CameraHandler(){
}
public Boolean takeAPic(){
try{
if (mCamera == null){
mCamera = Camera.open();
mCamera.enableShutterSound(false);
try {
mCamera.setPreviewTexture(new SurfaceTexture(10));
}
catch (IOException e1) {Log.e(Version.id(), e1.getMessage());
}
}
mCamera.startPreview();
mCamera.takePicture(null, null, this);
}
catch (Exception ex){ }
return true;
}
#Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile();
if (pictureFile == null) {
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
} catch (IOException e) { }
try {
Thread.sleep(2000);
}catch (Exception ex){}
}
public static File getOutputMediaFile() {
File file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File mediaStorageDir = new File(file, "MyCameraApp");
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");
return mediaFile;
}
}
Well David, you want 1 tip? I'm working on a similar problem and this may get you a little further down the road...to where I'm currently stuck.
I can take a picture without preview using the following.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
cameraHandler = new CameraHandler();
tryThis();
}
private void tryThis(){
cameraHandler.takeAPic();
}
And the class is:
public class CameraHandler implements Camera.PictureCallback{
private Camera mCamera;
public CameraHandler(){ }
public void takeAPic(){
try{
if (mCamera == null){
mCamera = Camera.open();
mCamera.enableShutterSound(false);
try {
mCamera.setPreviewTexture(new SurfaceTexture(10));
}
catch (IOException e1) { }
}
mCamera.startPreview();
mCamera.takePicture(null, null, this);
}
catch (Exception ex){ }
}
#Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile();
if (pictureFile == null) {
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
}
catch (FileNotFoundException e) { }
catch (IOException e) { }
}
The problem I'm running into now is that any code I put in following the 'takePicture' is not causing the 'onPictureTaken' to be called.
However, this will at least get you to a spot where you can take a picture without a preview. Maybe you can figure out how to make multiple calls to snap the pictures
I am currently facing following big problem:
I have a Framework-Project (maven), where a PropertyReader is included (reads "config.properties" in the same package and returns its values):
This is the Framework-Project:
public class PropertyReaderFramework {
private static Properties props;
private static void init(){
String filename = "com/ks/framework/properties/config.properties";
InputStream input = PropertyReaderFramework.class.getClassLoader()
.getResourceAsStream(filename);
if (input == null) {
System.out.println("Sorry, unable to find " + filename);
props = null;
} else {
props = new Properties();
}
try {
props.load(input);
} catch (IOException e) {
e.printStackTrace();
}
}
public static String getProperty(String key){
if(props == null) init();
return props.getProperty(key);
}
public static Properties getProperties(){
if(props == null) init();
return props;
}
}
And my main-project, where I need the information of the properties-file just has one class (for demonstation):
package testmsg;
import com.ks.framework.properties.PropertyReaderFramework;
public class main {
public static void main(String[] args) throws InterruptedException {
try {
String basepath = PropertyReaderFramework.getProperty("remoteFileAccess.script.location");
System.out.println(basepath);
} catch (Exception e) {
e.printStackTrace();
} finally {
Thread.sleep(5000);
}
}
}
The funny thing is, that if I execute the main() class in eclipse, it reads the value from the properties correctly.
But when I export it as a runnable JAR, it throws me following error:
Can anyone help me to solve this problem? I cannot figure out why it behaves like that...
We use the ScheduledThreadPoolExecutor and after submitting the job we call shutdown immediately.
Because as per doc Shutdown does not kill the submitted task, running task and allows it to complete.
The question is after shutdown can we continue to use the future object that the ScheduledThreadPoolExecutor submit returns.
private static Future submitACall(Callable callableDelegate) {
ScheduledThreadPoolExecutor threadPoolExe = null;
try {
threadPoolExe = new ScheduledThreadPoolExecutor(1);
return threadPoolExe.submit(callableDelegate);
} finally {
threadPoolExe.shutdown();
}
}
//in another method...
if(future.isDone())
future.get();
Yes, you can, in a try-catch:
package testsomething;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledThreadPoolExecutor;
public class TestSomething {
private static Future future = null;
private static ScheduledThreadPoolExecutor threadPoolExe = null;
public static void main(String[] args) {
Callable callableDelegate = new MyCallable();
future = submitACall(callableDelegate);
try {
System.out.println("First get: " + ((Integer)future.get()));
} catch (InterruptedException | ExecutionException ex) {
System.out.println("Exception: " + ex);
}
try {
Thread.sleep(100L);
} catch (InterruptedException ex) {
System.out.println("Exception: " + ex);
}
try {
System.out.println("Thread pool shut down? " + threadPoolExe.isShutdown());
System.out.println("Second get through 'anotherMethod': " + anotherMethod());
} catch (InterruptedException | ExecutionException ex) {
System.out.println("Exception: " + ex);
}
}
private static Future submitACall(Callable callableDelegate) {
try {
threadPoolExe = new ScheduledThreadPoolExecutor(1);
return
threadPoolExe.submit(callableDelegate);
} finally {
threadPoolExe.shutdown();
}
}
private static Integer anotherMethod() throws ExecutionException, InterruptedException {
if(future.isDone())
return ((Integer)future.get());
else
return null;
}
private static class MyCallable implements Callable {
#Override
public Object call() throws Exception {
return new Integer(0);
}
}
}