Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Java Development

Reply
Highlighted
New Contributor
Posts: 7
Registered: ‎05-19-2011
My Device: Curve 8520 IOS 4.6.1
My Carrier: Telcel

Using FileSystemJournalListener to invoke my App

[ Edited ]

Hi everyone

 

So I'm using the FileSystemJournalListener from the file explorer demo, and I adapted it so that when a file is written to the device, a pop up appears and asks the user if they want to open the just downloaded file with my App.

The FileSystemJournalListener is registered via the "normal" way and it runs on startup to listen to changes, and an alternate entry point is registered  with the arg "gui" to run the main app when the App icon is clicked.

 

There are several problems with this

First, when I test this in the simulator it works "fine", because I take a picture with the camera, it detects that a "jpg" file has been written and asks me if I want to open it with my app. As far as I know there are no other ways to test this functionality because you cannot download attachments from emails using ESS. Is there any other way I can test this?

 

Second, when I test this code on a real device, it does not work! It does not detect any writing on the device at all. Not even pictures. I dont understand what is going on.

 

And third, I have now two instances of my app running, one for the FileSystemJournalListener and the other one for the main app, and if I check the ribbon or task switching menu on the device I can see the 2 instances, of course I dont want this, is there a way to hide icons on the ribbon? Or a workaround to show only the one for the main app?

 

Thanks!

 

 

Trusted Contributor
Posts: 224
Registered: ‎08-11-2010
My Device: Not Specified

Re: Using FileSystemJournalListener to invoke my App URGENT

> is there a way to hide icons on the ribbon?

 

To prevent this, you need to mark one of the entry points as "system". 

Developer
Posts: 19,636
Registered: ‎07-14-2008
My Device: Not Specified

Re: Using FileSystemJournalListener to invoke my App URGENT

[ Edited ]

First the easy one, the two icons.

 

Marking it as System will stop the icon appearing but not, as far as I know, stop the second icon appearing in the Switch Application List. 

 

I could suggest ways around this, but in fact I would design your application differently.

 

You need to start your application at device startup and register your Listener.  However your Listener does not need to have a running Application.  It will stay there even if you Application is shutdown.  So I would use an Alternate Entry.  Have the normal icon entry start your Application.  have the ';start-up' version just register your Listener and exit. 

 

Now why does it not work on the device.  There are variety of possibilities..  But since it is difficult to test and debug startup code, I suggest you have a menu item in your normal application that can be used to add the File Listener.  Then debug on device, start-up your application and watch what happens when you try to integrate the Listener into the System.

 

If this works fine, then the most likely possibility is that you are trying to start your application before the system is ready.  Have a look at this KB article for my preferred approach to initiating processing at start-up time.

 

http://supportforums.blackberry.com/t5/Java-Development/Write-safe-initialization-code/ta-p/444795

 

Edit: The comment above about not needing an application is NOT correct.  You do.  See later.

 

New Contributor
Posts: 7
Registered: ‎05-19-2011
My Device: Curve 8520 IOS 4.6.1
My Carrier: Telcel

Re: Using FileSystemJournalListener to invoke my App URGENT

Thanks a lot Peter

 

I will try to implement something similar to the KB article.

 

OK so.

 

What I have to do at start up is, use the normal entry for my app, and register an alternate entry point to run on startup, register the JournalListener and exit.

 

Now I have some other questions.

 

If the listener does not have a running Application, how can I add it to the device so it can start listening?

Right now the code look something like this

 

public class InitScreen extends UiApplication{
    static InitScreen mainScreen = new InitScreen();
    static LoginCallerScreen loginScreen = new LoginCallerScreen();

    public static void main(String[] args){
        if(args != null && args.length >0 && args[0].equals("gui")){
            SplashScreen splashScreen = new SplashScreen(mainScreen, loginScreen);
             mainScreen.pushScreen(splashScreen);
        }else{
             ContextJournalListener screen = new ContextJournalListener();
             mainScreen.addFileSystemJournalListener(screen);
        }
        mainScreen.enterEventDispatcher();
    }
}

 

 

