Get favicon from a web and save it to declared Icon in a Pojo class
Asked Answered
B

2

-1

I have a RecyclerViewAdapter which I have called MyAdapter and there I set for a Bookmark: ID, Name, Icon, SearchUrl.

I am able to show all of them but for the icon it works only from Drawable. I don't want to convert Bitmap to Drawable I only want take favicon of url which is saved in DB.
I want to take the favicon from the Bitmap because the icon depens from which SearchUrl it is gaven for example.
SearchUrl = "https://www.youtube.com" In the icon I need to show the favicon of the youtube. As I said manually this works from drawable but this is depended from the user which I do not know what kind of Url it is written.

Below you can find the code.

@Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, final int position) {
        final int itemType = getItemViewType(position);
        if (itemType == ITEM_TYPE_ONE) {
            final ViewHolder viewHolder = (ViewHolder) holder;
            viewHolder.tvName.setText(arrayList.get(position).getName());

            Bitmap bitmap = BitmapFactory.decodeStream((InputStream)new URL(viewHolder.tvSearchUrl.setText(arrayList.get(position).getSearchUrl())).getContent()); //Here is the error of the new URL
            viewHolder.tvIcon.setImageBitmap(bitmap);
            viewHolder.tvId.setText(arrayList.get(position).getId());
            viewHolder.tvSearchUrl.setText(arrayList.get(position).getSearchUrl());
            viewHolder.tvNativeUrl.setText(arrayList.get(position).getNativeUrl());
            viewHolder.tvIcon.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent;
                    String Url = viewHolder.tvSearchUrl.getText().toString();
                    String Name = viewHolder.tvName.getText().toString();
                    intent = new Intent(context, BookmarkActivity.class);
                    intent.putExtra("WebSearchUrl", Url);
                    intent.putExtra("WebSearchName", Name);
                    v.getContext().startActivity(intent);
                }
            });


            viewHolder.tvIcon.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    Intent intent = new Intent(context, ActivityChangeBookmark.class);
                    String Url = viewHolder.tvSearchUrl.getText().toString();
                    String Name = viewHolder.tvName.getText().toString();
                    Integer Id = viewHolder.tvId.getId();
                    Bundle extras = new Bundle();
                    viewHolder.tvIcon.buildDrawingCache();
                    Bitmap image = viewHolder.tvIcon.getDrawingCache();
                    intent.putExtra("Url", Url);
                    intent.putExtra("Name", Name);
                    intent.putExtra("ID", Id);
                    extras.putParcelable("Image", image);
                    intent.putExtras(extras);
                    v.getContext().startActivity(intent);
                    return false;
                }
            });

        } else if (itemType == ITEM_TYPE_TWO) {
            ButtonViewHolder buttonViewHolder = (ButtonViewHolder) holder;
            buttonViewHolder.imgButton.setImageResource(arrayList.get(position).getIcon());
        }

    }

If I change viewHolder.tvIcon.setImageResource(arrayList.get(position).getIcon()); than this takes from the drawable and workd only for the icons which are in drawable.

Bookmark.class

public class Bookmark {
    String name, id, nativeUrl, searchUrl;
    int icon;
    int viewType;


    public String getName() { return name; }
    public void setName(String name) {
        this.name = name;
    }

    public int getIcon() { return icon; }
    public void setIcon(int icon) {
        this.icon = icon;
    }

    public String getId(){
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getNativeUrl() {
        return nativeUrl;
    }

    public void setNativeUrl(String nativeUrl) {
        this.nativeUrl = nativeUrl;
    }

    public String getSearchUrl() {
        return searchUrl;
    }

    public void setSearchUrl(String searchUrl) {
        this.searchUrl = searchUrl;
    }
    public int getViewType() {
        return viewType;
    }

    public void setViewType(int viewType) {
        this.viewType = viewType;
    }


    @Override
    public String toString() {
        return "Bookmark{" +
                "name='" + name + '\'' +
                ", icon='" + icon + '\'' +
                ", id='" + id + '\'' +
                ", nativeUrl='" + nativeUrl + '\'' +
                ", searchUrl='" + searchUrl + '\'' +
                '}';
    }
}

ActivityChangeBookmark.class

