views:

77

answers:

1

I've been reading the android documentation on reflection, but i'm just not really grasping how to actually use it. Is it multiple class files i'll have to create? Is it breaking it up to certain parts all in the same class file? I want to understand it, I really do, but I just don't get it.

Anyway, I have this simple webview code that wants to use the new geolocation code from SDK7 but it makes 1.5 and 1.6 phones crash. I really want to be able to make this java class work (as in at least loading the html) even if the geolocation won't work prior to sdk7. I've put comments around all the code the has a red line under it in eclipse when the SDK is under 7. Would someone mind showing me with my code how exactly to use reflection? I'd really appreciate it. I've read the bogs and documents and everything i try after reading them doesn't work.

    package com.my.app;

    import com.facebook.android.R;
    //NEEDS TO BE IGNORED**********************************************************
    import android.webkit.GeolocationPermissions;
    import android.webkit.GeolocationPermissions.Callback;
    //END**************************************************************************
    import android.app.Activity;
    import android.app.ProgressDialog;
    import android.content.Intent;
    import android.net.Uri;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.KeyEvent; 
    import android.view.Menu;
    import android.view.MenuInflater;
    import android.view.MenuItem;
    import android.webkit.CookieSyncManager;
    import android.webkit.WebChromeClient;
    import android.webkit.WebView;
    import android.webkit.WebViewClient;
    import android.widget.Toast;

    //GeolocationPermissionsCallback NEEDS TO BE IGNORED**********************************************************
    public class Places extends Activity implements GeolocationPermissions.Callback{ 
            private ProgressDialog progressBar;
            public WebView webview;
            private static final String TAG = "Main";
            String geoWebsiteURL = "http://google.com";

            @Override 
             public void onStart()
            {
               super.onStart();
                CookieSyncManager.getInstance().sync();

            }




        public void onCreate(Bundle savedInstanceState) { 
            super.onCreate(savedInstanceState); 
            setContentView(R.layout.main);
            CookieSyncManager.createInstance(this);
            CookieSyncManager.getInstance().startSync();

            webview = (WebView) findViewById(R.id.webview);
            webview.setWebViewClient(new testClient());
            webview.getSettings().setJavaScriptEnabled(true);
            webview.getSettings().setPluginsEnabled(true);
            webview.loadUrl("http://google.com");

            progressBar = ProgressDialog.show(Places.this, "", "Loading Page...");

            //START GROUP OF CODE THAT NEEDS TO BE IGNORED************************************************************
            webview.getSettings().setGeolocationEnabled(true);



            GeoClient geo = new GeoClient();
            webview.setWebChromeClient(geo);        

        }

        public void invoke(String origin, boolean allow, boolean remember) {

        }

        final class GeoClient extends WebChromeClient {


        @Override
        public void onGeolocationPermissionsShowPrompt(String origin,
        Callback callback) {
        super.onGeolocationPermissionsShowPrompt(origin, callback);
        callback.invoke(origin, true, false);
        }
    //END OF CODE THAT NEEDS TO BE IGNORED************************************************


}


        private class testClient extends WebViewClient { 
            @Override 
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                Log.i(TAG, "Processing webview url click...");
                view.loadUrl(url);
                return true;  



            }





            public void onPageFinished(WebView view, String url) {
                Log.i(TAG, "Finished loading URL: " +url);
                if (progressBar.isShowing()) {
                    progressBar.dismiss();
                }

                if (url.startsWith("mailto:") || url.startsWith("geo:") ||
                        url.startsWith("tel:")) {
                                                    Intent intent = new Intent
                        (Intent.ACTION_VIEW, Uri.parse(url));
                                                    startActivity(intent);
                        }
            }
        }



            public boolean onKeyDown(int keyCode, KeyEvent event) { 
                if ((keyCode == KeyEvent.KEYCODE_BACK) && webview.canGoBack()) { 
                    webview.goBack(); 
                    return true; 
                }
                    if (keyCode == KeyEvent.KEYCODE_SEARCH) {

                        Intent z = new Intent(this, Search.class);
                        startActivity(z);

                      }  
                return super.onKeyDown(keyCode, event);  
                }




            public boolean onCreateOptionsMenu (Menu menu) {
                super.onCreateOptionsMenu(menu);
                MenuInflater inflater = getMenuInflater();
                inflater.inflate(R.menu.menu, menu);
                return true;
            }

        @Override
        public boolean onOptionsItemSelected (MenuItem item) {
                switch (item.getItemId()) {
                case R.id.home:
                    Intent m = new Intent(this, Home.class);
                    startActivity(m);
                    return true;

                case R.id.refresh:
                    webview.reload();
                    Toast.makeText(this, "Refreshing...", Toast.LENGTH_SHORT).show();
                    return true;


        }
        return false;
            }

        public void onStop()
        {
           super.onStop();
    CookieSyncManager.getInstance().sync();

        }




    }
+1  A: 

Refactor your 7 code into a separate class and have no reference to this new class in your existing code.

You then need a way to determine if the facility you need is present. It looks to me that you can use "is android.webkit.GeolocationPermissions present" which is the easiest as you can use Class.forName("android.webkit.GeolocationPermissions"), and then use reflection to first load the separate class you wrote above and then invoke the method you want to run in your class. This will ensure that your code does not hint to the JVM that your separate class even exists until you determine at runtime that you will need it.

See http://www.exampledepot.com/egs/java.lang.reflect/Methods.html for examples of how to invoke a given method in a given class using reflection.

Thorbjørn Ravn Andersen