Launching the application from an url in the browser for BlackBerry? - blackberry

I am developing one application where i will launch a url in the browser from which i will launch my application.
Suppose if i will click google.com, and press enter, it will launch my application. For that i tried with the HttpFilterRegistry API.
For reference i am using the HTTPFilterDemo application. But currently while launching the app, i am getting the NullPointerException.
I wrote the below code i the openFilter Method:
public Connection openFilter(String name, int mode, boolean timeouts) throws IOException {
Logger.out("Protocol", "it is inside the openFilter method");
_url = name.substring(2);
_requestHeaders = new HttpHeaders();
_responseHeaders = new HttpHeaders();
_responseHeaders.setProperty(HttpProtocolConstants.HEADER_CONTENT_TYPE, "text/html");
Logger.out("Protocol", "here it is come ::::44444444");
final int modHandle = CodeModuleManager.getModuleHandle("AppLaunchBrowser");
Logger.out("Protocol", "here is the module handle:::" + modHandle);
final ApplicationDescriptor[] apDes = CodeModuleManager.getApplicationDescriptors(modHandle);
final ApplicationDescriptor appDescriptor = new ApplicationDescriptor(apDes[0], new String[] {});
Logger.out("Protocol", "here is the app descriptor:::" + appDescriptor);
try {
final int appCode = ApplicationManager.getApplicationManager().runApplication(appDescriptor, true);
Logger.out("Protocol", "here is the app code:::" + appCode);
} catch (ApplicationManagerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// }
return this;
}
And in the application class i am creating alternative entry point and using like below:
public class AppLaunch extends UiApplication{
public static void main(String args[])
{
Logger.out("AppLaunch", args+"length of the arguments::::" +args.length);
if((args != null) && (args.length > 0) && (args[0].equals("background")))
{
Logger.out("AppLaunch", "in the alternate entry point");
// Logger.out("AppLaunch", args+"length of the arguments::::" +args.length);
HttpFilterRegistry.registerFilter("www.google.co.in", "com.innominds.ca", false);
}
else
{
Logger.out("AppLaunch", "Inside the Applaunch");
AppLaunch theApp = new AppLaunch();
theApp.requestForeground();
Logger.out("AppLaunch", "created the app launch object");
theApp.enterEventDispatcher();
// Logger.out("AppLaunch", "in the alternate entry point");
// HttpFilterRegistry.registerFilter("www.google.co.in", "com.innominds.ca", false);
}
}
public AppLaunch()
{
checkPermissions();
showTestScreen();
}
private void checkPermissions()
{
ApplicationPermissionsManager apm = ApplicationPermissionsManager.getInstance();
ApplicationPermissions original = apm.getApplicationPermissions();
if(original.getPermission(ApplicationPermissions.PERMISSION_BROWSER_FILTER) == ApplicationPermissions.VALUE_ALLOW)
{
// All of the necessary permissions are currently available
return;
}
ApplicationPermissions permRequest = new ApplicationPermissions();
permRequest.addPermission(ApplicationPermissions.PERMISSION_BROWSER_FILTER);
boolean acceptance = ApplicationPermissionsManager.getInstance().invokePermissionsRequest(permRequest);
if(acceptance)
{
// User has accepted all of the permissions
return;
}
else
{
}
}
private void showTestScreen()
{
UiApplication.getUiApplication().pushScreen(new AppLaunchScreen());
}
}

Finally i was able to resolve this issue. Actually NPE is coming in some other callback methods because i was implementing the FilterBaseInterface.

Related

LWUIT Uncaught exception: java.lang.OutOfMemoryError(stack trace incomplete)

I developed an Rss Application using LWUIT Tabs,i want to display Rss Feed Titles and images on my Lwuit Tab screen,but when i run my application i am able to display three List (title with image)items Sucessfully,after that i am facing java.lang.OutOfMemoryError(stack trace incomplete) Eventhough there are list items present?can any one help......thanks...
Here my Code:
public class Process {
protected XMLMidlet midlet;
Form form1;
Image image;
Tabs tabs;
private List myNewsList;
private Vector topnews;
private Vector topstory;
private Command cmdExit;
private Command m_backCommand;
private List newsList;
private Form form2;
Process(XMLMidlet midlet) throws IOException {
this.midlet=midlet;
topnews = new Vector();
topstory = new Vector();
tabs = new Tabs();
form1 = new Form();
form2=new Form();
try {
newsList = new List(topnews);
newsList.setScrollVisible(false);
newsList.setRenderer(new NewsListCellRenderer());
m_backCommand = new Command("Back");
cmdExit = new Command("EXIT");
tabs.addTab("Topstory", newsList);
form1.addComponent(BorderLayout.CENTER, tabs);
}
catch(Exception e){
e.printStackTrace();
} }
public void process() {
try{
String url = "http://www.teluguone.com/news/tonefeeds/news/news-1.rss";
form1.show();
ParseThread myThread = new ParseThread(this);
myThread.getXMLFeed(url);
} catch (Exception e) {
}
}
public void addNews(News newsItem) {
try{
topnews.addElement(newsItem);
newsList.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
List source = (List) ae.getSource();
News selectedNewsItem = (News) source.getSelectedItem();
if (selectedNewsItem != null) {
displayCompleteNewsScreen(selectedNewsItem);
}
}
});
}
catch(OutOfMemoryError r){
}
form1.show();
}
private void displayCompleteNewsScreen(News detailNews) {
try{
form2.removeAll();
form2.repaint();
form2.addCommand(m_backCommand);
form2.addCommandListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
form1.show();
}
});
HTMLComponent com=new HTMLComponent();
com.setPreferredSize(new Dimension(300,300));
com.setShowImages(false);
com.setBodyText(detailNews.getDescription());
form2.addComponent(com);
//form2.addComponent(big);
}
catch(OutOfMemoryError e){
}
form2.show();
}
}
How big are the images? What handset are we talking about here?
I am betting that the images you're getting are not being scaled down before being displayed. I believe there are methods in LWUIT to scale down the size of an image. Remember to dispose of the temp image you create after adding the image to your form.