 public class ActivityChangeBookmark  extends AppCompatActivity {
 private ArrayList<String> listItems = new ArrayList<String>();
 private RecyclerView recyclerView;
 Button saveBookmark, cancelBookmark;
 TextView name, url;
 ImageView icon, mIcon;
 EditText mName, mUrl, mID;
 public static final String Save_Bookmark = "Save_Bookmark";
 String Url, Name;
 Integer Id;
 MyAdapter myAdapter;
 BookmarkDB bookmarkDB;
 ButtonRobotoMedium removeBookmark, sendToHomeScreen;
 ArrayList<Bookmark> arrayList = new ArrayList<>();


@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_change_bookmark);
    saveBookmark = findViewById(R.id.btnSave);
    name = findViewById(R.id.tvNameEdit);
    url = findViewById(R.id.tvURLEdit);
    recyclerView = findViewById(R.id.myRecyclerView);
    icon = findViewById(R.id.ivFavIcon);
    mName = findViewById(R.id.etNameEdit);
    mUrl = findViewById(R.id.etURLEdit);
    sendToHomeScreen = findViewById(R.id.btnAddIconToDeviceScreen);
    name.setVisibility(View.GONE);
    url.setVisibility(View.GONE);
    bookmarkDB = new BookmarkDB(getApplicationContext());
    Intent intent = getIntent();
    myAdapter = new MyAdapter(getApplicationContext(), arrayList);

    Bundle extras = intent.getExtras();
    if (extras != null) {
        Url = intent.getExtras().getString("Url");
        Name = intent.getExtras().getString("Name");
        Id = intent.getExtras().getInt("ID");

        Bitmap bitmap = intent.getExtras().getParcelable("Image");
        mName.setText(Name);
        mUrl.setText(Url);

        icon.setImageBitmap(bitmap);
        removeBookmark.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                bookmarkDB.deleteName(Id, Name);
                myAdapter.notifyDataSetChanged();
                finish();
            }
        });
    }
     else {
        removeBookmark.setVisibility(View.GONE);
        sendToHomeScreen.setVisibility(View.GONE);
        icon.setImageResource(R.drawable.user_bookmark);
        mName.setText("");
        mUrl.setText("");
    }


    saveBookmark.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            saveData();
            myAdapter.notifyDataSetChanged();
            finish();
            }
    });

public void saveData() {
    Random r = new Random();
    int low = 14;
    int high = 100;
    int result = r.nextInt(high-low) + low;
    bookmarkDB.addBookmark(result, mName.getText().toString(), false, "https://www.google.com/s2/favicons?domain=" + mUrl.getText().toString(), mUrl.getText().toString(), "http://" + mUrl.getText().toString());
 }
}

