如何获取最近访问过的URL浏览器的屏幕截图,例如chrome

时间:2015-03-03 07:51:45

标签: android browser browser-history

我想在浏览器中显示最近访问过的网址的屏幕截图,例如google chrome。 enter image description here

我能够获得相同的网址,标题和图标,但也希望显示最近访问过的网站的截图。请引导我完成此操作。

1 个答案:

答案 0 :(得分:1)

与大多数其他视图一样,WebView可以将自己绘制到提供的Canvas上。页面加载后,我们可以使用此方法创建呈现页面的屏幕截图,并将其与网站的标题和图标一起添加到GridView。以下示例相当通用,因为我确定您要自定义它。

我已将此功能包装在Fragment中,而Fragment只需要对WebView的引用。在我的简单演示应用程序中,我在WebView的WebViewClient的addCurrentSite()回调中调用了Fragment的onPageFinished()方法,为每个访问过的新URL创建了一个屏幕截图。 Fragment类还提供了一个回调接口,Activity可以实现该回调接口来响应屏幕截图的点击。此外,长按屏幕截图会将其从列表中删除。

首先,WebShotFragment类:

public class WebShotFragment extends Fragment {
    private WebView webView;
    private GridView grid;
    private SiteMap<String, Site> sites = new SiteMap<String, Site>();
    private SiteAdapter adapter;

    public WebShotFragment() {}

    public interface OnSiteSelectedListener {
        public void onSiteSelected(String url);
    }

    private OnSiteSelectedListener listener;
    public void setOnSiteSelectedListener(OnSiteSelectedListener listener) {
        this.listener = listener;
    }

    public void registerWebView(WebView webView) {
        this.webView = webView;
    }

    public void addCurrentSite() {
        if (!sites.containsKey(webView.getUrl())) {
            webView.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        Bitmap bmp = getWebshot();
                        sites.put(webView.getUrl(), new Site(webView.getTitle(), webView.getUrl(), webView.getFavicon(), bmp));
                        adapter.notifyDataSetChanged();
                    }
                }, 1000);
        }
    }

    private Bitmap getWebshot() {
        Bitmap bmp = Bitmap.createBitmap(webView.getWidth(), webView.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bmp);
        webView.draw(canvas);
        Bitmap res = Bitmap.createBitmap(200, 150, Bitmap.Config.ARGB_8888);
        canvas = new Canvas(res);
        canvas.drawBitmap(bmp,
                          new Rect(0, 0, bmp.getWidth(), bmp.getHeight()),
                          new Rect(0, 0, res.getWidth(), res.getHeight()),
                          new Paint());

        return res;
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        adapter = new SiteAdapter(activity, sites);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        grid = (GridView) inflater.inflate(R.layout.fragment_webshot, container, false);
        grid.setAdapter(adapter);
        grid.setOnItemClickListener(new OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    if (listener != null)
                        listener.onSiteSelected(sites.getValue(position).url);
                }
            });
        grid.setOnItemLongClickListener(new OnItemLongClickListener() {
                @Override
                public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
                    sites.remove(sites.getEntry(position).getKey());
                    adapter.notifyDataSetChanged();
                    return true;
                }
            });
        return grid;
    }   

    private class SiteAdapter extends BaseAdapter {
        private LayoutInflater inflater;
        private SiteMap<String, Site> sites;

        public SiteAdapter(Context context, SiteMap<String, Site> sites) {
            this.inflater = LayoutInflater.from(context);
            this.sites = sites;
        }

        @Override
        public int getCount() {
            return sites.size();
        }

        @Override
        public Object getItem(int position) {
            return sites.getValue(position);
        }

        @Override
        public long getItemId(int position) {
            return 0;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View v = inflater.inflate(R.layout.webshot, null);

            Site s = (Site) getItem(position);
            ((ImageView) v.findViewById(R.id.icon)).setImageBitmap(s.icon);
            ((TextView) v.findViewById(R.id.title)).setText(s.title);
            ((ImageView) v.findViewById(R.id.shot)).setImageBitmap(s.webshot);

            return v;
        }
    }

    private class Site {
        public String title, url;
        public Bitmap icon, webshot;

        public Site(String title, String url, Bitmap icon, Bitmap webshot) {
            this.title = title;
            this.url = url;
            this.icon = icon;
            this.webshot = webshot;
        }
    }

    private class SiteMap<K, V> extends LinkedHashMap<K, V> {
        public V getValue(int i) {
            Map.Entry<K, V> entry = this.getEntry(i);

            if (entry == null)
                return null;

            return entry.getValue();
        }

        public Map.Entry<K, V> getEntry(int i) {
            if (i < 0)
                throw new IllegalArgumentException("Index cannot be negative");

            Set<Map.Entry<K,V>> entries = entrySet();

            int j = 0;
            for (Map.Entry<K, V> entry : entries)
                if (j++ == i)
                    return entry;

            return null;
        }
    }
}

此类使用两个布局文件。这里,GridView的fragment_webshot.xml

<GridView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff"
    android:padding="10dp"
    android:numColumns="auto_fit"
    android:stretchMode="columnWidth"
    android:verticalSpacing="10dp"
    android:horizontalSpacing="10dp" />

webshot.xml项目:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#eeeeee"
    android:padding="5dp"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="30dp"
        android:gravity="center_vertical">

        <ImageView android:id="@+id/icon"
            android:layout_width="24dp"
            android:layout_height="24dp"
            android:scaleType="fitXY" />

        <Space
            android:layout_width="10dp"
            android:layout_height="match_parent" />

        <TextView android:id="@+id/title"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:singleLine="true" />

    </LinearLayout>

    <ImageView android:id="@+id/shot"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:scaleType="fitXY" />

</LinearLayout>

活动中的设置很少。只需获取对WebView的引用,设置其WebViewClient,并将其注册到WebShotFragment。如上所述,我在每个addCurrentSite()回调上执行Fragment onPageFinished()方法只是为了演示;你可能想改变它。

public class MainActivity extends Activity
    implements WebShotFragment.OnSiteSelectedListener {
    ...
    WebView webView;
    WebShotFragment webShotFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ...
        webView = (WebView) findViewById(...);
        webView.setWebViewClient(new WebViewClient() {
                public boolean shouldOverrideUrlLoading(WebView webView, String url) {
                    return false;
                }

                public void onPageFinished(WebView webView, String url) {
                    webShotFragment.addCurrentSite();
                }
            });

        webShotFragment = ... // Instantiate/initialize the Fragment

        webShotFragment.setOnSiteSelectedListener(this);
        webShotFragment.registerWebView(webView);
        ...
    }

    @Override
    public void onSiteSelected(String url) {
        webView.loadUrl(url);
    }
}

示例应用的截图:

screenshot