0

任何人都可以为黑莓中的BrowserField实现一个进度跟踪器栏,我正在为此付出努力。我想告诉用户,当他在我的应用程序中打开浏览器字段时,确实发生了一些情况。黑莓BrowserField中的浏览器进度跟踪器

我已经检查过BrowserFieldProgressBar演示,但它只适用于OS 6,因为它是用于BrowserField2的。进度条或带有gif的对话框都可以工作。我试图实现以下,但PopUpScreen不会显示在浏览器领域,一旦我离开browserfield它卡住:

public class BrowserPopUpScreen extends MainScreen{ 

    private GridFieldManager _manager; 
    private BrowserField _browserField; // Campo de la interfaz que se utiliza para mostrar una página web 


    private final String GRAPH_URL = "https://graph.facebook.com"; // URL de Graph API de Facebook. 
    private final String NEXT_URL = "http://www.facebook.com/connect/login_success.html"; // URL adonde se redirige al usuario cuando la operacion es exitosa. 
    private final String APPLICATION_KEY = "e1812f3b71678c8e0017831cc4cbc87a"; // Llave de la aplicación en Facebook. 
    private final String APPLICATION_SECRET = ""; // Secreto de la aplicacion en Facebook. 
    private final String APPLICATION_ID = ""; // ID de la aplicacion en Facebook. 

    public static final int FACEBOOK_SIGNUP = 1; // Constante que indica que el usuario desea registrarse con Facebook 
    public static final int FACEBOOK_LINK = 2; // Constante que indica que el usuario desea conectar su cuenta de Facebook a la cuenta de Social Voice 

    /** 
    * Construye la pantalla de browser. 
    * 
    * Dependiendo te la acción que recibe en caso de ser FACEBOOK_SIGNUP 
    * peticiona en envió de información de usuario a Facebook, en caso contrario 
    * solo pide un token de acceso para el usuario. 
    * 
    * @param manager 
    *   Administrador de contenido que utilizará la pantalla 
    * @param action 
    *   Acción que se realizará, en caso de ser registro la 
    *   acción será FACEBOOK_SIGNUP, en caso de solo conectar 
    *   Fonyk con Facebook será FACEBOOK_LINK 
    */ 
    public BrowserPopUpScreen(GridFieldManager manager, final int action) 
    { 
     _manager = manager; 

     _browserField = new BrowserField(); 

     // Se crea el URL de la petición y se hace el llamado a dicho URL 
     _browserField.requestContent(new StringBuffer().append("https://graph.facebook.com/oauth/authorize?client_id=").append(APPLICATION_ID).append("&").append("redirect_uri=").append(NEXT_URL).append("&").append("scope=offline_access,publish_stream,email").append("&display=wap").toString()); 

     final LoadingScreen loadingScreen = new LoadingScreen(); 
     //Este metodo detecta cuando se realiza un cambio en el BrowserField 
     BrowserFieldListener browserListener = new BrowserFieldListener() { 

      public void documentLoaded(BrowserField browserField, Document document) throws Exception 
      { 
       loadingScreen.onClose(); 
       //Se verifica si es nuestro URL de redirección 
       if(_browserField.getDocumentUrl().startsWith(NEXT_URL)) 
       { 

        String url = _browserField.getDocumentUrl(); 
        String code = getElement(url, "code"); 

        //Si la petición fue exitosa al URL se le agrega un campo code 
        //revisamos si este no es uno para continuar con la operacion 
        if(!code.equals("")) 
        { 

         //Creamos un cliente http para hacer un GET y obtener el token 
         //de acceso 
         HttpClient httpClient = new HttpClient(MainApp.connFactory); 

         //Se crea un hashtable que va a contener la información de nuestra aplicación 
         //y el código proporcionado previamente 
         Hashtable data = new Hashtable(); 

         data.put("client_id", APPLICATION_ID); 
         data.put("redirect_uri", NEXT_URL); 
         data.put("client_secret", APPLICATION_SECRET); 
         data.put("code", code); 

         StringBuffer response = httpClient.doGet(GRAPH_URL.concat("/oauth/access_token"), data); 


         if(response.length() == 0) 
          throw new Exception(); 

         //Se obtiene el token de acceso de la respuesta y se asigna a nuestro 
         //objeto usuario 
         String accessToken = getElement(response.toString(), "access_token"); 

         MainApp.user.setFacebookAccessToken(accessToken); 
         MainApp.user.setFacebookAccess(true); 

         //Si la acción a realizar es de registro, se utiliza el token de acceso 
         //para peticionar los datos del usuario a FB 
         if(action == FACEBOOK_SIGNUP) 
         { 
          data.clear(); 
          data.put("access_token", accessToken); 

          response = null; 

          response = httpClient.doGet(GRAPH_URL.concat("/me"), data); 

          JSONObject jsonResponse = new JSONObject(response.toString()); 

          // Al obtener una respuesta se establecen los valores en el objeto definido 
          // inicialmente en la aplicacion 
          MainApp.facebookUserInfo.setFirstName(jsonResponse.optString("first_name")); 
          MainApp.facebookUserInfo.setLastBame(jsonResponse.optString("last_name")); 
          MainApp.facebookUserInfo.setEmail(jsonResponse.optString("email")); 
//       MainApp.facebookUserInfo.set_birthday(jsonResponse.optString("birthday")); 
          MainApp.facebookUserInfo.setGender(jsonResponse.optString("gender")); 
          MainApp.facebookUserInfo.setMiddleName(jsonResponse.optString("middle_name")); 
          MainApp.facebookUserInfo.setLink(jsonResponse.optString("link")); 
         } 

         //Se invoca a la aplicación para cerrar esta pantalla después de 
         //completarse la operación 
         UiApplication.getUiApplication().invokeLater(new Runnable() { 

          public void run() { 
           UiApplication.getUiApplication().getActiveScreen().close(); 

          } 
         }); 
        } 
       } 
      } 
     }; 
     _browserField.addListener(browserListener); 
     add(_browserField); 
     UiApplication.getUiApplication().pushScreen(loadingScreen); 
    } 

