Search code examples
javaandroidreflectionremoteview

Determine if a Method is a `RemotableViewMethod`


I am building a Widget which contains a ProgressBar. If the Widget is computing I set the visibility of that ProgressBar to VISIBLE, and to INVISIBILE if all computings stopped. There should be no Problem, because the setVisibility is documented as RemotableViewMethod. However some guys at HTC seem to forget it, (i.e on the Wildfire S), so a call to RemoteViews.setVisibility will result in a crash. For this reason I try to implement a check, if setVisibility is really callable. I have writen this Method for it:

private boolean canShowProgress(){
        LogCat.d(TAG, "canShowProgress");
        Class<ProgressBar> barclz = ProgressBar.class;
        try {
            Method method = barclz.getMethod("setVisibility", new Class[]{int.class});
            Annotation[] anot = method.getDeclaredAnnotations();
            return anot.length > 0;
        } catch (SecurityException e) {
            LogCat.stackTrace(TAG, e);
        } catch (NoSuchMethodException e) {
            LogCat.stackTrace(TAG, e);
        }
        return false;
    }

This will work, but is REALLY ugly as it will return `True´ if ANY Annotiation is present. I looked, how RemoteView itself is doing the lookup and found this:

if (!method.isAnnotationPresent(RemotableViewMethod.class)) {
                throw new ActionException("view: " + klass.getName()
                        + " can't use method with RemoteViews: "
                        + this.methodName + "(" + param.getName() + ")");
            }

But i could't do the same, because the Class RemotableViewMethod is not accsesible through the sdk. How to know if it is accesible or not?


Solution

  • By Writing my question I had the Idea to lookup for the class by its Name, and it worked. So I updated my Method to the following:

    private boolean canShowProgress(){
            LogCat.d(TAG, "canShowProgress");
            Class<ProgressBar> barclz = ProgressBar.class;
            try {
                Method method = barclz.getMethod("setVisibility", new Class[]{int.class});
                Class c = null;
                try {
                    c = Class.forName("android.view.RemotableViewMethod");
                } catch (ClassNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                return (this.showProgress= (c != null && method.isAnnotationPresent(c)));
    
    
            } catch (SecurityException e) {
                LogCat.stackTrace(TAG, e);
            } catch (NoSuchMethodException e) {
                LogCat.stackTrace(TAG, e);
    
            }
            return false;
        }
    

    which works flawlessly