2012-05-16 55 views
1

我尝试了很多,现在我需要你的帮助。我想要做的是以下几点: 当黑莓应用程序启动yes/no对话框时弹出。 如果用户选择“是”,则执行一些操作并在启动后继续。如果用户选择“否”退出应用程序。Blackberry - 启动时显示对话框,并等到对话框关闭

我写了一个SSCCE,如果选择“是”,那么应该振动,之后你应该听到声音。当然我知道,在调用Alert.vibrate()后代码会继续运行,并且不会等待振动完成。无论如何,这只是一个例子。在声音播放之前,应该首先调用vibrate(),并且应该完全处理dialogClosed()。

SSCCE是我到目前为止。我尝试了很多其他的东西。我相信它不会那么困难。我只是不明白。

这就是:

package TestDialog; 

import net.rim.device.api.system.Alert; 
import net.rim.device.api.system.Bitmap; 
import net.rim.device.api.ui.UiApplication; 
import net.rim.device.api.ui.component.Dialog; 
import net.rim.device.api.ui.component.DialogClosedListener; 

public class TestDialog extends UiApplication 
{ 

public static short[] SOUND_ALERT = { 523, 200, //C for 200ms 
       0, 200, //Pause 200ms 
       554, 200, //C# 200ms 
       0, 200, //Pause 200ms 
       587, 200, //D 200ms 
       0, 200, //Pause 200ms 
       622, 200   //D# 200ms   
            }; 

/** 
* @param args 
*/ 
public static void main(final String[] args) 
{ 

    final TestDialog test = new TestDialog(); 
    test.enterEventDispatcher(); 

} 

public TestDialog() 
{ 

    //the dialog 
    final Dialog d = new Dialog(Dialog.D_YES_NO, "vibrate?", Dialog.OK, Bitmap.getPredefinedBitmap(Bitmap.QUESTION), Dialog.FIELD_TOP); 
    d.setDialogClosedListener(new DialogClosedListener() 
    { 

     public void dialogClosed(final Dialog dialog, final int choice) 
     { 
      if (d.getSelectedValue() == Dialog.YES) 
      { 
       Alert.startVibrate(2000); 
       //do something which takes some time 
      } 
      else 
      { 
       System.exit(0); 
      } 

     } 
    }); 

    //show the dialog 
    showDialog(d); 

    //now wait for the dialog to call notify 
    try 
    { 
     synchronized (this) 
     { 
      this.wait(); 
     } 
    } 
    catch (final Exception e) 
    { 
     System.out.println(e.getMessage()); 
    } 

    //finally AFTER the dialog has been closed and everything in dialogClosed() has been done, play a sound 
    Alert.startAudio(SOUND_ALERT, 100); 

} 

private void showDialog(final Dialog d) 
{ 

    UiApplication.getUiApplication().invokeLater(new Runnable() 
    { 
     public void run() 
     { 
      d.doModal(); 
      this.notify(); 
     } 
    }); 

} 
} 

OK,其他一些SSCCE。这将启动并显示一个对话框,但随后抛出IllegalMonitorExcpetion:

package TestDialog; 

import net.rim.device.api.system.Bitmap; 
import net.rim.device.api.ui.UiApplication; 
import net.rim.device.api.ui.component.Dialog; 

public class TestDialog extends UiApplication 
{ 

public static short[] SOUND_ALERT = { 523, 200, //C for 200ms 
       0, 200, //Pause 200ms 
       554, 200, //C# 200ms 
       0, 200, //Pause 200ms 
       587, 200, //D 200ms 
       0, 200, //Pause 200ms 
       622, 200   //D# 200ms   
            }; 

/** 
* @param args 
*/ 
public static void main(final String[] args) 
{ 

    final TestDialog test = new TestDialog(); 
    test.enterEventDispatcher(); 

} 

public TestDialog() 
{ 

    UiApplication.getUiApplication().invokeLater(new Runnable() 
    { 
     public void run() 
     { 
      //the dialog 
      final Dialog d = new Dialog(Dialog.D_YES_NO, "vibrate?", Dialog.OK, Bitmap.getPredefinedBitmap(Bitmap.QUESTION), Dialog.FIELD_TOP); 

      if (d.doModal() == Dialog.YES) 
      { 
       System.out.println("selection made yes"); 
       this.notify(); 
      } 
      else 
      { 
       System.out.println("selection made no"); 
       System.exit(0); 
      } 

     } 
    }); 


     try 
     { 
      this.wait(); 
     } 
     catch (final Exception e) 
     { 
      e.printStackTrace(); 
     } 


    //finally AFTER the dialog has been closed and everything in dialogClosed() has been done, play a sound 
    System.out.println("done"); 
} 

} 

所以我把一个synchronized块周围的wait()调用,因为我读,该对象必须调用wait()时进行同步。但现在应用程序什么也没有显示它运行主要方法,但某处停止。在模拟器中会发生很奇怪的事情:当模拟器仍然处于启动状态并且在显示器上写入“调试器附加”时,会调用该应用程序的主要方法。那么,这里是带有同步块的SSCCE。仍然不起作用。

package TestDialog; 

import net.rim.device.api.system.Bitmap; 
import net.rim.device.api.ui.UiApplication; 
import net.rim.device.api.ui.component.Dialog; 