BookmarkDB.class

 public class BookmarkDB extends SQLiteOpenHelper {
    public static final String DBNAME = "bookmarks.db"; // The name of the 
 database file
    public static final int DBVERSION = 1;  // The Database version

    public static final String TBL_BOOKMARK = "bookmark";
    public static final String COL_ID = BaseColumns._ID; // equates to _id
    public static final String COl_NAME = "name";
    public static final String COl_HIDDEN = "hidden";
    public static final String COL_ICON = "icon";
    public static final String COL_NATIVEURL = "nativeurl";
    public static final String COL_SEARCHURL = "searchurl";

    SQLiteDatabase mDB;

    public BookmarkDB(Context context) {
        super(context, DBNAME, null, DBVERSION);
        mDB = this.getWritableDatabase();
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

        // The SQL to be used to create the table
        String crt_bookmark_tbl_sql = "CREATE TABLE IF NOT EXISTS " + TBL_BOOKMARK + "(" +
                COL_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                COl_NAME + " TEXT, " +
                COl_HIDDEN + " INTEGER, " +
                COL_ICON + " TEXT, " +
                COL_NATIVEURL + " TEXT," +
                COL_SEARCHURL + " TEXT" +
                ")";
        db.execSQL(crt_bookmark_tbl_sql); // CREATE THE TABLE

    }


    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP IF TABLE EXISTS " + DBNAME);
        onCreate(db);
    }

    public long addBookmark(long id, String name, boolean hidden, String icon, String nativeurl, String searchurl) {
        ContentValues cv = new ContentValues();

        cv.put(COl_NAME,name);
        cv.put(COl_HIDDEN,hidden);
        cv.put(COL_ICON,icon);
        cv.put(COL_NATIVEURL,nativeurl);
        cv.put(COL_SEARCHURL,searchurl);
        // uses the convenience insert method that builds the SQL
        return mDB.insert(TBL_BOOKMARK,null,cv);
    }
    public ArrayList<Bookmark> getAllBookmarks() {
        ArrayList<Bookmark> rv  = new ArrayList<>();
        Cursor csr = mDB.query(TBL_BOOKMARK,null,null,null,null,null, null);
        while (csr.moveToNext()) {
            Bookmark b = new Bookmark();
            b.setId(csr.getString(csr.getColumnIndex(COL_ID)));
            b.setName(csr.getString(csr.getColumnIndex(COl_NAME)));
            b.setIcon(csr.getInt(csr.getColumnIndex(COL_ICON))); // Here I set the icon but I want to set icon from the saved SearchUrl.
            b.setViewType(csr.getInt(csr.getColumnIndex(COl_NAME)));
            b.setNativeUrl(csr.getString(csr.getColumnIndex(COL_NATIVEURL)));
            b.setSearchUrl(csr.getString(csr.getColumnIndex(COL_SEARCHURL)));
            rv.add(b);
        }
        return rv;
    }

FragmentBookmark.class