So the listener is added here: mainScreen.addFileSystemJournalListener(screen);

but if it does not have a running UiApplication, the where do you add it?

 

Also, can you help me with some code or KB article on how to mark my app as "System"?

 

And regarding the simulator question I asked, is there any other way to simulate writing a file? Because the only way I can do this right now is by taking a picture, but it would be great if there was some other way.

 

Thanks a lot!

 

New Contributor
Posts: 7
Registered: ‎05-19-2011
My Device: Curve 8520 IOS 4.6.1
My Carrier: Telcel

Re: Using FileSystemJournalListener to invoke my App URGENT

Thanks KraKra

 

I checked this "System" option you and Peter mentioned, and in Eclipse that option was renamed to "Do not display the application icon on the BlackBerry home screen", and I do actually have that checked por the alternate entry point, that keeps it from appearing in the "Downloads" folder, but I can still see the icon when switching applications, that menu you get when you press and hold the BB menu button and you can see all active apps.

And of course I dont want to confuse the user with two icons in the switching apps menu. Also, if I click the Alternate Entry point icon, the simulator loops, and gets stuck forever, until I close it of course.

 

What can I do about this?

Developer
Posts: 19,636
Registered: ‎07-14-2008
My Device: Not Specified

Re: Using FileSystemJournalListener to invoke my App URGENT

[ Edited ]

Apologies, I was wrong in saying that you did not need an Application for the FileSystemJournalListener - you do.

 

So the idea is to suppress the icon in the switch application list for that instance.  Fortunately it is pretty easy.  All you need to do is return false, to a call on 

acceptsForeground()

 

So implement acceptsForeground() in your MainScreen application, and have it check in some way that it is running the Listener and not the icon.  If running the listener, return false, otherwise true.  And the icon will disappear!

 

Re testing - write a program to create a file.  That is the easiest way. 

 

Edit - just had a thought.  You might put your application into the foreground to display the 'shall I process this file' screen.  If you do, then acceptsForeground returning false will stop this happening.  So you might have to vary this depending on the state of the listener.

 

Alternatively you might use a Global screen which will work correctly even if acceptsForeground returns false.

New Contributor
Posts: 7
Registered: ‎05-19-2011
My Device: Curve 8520 IOS 4.6.1
My Carrier: Telcel

Re: Using FileSystemJournalListener to invoke my App URGENT

Thanks a lot for the quick response Peter, I'm getting the hang now on the BB API... baby steps

 

So basically this is the code for my JournalListener

 

public final class ContextJournalListener implements FileSystemJournalListener {
	
	private long _lastUSN; // = 0;
	private String[] supported = {"doc", "docx", "xls", "xlsx", "ppt", "pptx", "pdf", "txt", "bmp", "jpg", "jpeg", "gif", "png"};

	public void fileJournalChanged() {
		long nextUSN = FileSystemJournal.getNextUSN();
		String msg = null;
		String fullpath = null;

		for (long lookUSN = nextUSN - 1; lookUSN >= _lastUSN && msg == null; --lookUSN) {
			FileSystemJournalEntry entry = FileSystemJournal.getEntry(lookUSN);
			
			if (entry == null) {
				break;
			}
			String path = entry.getPath();
			if (path != null) {
				if (entry.getEvent() == FileSystemJournalEntry.FILE_ADDED) {
					if(validateFileExt(path)){
						msg = "¿Use MyApp?";
						fullpath = path;
					}
				}
			}
		}
		_lastUSN = nextUSN;
		if (msg != null && fullpath != null) {
			showMessage(msg, fullpath);
		}
	}
	
    private boolean validateFileExt(String name){
           // Non important code
    }