public class TestDialog extends UiApplication 
{ 

public static short[] SOUND_ALERT = { 523, 200, //C for 200ms 
       0, 200, //Pause 200ms 
       554, 200, //C# 200ms 
       0, 200, //Pause 200ms 
       587, 200, //D 200ms 
       0, 200, //Pause 200ms 
       622, 200   //D# 200ms   
            }; 

/** 
* @param args 
*/ 
public static void main(final String[] args) 
{ 

    final TestDialog test = new TestDialog(); 
    test.enterEventDispatcher(); 

} 

public TestDialog() 
{ 

    UiApplication.getUiApplication().invokeLater(new Runnable() 
    { 
     public void run() 
     { 
      //the dialog 
      final Dialog d = new Dialog(Dialog.D_YES_NO, "vibrate?", Dialog.OK, Bitmap.getPredefinedBitmap(Bitmap.QUESTION), Dialog.FIELD_TOP); 

      if (d.doModal() == Dialog.YES) 
      { 
       System.out.println("selection made yes"); 
       this.notify(); 
      } 
      else 
      { 
       System.out.println("selection made no"); 
       System.exit(0); 
      } 

     } 
    }); 

    synchronized (this) 
    { 
     try 
     { 
      this.wait(); 
     } 
     catch (final Exception e) 
     { 
      e.printStackTrace(); 
     } 
    } 

    //finally AFTER the dialog has been closed and everything in dialogClosed() has been done, play a sound 
    System.out.println("done"); 
} 

} 

最后我试着利用忙碌的等待。仍然没有成功。对话框不会弹出。即使在主线程的while循环中使用Thread.sleep(1000),UI线程似乎也不起作用。这里是繁忙的等待的SSCCE:

package TestDialog; 

import net.rim.device.api.system.Bitmap; 
import net.rim.device.api.ui.UiApplication; 
import net.rim.device.api.ui.component.Dialog; 

public class TestDialog extends UiApplication 
{ 
    /** 
    * @param args 
    */ 
    public static void main(final String[] args) 
    { 

     final TestDialog test = new TestDialog(); 
     test.enterEventDispatcher(); 

    } 

    private volatile boolean _blocked = true; 

    public TestDialog() 
    { 

     UiApplication.getUiApplication().invokeLater(new Runnable() 
     { 
      public void run() 
      { 
       //the dialog 
       final Dialog d = new Dialog(Dialog.D_YES_NO, "vibrate?", Dialog.OK, Bitmap.getPredefinedBitmap(Bitmap.QUESTION), Dialog.FIELD_TOP); 

       if (d.doModal() == Dialog.YES) 
       { 
        System.out.println("selection made yes"); 
        _blocked = false; 
       } 
       else 
       { 
        System.out.println("selection made no"); 
        System.exit(0); 
       } 

      } 
     }); 

     while (_blocked) 
     { 
      try 
      { 
       Thread.sleep(1000); 
      } 
      catch (final Exception e) 
      { 
       //safety catch 
      } 
     } 
     finish(); 

    } 

    private void finish() 
    { 
     System.out.println("done"); 
    } 

} 

感谢您的帮助。

Haferblues

+0

供参考。我在这里的BB论坛也问过这个问题:http://supportforums.blackberry.com/t5/Java-Development/Startup-YES-NO-Dialog-should-stop-the-launchign-process-of-the/td -p/1725071我将尽快为这两个论坛提供解决方案。我希望这是好的,因为我真的需要帮助。 – haferblues

回答

1

HI我终于在黑莓论坛在这里的答案:http://supportforums.blackberry.com/t5/Java-Development/Startup-YES-NO-Dialog-should-stop-the-launchign-process-of-the/m-p/1725085

最终的解决方案,这对我的作品(而且看上去更漂亮,然后我在上面所做的一切)如下:

package TestDialog; 

import net.rim.device.api.ui.UiApplication; 
import net.rim.device.api.ui.component.Dialog; 
import net.rim.device.api.ui.component.LabelField; 
import net.rim.device.api.ui.component.RichTextField; 
import net.rim.device.api.ui.container.MainScreen; 

public class TestDialog extends UiApplication implements Runnable 
{ 
    /** 
    * @param args 
    */ 
    public static void main(final String[] args) 
    { 

     final TestDialog test = new TestDialog(); 
     test.invokeLater(test); 

     test.enterEventDispatcher(); 

    } 

    public TestDialog() 
    { 

    } 

    public void run() 
    { 

     final int answer = Dialog.ask(Dialog.D_YES_NO, "continue?"); 
     //  pushGlobalScreen(new Dialog(Dialog.D_YES_NO, "continue?", 0, null, Dialog.GLOBAL_STATUS), 1, TestDialog.GLOBAL_QUEUE | TestDialog.GLOBAL_MODAL); 

     if (answer == Dialog.YES) 
     { 
      System.out.println("user clicked yes"); 
     } 
     else 
     { 
      System.exit(0); 
     } 

     pushScreen(new MyScreen("App loaded")); 
    } 

    class MyScreen extends MainScreen 
    { 

     public MyScreen(final String msg) 
     { 

      final LabelField title = new LabelField("First Screen", LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH); 
      setTitle(title); 
      this.add(new RichTextField(msg)); 

     } 

    } 

} 

感谢双方的大力支持。

1

使用invokeAndWait,而不是invokeLater的。

private void showDialog(final Dialog d) 
{ 

    UiApplication.getUiApplication().invokeAndWait(new Runnable() 
    { 
     public void run() 
     { 
      d.doModal(); 
      this.notify(); 
     } 
    }); 

} 
+0

这不起作用。任何其他想法? – haferblues

相关问题