public class FragmentBookmark extends Fragment {
    ArrayList<Bookmark> arrayList = new ArrayList<>();
    MyAdapter myAdapter;
    View paramView;
    RecyclerView myRecyclerView;
    private Context mContext;
    BookmarkDB mDB;
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        mContext = context;
        mDB = new BookmarkDB(mContext);
        mDB.getAllBookmarks();
        buildBookmarkArrayListfromDB();
        loadBookMarksFromXML();
        mDB.logAllBookmarkRows();
    }
    @Nullable
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        paramView = inflater.inflate(R.layout.bookmark, container, false);
        myRecyclerView =  paramView.findViewById(R.id.myRecyclerView);
        // myRecyclerView.setLayoutManager(new LinearLayoutManager(mContext));
        myRecyclerView.setLayoutManager(new GridLayoutManager(mContext, 4));
        myRecyclerView.setHasFixedSize(true);
        myAdapter = new MyAdapter(mContext, arrayList);
        myRecyclerView.setAdapter(myAdapter);

        myAdapter.notifyDataSetChanged();
        Bookmark bookmark = new Bookmark();
        bookmark.setViewType(1);
        bookmark.setIcon(R.drawable.add_new_bookmark_icon);
        arrayList.add(bookmark);
        return paramView;
    }
    private void loadBookMarksFromXML() {

        // MAY WISH TO ONLY DO THIS ONCE as bookmarks would be loaded OTHERWISE DELETE LINE BELOW
        if(DatabaseUtils.queryNumEntries(mDB.getWritableDatabase(),BookmarkDB.TBL_BOOKMARK) > 0 ) return;
        try {
            XmlResourceParser xpp = getResources().getXml(R.xml.bookmarks);
            while (xpp.getEventType() != XmlPullParser.END_DOCUMENT) {
                if (xpp.getEventType() == XmlPullParser.START_TAG) {
                    if (xpp.getName().equals("Bookmark")) {
                        Bookmark bookmark = new Bookmark();
                        bookmark.setName(xpp.getAttributeValue(null, "name"));
                        bookmark.setSearchUrl(xpp.getAttributeValue(null, "searchUrl"));
                        bookmark.setNativeUrl(xpp.getAttributeValue(null, "nativeUrl"));
                        int drawableResourceId = getResources().getIdentifier(xpp.getAttributeValue(null, "icon"),"drawable", mContext.getPackageName());
                        bookmark.setIcon(drawableResourceId);
                        bookmark.setViewType(0);
                        if (bookmark.getId() == null) {
                            bookmark.setId("1");
                        }
                        mDB.addBookmark(
                                Long.valueOf(bookmark.getId()),
                                bookmark.getName(),
                                bookmark.getViewType() > 0,
                                String.valueOf(bookmark.getIcon()),
                                bookmark.getNativeUrl(),
                                bookmark.getSearchUrl()
                        );
                    }
                }
                xpp.next();
            }
        } catch (XmlPullParserException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        mDB.logAllBookmarkRows();
    }
    public void buildBookmarkArrayListfromDB() {
        arrayList.clear();
        arrayList.addAll(mDB.getAllBookmarks());
        Bookmark bookmark = new Bookmark();
        bookmark.setViewType(1);
        bookmark.setIcon(R.drawable.add_new_bookmark_icon);
        arrayList.add(bookmark);
    }
Boughten answered 17/1, 2019 at 10:25 Comment(4)
Possible duplicate of How to convert a Bitmap to Drawable in android?Kendakendal
@Kendakendal I am not trying to convert Bitmap to drawable I want to show favicon of Url to the viewHolder.tvIconBoughten
try this https://mcmap.net/q/57016/-any-way-to-grab-a-logo-icon-from-website-url-programmaticallyKendakendal
@Kendakendal Thank you for this but I have watched and It is not helping me so much. If you can please provide a code for my problem, only set favicon to viewholder.tvIcon which comes from a string and this is a void method viewHolder.tvSearchUrl.setText(arrayList.get(position).getSearchUrl());Boughten
V
1

You can use besticon

This is a favicon service:

  • Supports favicon.ico and apple-touch-icon.png

  • Simple URL API

  • Fallback icon generation

  • Docker image & single binary download for easy hosting

SAMPLE CODE HOW To use it

Layout

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/parentView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="10dp"
    android:orientation="vertical">


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">


        <ImageView
            android:id="@+id/stackIMG"
            android:layout_width="32dp"
            android:layout_height="32dp"
            android:layout_margin="10dp" />

        <ImageView
            android:id="@+id/fbIMG"
            android:layout_width="32dp"
            android:layout_height="32dp"
            android:layout_margin="10dp" />

        <ImageView
            android:id="@+id/twitterIMG"
            android:layout_width="32dp"
            android:layout_height="32dp"
            android:layout_margin="10dp" />

    </LinearLayout>


</LinearLayout>

Activity code

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.ImageView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;

public class MainActivity extends AppCompatActivity {


    String stackOverFlowURL, FacebookURL, TwitterURL;
    String BASE_URL = "https://besticon-demo.herokuapp.com/icon?url=";


    ImageView stackIMG,fbIMG,twitterIMG;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        stackIMG = findViewById(R.id.stackIMG);
        fbIMG = findViewById(R.id.fbIMG);
        twitterIMG = findViewById(R.id.twitterIMG);


        stackOverFlowURL = BASE_URL + "https://stackoverflow.com/" + "&size=32;";
        FacebookURL = BASE_URL + "https://www.facebook.com/" + "&size=32;";
        TwitterURL = BASE_URL + "https://twitter.com" + "&size=32;";

        RequestOptions requestOptions = new RequestOptions();
        requestOptions.error(R.drawable.ic_fav);

        Glide.with(MainActivity.this)
                .load(stackOverFlowURL)
                .apply(requestOptions)
                .into(stackIMG);

        Glide.with(MainActivity.this)
                .load(FacebookURL)
                .apply(requestOptions)
                .into(fbIMG);


        Glide.with(MainActivity.this)
                .load(TwitterURL)
                .apply(requestOptions)
                .into(twitterIMG);
    }


}

OUTPUT

enter image description here

UPDATE

make below changes in your code