I want to show splash screen until i am done with downloading xml files from server and after completion show next screen

I am trying to download xml files from server when my application starts. So i want to show splash screen until am done with downloading and then show next screen. below is my code:
Here, i want to show My splash screen when getTopNotDoc() method is under execution. and after completion of that method show next screen.
//get _topics and notification document<br>
_getDoc = new ServerConnectivity(this);
public class ServerConnectivity {
private Document _questionDoc;
private Document _topics;
private Document _notifications;
public ServerConnectivity(ApplicationSession appSession){
//getTopNotDoc();
_this = this;
_appSession = appSession;
new Thread(new Runnable(){
public void run(){
getTopNotDoc();
}
}).start();
}
}
private void getTopNotDoc(){
InputStream inputStream = null ;
try{
// Build a document based on the XML file.
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
inputStream = getClass().getResourceAsStream("topics.xml");
_topics = builder.parse( inputStream );
inputStream = getClass().getResourceAsStream("notification.xml");
_notifications = builder.parse( inputStream );
if(_topics == null || _notifications == null){
Dialog.alert("Unable to connect to internet");
}
}
catch ( Exception e ){
System.out.println( e.toString() );
}
finally{
if(inputStream != null){
try {
inputStream.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
}
Usually when I do this, I create a loading screen, then I just extend the Thread class.
So I would create a loading screen like this:
public class LoadingScreen extends MainScreen {
public LoadingScreen() {
super();
this.setTitle("loading...");
// add a spinning animated gif or whatever here
final Screen me = this;
new Thread(new Runnable(){
public void run(){
// do something that takes a long time
try { Thread.sleep(1000);} catch (Exception e) {}
}
}){
public void run() {
super.run();
synchronized (UiApplication.getEventLock()) {
UiApplication.getUiApplication().popScreen(me);
}
}
}.start();
}
}
Then I push this screen, it will perform the long task, and then pop itself when its done.
(you may or may not want to disable the back button and menus on this screen)
I made the Runnable as an anonymous inner class just to compact the code, but you probably have this code already in a class somewhere else, so you would pass it in instead.
To add some flexibility and keep your classes loosely coupled together, you could make some modifications to your ServerConnectivity class so your calls could go something like the following:
// push your splash screen on to the stack
//
final SplashScreen splashScreen = new SplashScreen();
UiApplication.getUiApplication().pushScreen(splashScreen);
_getDoc = new ServerConnectivity(this, new ServerConnectivityListener() {
public void onCompleted(ServerConnectivity sender) {
// display next screen
//
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
splashScreen.close();
UiApplication.getUiApplication().pushScreen(new NextScreen());
}
});
}
public void onError(ServerConnectivity sender) {
splashScreen.close();
// display error message, retry, etc...
}
});
For this to work, you need an interface with the following definition:
public interface ServerConnectivityListener {
void onCompleted(ServerConnectivity sender);
void onError(ServerConnectivity sender);
}
So, your ServerConnectivity class maintains a reference to some object that implements the interface called ServerConnectivityListener This allows you to maintain loose coupling between the subject class and any observers that need to listen for events.
Within ServerConnectivity, you would make calls to the listener's methods something like this:
// begin excerpt from above...
//
if(_topics == null || _notifications == null) {
_listener.onError(this);
} else {
_listener.onCompleted(this);
}
catch ( Exception e ){
System.out.println( e.toString() );
_listener.onError(this);
//
// end excerpt from above...
Here is code for splash screen in java........after and call that view.........
http://www.randelshofer.ch/oop/javasplash/javasplash.html
import java.awt.*;
import java.awt.event.*;
public class SplashTest extends Frame implements ActionListener {
static void renderSplashFrame(Graphics2D g, int frame) {
final String[] comps = {"foo", "bar", "baz"};
g.setComposite(AlphaComposite.Clear);
g.fillRect(130,250,280,40);
g.setPaintMode();
g.setColor(Color.BLACK);
g.drawString("Loading "+comps[(frame/5)%3]+"...", 130, 260);
g.fillRect(130,270,(frame*10)%280,20);
}
public SplashTest() {
super("SplashScreen demo");
setSize(500, 300);
setLayout(new BorderLayout());
Menu m1 = new Menu("File");
MenuItem mi1 = new MenuItem("Exit");
m1.add(mi1);
mi1.addActionListener(this);
MenuBar mb = new MenuBar();
setMenuBar(mb);
mb.add(m1);
final SplashScreen splash = SplashScreen.getSplashScreen();
if (splash == null) {
System.out.println("SplashScreen.getSplashScreen() returned null");
return;
}
Graphics2D g = (Graphics2D)splash.createGraphics();
if (g == null) {
System.out.println("g is null");
return;
}
for(int i=0; i<100; i++) {
renderSplashFrame(g, i);
splash.update();
try {
Thread.sleep(200);
}
catch(InterruptedException e) {
}
}
splash.close();
setVisible(true);
toFront();
}
public void actionPerformed(ActionEvent ae) {
System.exit(0);
}
public static void main (String args[]) {
SplashTest test = new SplashTest();
}
}
Since,it is a thread based one,We cannot do it the normal way.So Check the following link
http://supportforums.blackberry.com/t5/Java-Development/What-is-the-Event-Thread/ta-p/446865
and Check whether parsing is done,Until that have the same screen,Check the condition of whehter it is downloaded or not ,and then push the screen

Loading Screen in BlackBerry

Suppose this is my NeteorkingMainScreen class which will display the text retrived from web.
public NetworkingMainScreen() {
setTitle("Networking");
urlField = new EditField("URL:", "");
textOutputField = new RichTextField();
add(urlField);
add(textOutputField);
}
protected void makeMenu(Menu menu, int instance) {
super.makeMenu(menu, instance);
menu.add(new MenuItem("Get", 10, 10) {
public void run() {
getURL();
}
});
private void getURL() {
HttpRequestDispatcher dispatcher = new HttpRequestDispatcher(urlField.getText(),"GET", this);
dispatcher.start();
}
//*********************************************************************************
//HttpRequestDispatcher class performs the downloading of contents of webpage.
public class HttpRequestDispatcher extends Thread {
private String url;
private String method; // GET or POST
private NetworkingMainScreen screen;
public HttpRequestDispatcher(String url, String method, NetworkingMainScreen screen){
this.url = url;
this.method = method;
this.screen = screen;
}
public void run() {
try{
HttpConnection connection = (HttpConnection)Connector.open(url);
connection.setRequestMethod(method);
int responseCode = connection.getResponseCode();
if (responseCode != HttpConnection.HTTP_OK){
screen.requestFailed("Unexpected response code: " + responseCode);
connection.close();
return;
}
String contentType = connection.getHeaderField("Content-type");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
InputStream responseData = connection.openInputStream();
byte[] buffer = new byte[10000];
int bytesRead = responseData.read(buffer);
while(bytesRead > 0) {
baos.write(buffer, 0, bytesRead);
bytesRead = responseData.read(buffer);
}
baos.close();
connection.close();
screen.requestSucceeded(baos.toByteArray(), contentType);
}
catch (IOException ex) {
screen.requestFailed(ex.toString());
}
}
}
//***************************************************************************
//WaitScreen displays animation till the downloading is completed.
class WaitScreen extends FullScreen
{
}
Now I m getting confused...
When to start the WaitScreen class. Suppose i start by creating an object of WaitScreen and pushing the screen object.
protected void makeMenu(Menu menu, int instance) {
super.makeMenu(menu, instance);
menu.add(new MenuItem("Get", 10, 10) {
public void run()
UiApplication.getUiApplication.pushScreen(new WaitScreen());
getURL();
}
});
How would my code know that it should displaying the animated Screen and display the contents of the webpages ie i mean how my code will knows downloading data has been completed. ie when i will call popScreen()?
I interface is to be used how can use the interface and what help we will get by using the interface.? Plz help
This is rather simple.
Your HttpRequestDispatcher should have a handle to the WaitScreen instance to be able to show it on start and close it upon completion.
So inside of the HttpRequestDispatcher you could (1) create the WaitScreen. (2) Push it. (3) Do the stuff the HttpRequestDispatcher should do. (4) Pop the the WaitScreen. Smth like that:
final WaitScreen waitScreen = new WaitScreen();
// just to reduce code duplication
final UiApplication app = UiApplication.getUiApplication();
// we are on the non-UI thread, so need
// to use UiApplication.invokeLater(Runnable action),
// it safely runs the passed action on the UI thread
app.invokeLater(new Runnable() {
public void run() {
app.pushScreen(waitScreen);
}
});
try {
// main networking actions go here
} catch (..) {
// error handling goes here
} finally {
// make sure we close the waitScreen
app.invokeLater(new Runnable() {
public void run() {
app.popScreen(waitScreen);
}
});
}
Here, Try this. All you have to do is put your code into the "run" function.
If you want help with the HttpRequest stuff or have trouble with the classes there, let me know. I have a web library with thread classes set up to use the classes within that post.

previous instance still active error in blackberry

I created app which user can start from menu and from icon. I do not use GlobalEventListener in my app, just register ApplicationMenuitem. And now I am getting error: previous instance still active when launch my app.
Steps to reproduce not so trivial:
launch app from icon
do not close it, just switch to another app
launch app from icon again
I founded article in blackberry's forum about it , but I can't find solution where I should remove my ApplicationMenuItem: it added on phone boot and should show all the time.
My code:
public class Jingu extends UiApplication {
public static void main(String[] args) {
ApplicationManager app = ApplicationManager.getApplicationManager();
boolean keepGoing = true;
while (keepGoing) {
if (app.inStartup()) {
try {
Thread.sleep(1000);
} catch (Exception e) {}
} else {
keepGoing = false;
}
}
Jingu theApp = new Jingu();
theApp.initMenuItem();
theApp.showMainScreen();
theApp.enterEventDispatcher();
}
public Jingu() {
}
public void showMainScreen() {
showScreen(new JinguMainScreen(this));
}
public void initMenuItem() {
// Create menu item
Object o = RuntimeStore.getRuntimeStore().get(JinguMenuItem.MY_MENU_ID);
// register only if not done already.
if (o == null) {
new JinguMenuItem(this).registerInstance();
}
}
public void showScreen(Screen aScreen) {
synchronized (Application.getEventLock()) {
try {
UiApplication.getUiApplication().popScreen(aScreen);
} catch (Exception e) {
}
UiApplication.getUiApplication().pushScreen(aScreen);
}
}
}
public class JinguMenuItem extends ApplicationMenuItem {
public static final long MY_MENU_ID = 0xb9739d5240d5943dL;
private final Jingu jingu;
public JinguMenuItem(Jingu jingu) {
super(0x350100);
this.jingu = jingu;
}
public void registerInstance() {
Object menuItem = RuntimeStore.getRuntimeStore().remove(MY_MENU_ID);
if (menuItem == null) {
ApplicationMenuItemRepository amir = ApplicationMenuItemRepository.getInstance();
amir.addMenuItem(ApplicationMenuItemRepository.MENUITEM_SYSTEM, this);
RuntimeStore.getRuntimeStore().put(MY_MENU_ID, this);
}
}
public Object run(Object context) {
jingu.setDefaultFont(Font.getDefault());
jingu.setMainApp(false);
jingu.setBbmEditField(null);
jingu.showMainScreen();
return context;
}
public String toString() {
return "My Menu";
}
}
plz advice where I should delete ApplicationMenuItem in my app?
my regards,
Vadim
If you are registering an ApplicationMenuItem from your application, as a user I would consider it bad style for your application to remove and exit, even if RIM provided a way to do this. You may want to separate your application into two parts. One provides the minimal support for responding to the ApplicationMenuItem selection, that starts automatically and runs in the background. The other has all the rest and can run and exit as needed.
My solution for this situation is:
create alternative entry point and run it on app load
register menu in it
do not use runtimeStore

Create an application which will lock another application event

Actually I want to make an application which will getGlobalEvent and control that event through another custom application. Is there any way to do so. Can i get global event from a particular application? Its like an application which will lock custom application in your blackberry, if you add following application in that locking app list and put password to access then when u try to open that application, it will ask for a password which u set in the locking app.
Common advices
this should be background application
in timer thread check current foreground application
use custom global modal dialog to request password
if password was wrong close app by simulating back key press or move app to background
Checking Application
Have to say, there can be several processes within one application so we will perform check based on module name:
private String getModuleNameByProcessId(int id) {
String result = null;
ApplicationManager appMan = ApplicationManager.getApplicationManager();
ApplicationDescriptor appDes[] = appMan.getVisibleApplications();
for (int i = 0; i < appDes.length; i++) {
if (appMan.getProcessId(appDes[i]) == id) {
result = appDes[i].getModuleName();
break;
}
}
return result;
}
Move application to Background?
Yep, there's no requestBackground() in ApplicationManager... so what you can do is requestForeground() on the next best app which is not on foreground, and this will move active app to background! You can even bring up Home Screen with requestForegroundForConsole():
protected int switchForegroundModule() {
int id = -1;
ApplicationManager appMan = ApplicationManager.getApplicationManager();
ApplicationDescriptor appDes[] = appMan.getVisibleApplications();
for (int i = 0; i < appDes.length; i++) {
if (!appDes[i].getModuleName().equalsIgnoreCase(STR_MODULE_NAME)) {
id = appMan.getProcessId(appDes[i]);
appMan.requestForeground(id);
// give a time to foreground application
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
break;
}
}
return id;
}
Global Dialog
Just to input password you can extend Dialog, it will be easier to consume result:
class PaswordDialog extends Dialog {
private BasicEditField mPwdField = new BasicEditField();
public PaswordDialog() {
super(Dialog.D_OK_CANCEL, "Enter password", Dialog.CANCEL, null,
Dialog.FIELD_HCENTER);
add(mPwdField);
}
public String getPassword() {
return mPwdField.getText();
}
}
And password check will look like:
private boolean checkPassword() {
boolean result = false;
final PaswordDialog pwdDlg = new PaswordDialog();
invokeAndWait(new Runnable() {
public void run() {
Ui.getUiEngine().pushGlobalScreen(pwdDlg, 0,
UiEngine.GLOBAL_MODAL);
}
});
result = ((Dialog.OK == pwdDlg.getSelectedValue()) && pwdDlg
.getPassword().equalsIgnoreCase(STR_PASSWORD));
return result;
}
Put this all together
Sample to block Adress Book App:
public class LockMainApp extends Application {
private static final String STR_MODULE_NAME = "net_rim_bb_addressbook_app";
private static final String STR_PASSWORD = "12345";
int mFGProcessId = -1;
public LockMainApp() {
Timer timer = new Timer();
timer.schedule(mCheckForeground, 1000, 1000);
}
public static void main(String[] args) {
LockMainApp app = new LockMainApp();
app.enterEventDispatcher();
}
TimerTask mCheckForeground = new TimerTask() {
public void run() {
int id = ApplicationManager
.getApplicationManager().getForegroundProcessId();
if (id != mFGProcessId) {
mFGProcessId= id;
String moduleName = getModuleNameByProcessId(mFGProcessId);
if (moduleName.equalsIgnoreCase(STR_MODULE_NAME)) {
if (!checkPassword())
mFGProcessId = switchForegroundModule();
}
}
};
};
}

Resources