    private void showMessage(String msg, String path) {
        synchronized (Application.getApplication().getAppEventLock()) {
        	UiEngine ui = Ui.getUiEngine();
        	Screen screen = new Dialog(Dialog.D_YES_NO, msg, Dialog.YES, Bitmap.getPredefinedBitmap(Bitmap.QUESTION), Manager.VERTICAL_SCROLL);
            ui.pushGlobalScreen(screen, 1, UiEngine.GLOBAL_MODAL);
            int value = ((Dialog)screen).getSelectedValue();
            if(value == Dialog.YES){
            	String finalPath = path.substring(1);
            	FileExplorerFileHolder file = new FileExplorerFileHolder(finalPath);
            	LoginCallerScreen myscreen = new LoginCallerScreen(file);
            	ui.pushScreen(myscreen);
            	Application.getApplication().requestForeground();
            }
        }
    }
}

 

So, I already use the pushGlobalScreen method so how would I implement the acceptsForeground() method?

 

This class does not extend from any other class, should it? Extend from Application or something like that? maybe MainScreen?

 

Oh and also the LoginCallerScreen extends from MainScreen, but after the actual "login screen" I have another MainScreen, the one that manages the actual app. And right now I am overriding the onClose() method in the LoginCallerScreen so that it stays on background... I hope that is useful somehow

 

Thanks!

Developer
Posts: 19,636
Registered: ‎07-14-2008
My Device: Not Specified

Re: Using FileSystemJournalListener to invoke my App URGENT

OK, this is getting messy. 

 

Have a look at this code:

            ui.pushGlobalScreen(screen, 1, UiEngine.GLOBAL_MODAL);
            int value = ((Dialog)screen).getSelectedValue();
            if(value == Dialog.YES){

Now you have pushed the Global Screen, and it will appear.  But you don't wait for a response.  To do that the screen would have to be Modal.  its not, so the push will display the screen, but let processing continue.  So with this code it looks like you will always process through the LoginCallerScreen. 

 

However I don't think you can in fact do a push Modal here.

 

And it gets worse, because you actually do use the 'listening application to display the screens.  So we can't use the acdeptsForeground trick.

 

I'll need to think about this.

 

Can you tell me what your users will expect to happen should they click on the icon? 

New Contributor
Posts: 7
Registered: ‎05-19-2011
My Device: Curve 8520 IOS 4.6.1
My Carrier: Telcel

Re: Using FileSystemJournalListener to invoke my App

Thanks again Peter

 

Ok, so..

My app is supposed to be used to print files.
So I have my main app, with it users login to a server, if the login was valid, the user can access the app. Inside the app you can choose any file you like from the device, using a file explorer, and then print it (used in a closed network).  The users already know the printers an the printing system which is not important.

That is the functionality they get when they click the main application icon.

 

On the other side of the app I want to check when the files are written to the device, when they are downloaded from browser or recieved on an email, doesn't matter. So I create an alternate entry point with the arg "list" to auto run on start-up and to hide the home icon.

 

In my "main" method (changed now from previous post):

	public static void main(String[] args){
		if(args != null && args.length >0 && args[0].equals("list")){
			try {
				Application appInstance = Application.getApplication();
				ContextJournalListener screen = new ContextJournalListener();
				if (ApplicationManager.getApplicationManager().inStartup()) {
					appInstance.addFileSystemJournalListener(screen);
				} else {
					mainScreen.doStartupWorkLater();
				}
			} catch (Exception e) {
				System.out.println("Journal: " + e.toString());
			}
		}else{
			foreground = true;
			SplashScreen splashScreen = new SplashScreen(mainScreen, loginScreen);
			mainScreen.pushScreen(splashScreen);
		}
		mainScreen.enterEventDispatcher();
	}

 It is a bit like the KB article you told me about, so you can imagine what the method "doStartupWorkLater()" doe.

 

Ok so wirth this AlternateEntryPoint I am trying to register JournalListener, and in the Listener, if a file is downloaded or written I ask the user if they want to use myapp to print this new file, if the click "YES", then my LoginScreen should be called, so that they can login to the app and print the file.

 

The "final" functionality I want to achieve is so that my app behaves like "Documents to go", that app that is used to open MS Office files.

 

I hope its clear enough.

 

Thanks again