@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, final int position) {
    String BASE_URL = "https://besticon-demo.herokuapp.com/icon?url=";

    final int itemType = getItemViewType(position);
    if (itemType == ITEM_TYPE_ONE) {
        final ViewHolder viewHolder = (ViewHolder) holder;

        viewHolder.tvName.setText(arrayList.get(position).getName());

        Glide.with(context)
                .load(BASE_URL+arrayList.get(position).getSearchUrl()+"&size=32;")
                .apply(requestOptions)
                .into(viewHolder.tvIcon);

        viewHolder.tvId.setText(arrayList.get(position).getId());
        viewHolder.tvSearchUrl.setText(arrayList.get(position).getSearchUrl());
        viewHolder.tvNativeUrl.setText(arrayList.get(position).getNativeUrl());
        viewHolder.tvIcon.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent;
                String Url = viewHolder.tvSearchUrl.getText().toString();
                String Name = viewHolder.tvName.getText().toString();
                intent = new Intent(context, BookmarkActivity.class);
                intent.putExtra("WebSearchUrl", Url);
                intent.putExtra("WebSearchName", Name);
                v.getContext().startActivity(intent);
            }
        });


        viewHolder.tvIcon.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                Intent intent = new Intent(context, ActivityChangeBookmark.class);
                String Url = viewHolder.tvSearchUrl.getText().toString();
                String Name = viewHolder.tvName.getText().toString();
                Integer Id = viewHolder.tvId.getId();
                Bundle extras = new Bundle();
                viewHolder.tvIcon.buildDrawingCache();
                Bitmap image = viewHolder.tvIcon.getDrawingCache();
                intent.putExtra("Url", Url);
                intent.putExtra("Name", Name);
                intent.putExtra("ID", Id);
                extras.putParcelable("Image", image);
                intent.putExtras(extras);
                v.getContext().startActivity(intent);
                return false;
            }
        });

    } else if (itemType == ITEM_TYPE_TWO) {
        ButtonViewHolder buttonViewHolder = (ButtonViewHolder) holder;
        buttonViewHolder.imgButton.setImageResource(arrayList.get(position).getIcon());
    }

}
Violette answered 19/1, 2019 at 11:34 Comment(12)
It is not showing any icon now. I have added the same code as you only in the request.error(R.drawable.ic_fav) I dont have this drawable. The url it is saved something like this http://samsung.comBoughten
@Spritzig try to print in log your BASE_URL+arrayList.get(position).getSearchUrl()+"&size=32;" anc check what url you are gettingViolette
@Spritzig also the requestOptions.error() is used to display error image if your can't get image from urlViolette
At the Logs I am getting this url https://besticon-demo.herokuapp.com/icon?url=https://www.bing.com&size=32 and when I paste this url in google chrome than it is getting the right icon.Boughten
@Spritzig sorry to say that but for me this url besticon-demo.herokuapp.com/icon?url=https://… is working fine check this output image screenshotViolette
@Spritzig here is the code i used for that url Glide.with(MainActivity.this) .load("https://besticon-demo.herokuapp.com/icon?url=https://www.bing.com&size=32") .into(stackIMG);Violette
it is working for me if I put in the google chrome but only in my app not, can you check my FragmentBookmark maybe there it is a problem with setting the Icon.Boughten
@Spritzig if POSSIBLE can please post your project or mail on GitHub so i can download and chcek where is the issue thanks and also for me on phone I'm able to see icon from that urlViolette
Please give me your gmail I will send you there.Boughten
@Spritzig you can find my email from hereViolette
I just send it.Boughten
@Spritzig let me checkViolette
K
0

Why are you using setText? This should work

URL url = new URL(arrayList.get(position).getSearchUrl());
Bitmap bmp = BitmapFactory.decodeStream(url.openConnection().getInputStream());
imageView.setImageBitmap(bmp);
Kenzie answered 18/1, 2019 at 22:43 Comment(3)
Where do I need to write this code ? i write to the Adapter but this is coming as error Method invocation 'openConnection' may produce 'java.lang.NullPointerException' more...Boughten
This is crashing my app, I write the same code and it was looking for try and catch I have writed but it is crashing the app. URL url = null; try { url = new URL(arrayList.get(position).getSearchUrl()); } catch (MalformedURLException e) { e.printStackTrace(); } Bitmap bmp = null; try { bmp = BitmapFactory.decodeStream(Objects.requireNonNull(url).openConnection().getInputStream());} catch (IOException e) { e.printStackTrace(); }viewHolder.tvIcon.setImageBitmap(bmp);Boughten
The problem it is coming in this line. bmp = BitmapFactory.decodeStream(Objects.requireNonNull(url).openConnection().getInputStream()); Boughten

© 2022 - 2024 — McMap. All rights reserved.