    private class LoadingScreen extends PopupScreen{ 
     private AnimatedGIFField _loader; 
     public LoadingScreen(){ 
      super(new VerticalFieldManager()); 
      GIFEncodedImage ourAnimation = (GIFEncodedImage) GIFEncodedImage.getEncodedImageResource("ajax-loader (7).gif"); 
      _loader = new AnimatedGIFField(ourAnimation, Field.FIELD_HCENTER); 
      this.add(_loader); 
     } 

     public boolean onClose() { 
      setDirty(false); 
      return super.onClose(); 
     } 
    } 


    /** 
    * Extra un valor especificado del URL 
    * 
    * @param url 
       URL del cuál se va a extraer un valor 
    * @param element 
       Elemento que se desea obtener 
    * @return 
    */ 
    private String getElement(String url, String element) 
    { 
     int startIndex = url.indexOf(element); 

     if (startIndex > -1) { 
      int stopIndex = url.length(); 

      if (url.indexOf('&', startIndex) > -1) { 
       stopIndex = url.indexOf('&', startIndex); 
      } else if (url.indexOf(';', startIndex) > -1) { 
       stopIndex = url.indexOf(';', startIndex); 
      } 

      element = url.substring(url.indexOf('=', startIndex) + 1, stopIndex); 


      return element; 
     } 

     return ""; 
    } 
} 

回答

1

一览4件事情看起来很奇怪对我说:

1) 。在请求内容之后,您就是设置监听器(因此可能发生页面可以在监听器作出反应之前加载)。 2)。 loadingScreen.onClose(); - 你期望这会做什么? 3)。 UiApplication.getUiApplication().getActiveScreen().close(); - 你确定你正在关闭哪个屏幕?看起来你是一个不可救药的乐观主义者。 4)。我从来没有使用过BrowserFieldListener,所以这一点只是一个猜测:BrowserFieldListener还有其他回调,包括失败的回调。那么,如果BrowserField.requestContent(String url)失败(可能有十几个潜在的原因) - 最终是否会调用您使用的回调?

UPDATE

我想这个问题是你在做什么,在UI线程发生顺序。所以你推进一个进度屏幕,做一些有用的事情,然后关闭进度 - 所有这些都是在UI线程上依次进行的。在这种情况下,您不会给UI框架实际显示/绘制进度屏幕的机会。要绘制一个屏幕,UI线程需要一些免费的CPU时间。当UI线程进入可以开始绘制进度屏幕的位置时,它发现不需要执行,因为进度屏幕已关闭。

一个简单的(并且很脏的)解决方法是在您按下进度屏幕后立即调用UiApplication.repaint()。此方法执行以下操作:

重新整体显示。

调用此方法重新绘制整个显示屏的 。它无效,然后 然后油漆, 显示堆栈上的每个屏幕。

+0

1)在调用之前或之后设置BrowserFieldListener并不重要,它在这种情况下的工作方式是相同的,它不同于在所述事件之后为按钮事件设置侦听器,但我猜它看起来很奇怪。 2)我是一个白痴错误的方法,它应该是关闭()。 3)是的,我相信它是那个正在关闭的屏幕,经过2个月的彻底测试,我没有问题,未来我试图修改我的屏幕管理,因为我知道我现在做它不是最佳的。 4)不,它不会,所以我不会得到错误的成功。但是,我应该检查失败 – 8vius 2011-04-07 05:08:16

+0

我的主要问题是LoadingScreen不显示在BrowserField的顶部,我不知道我在做什么错。并且赦免你看到的任何东西都是错误的,我对黑莓开发相对陌生,所以我还没有完全理解所有的怪癖。 – 8vius 2011-04-07 05:13:53

+0

@ 8vius:请参阅UPDATE部分。 – 2011-04-07 07:12:55