在 Android 中使用反射来实现向后兼容性

发布于 2024-09-16 23:09:39 字数 5269 浏览 12 评论 0原文

我在 Android 开发网站上阅读了有关使用反射的内容。但我实在不明白如何使用它。我需要这个 Java 文件在 1.5 (SDK3) 设备上运行,但只需忽略新代码,它就可以在 2.0 (SDK5) 或更高版本的手机上正常工作。我有这个活动(发布在下面),它是一个简单的网络视图。但是,我希望启用地理定位(即使仅适用于 2.0 及更高版本的手机),因为这些 API 直到 SDK 5 才引入,并且我希望 webview 至少能够加载在 1.5 手机上,而不仅仅是崩溃。如何获取我的代码并使用反射进行设置?

    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);
            }
        }
    }

        //What's here????

        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();
        }
    }

I was reading over at the Android development website about using reflections. But I'm really not grasping how to use it. I need this Java file to run on a 1.5 (SDK3) device but just ignore the new code and it works fine on a 2.0 (SDK5) or later phone. I have this Activity (posted below) and it's a simple webview. However, I want to have geolocation enabled (even if it is only for 2.0 and later phones), since these APIs weren't introduced until SDK 5, and I would like the webview to be able to, at the very least, to load on a 1.5 phone rather than just crashing. How do I take my code and set it up using reflections?

    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);
            }
        }
    }

        //What's here????

        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();
        }
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

昔日梦未散 2024-09-23 23:09:39

步骤#1:不要在 Activity 上实现 GeolocationPermissions.Callback。使用一些其他对象作为 GeolocationPermissions.Callback,该对象是在公共 Java 类中实现的,如果您在旧版本的操作系统上运行,则不会加载该对象。

步骤#2:阅读 您之前提出的问题,其中涵盖了您需要了解的其余内容。值得注意的是,您可以将 GeoClient 设为其自己文件中的公共 Java 类,这样就可以避免在旧版本的操作系统上加载它。就我个人而言,我喜欢 Stephen C 的答案,我在 这里演示了它的用法

Step #1: Do not implement GeolocationPermissions.Callback on the activity. Use some other object for GeolocationPermissions.Callback, one implemented in a public Java class that you would not load if you are running on older versions of the OS.

Step #2: Read the answers and comments on the question you asked previously, which covers what you need to know for the rest. Notably, you would make GeoClient be a public Java class in its own file, so you can avoid loading it on older versions of the OS. Personally, I like the Stephen C answer, and I demonstrate its use here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文