I'm a little unsure how to retrieve a large profile picture from facebook current when I use the picture ID. I am loading this URL into my imageview.
http://graph.facebook.com/1454465268197338/picture?type=large
But it doesn't load, when I enter this though it works.
https://fbcdn-profile-a.akamaihd.net/hprofile-ak-xft1/v/t1.0-1/p200x200/11014854_1403982213245644_5725357301610737602_n.jpg?oh=9d95140ca58c8e13a950e14f63018ff4&oe=55F8A88F&gda=1442905098_49d2c7ec583d417722e02a10206c0fb6
What I put above is the REDIRECTED URL after I put in the first. The problem is I cannot produce that with the userID I am given because I am using this.
#Override
public void onBindViewHolder(ContactViewHolder contactViewHolder, int i) {
Event ci = contactList.get(i);
contactViewHolder.vName.setText(ci.name);
TinyDB userinfo =new TinyDB(context);
String user_id = userinfo.getString("id");
profile_pic_url ="http://graph.facebook.com/"+user_id+"/picture?type=large";
Picasso.with(context)
.load(profile_pic_url)
.resize(225, 225)
.centerCrop()
.into(contactViewHolder.vProfilePic);
}
Pay attention to the profile_pic_url.
So ultimately, how can I get the redirected url (because I know that works)?
OR
how can I get a LARGE facebook profile picture url from the user because keep in mind the facebook android id because what I get from this:
parameters.putString("fields", "id,name,link,picture,friends");
IS REALLY SMALL.
I tried using
Java - How to find the redirected url of a url?
https://developers.facebook.com/docs/graph-api/reference/user/picture/
No luck unfortunately,
help is appreciated.
TYTY
Try
parameters.putString("fields", "id,name,link,picture.type(large),friends");
– that should get you the large version of the profile picture.
(This makes use of Field Expansion syntax to specify which data you want more precisely.)
You can get good large photo with minimym width of 1000 pic, for example, and height given from aspect ratio, using next code:
GraphRequest request = GraphRequest.newMeRequest(
loginResult.getAccessToken(),
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject object, GraphResponse response) {
String profileImg = "https://graph.facebook.com/" + loginResult.getAccessToken().getUserId() + "/picture?type=large&width=1000";
}
});
Bundle parameters = new Bundle();
parameters.putString(AuthConstants.FIELDS,
AuthConstants.ID + "," +
AuthConstants.BIRTHDAY + "," +
AuthConstants.FIRST_NAME + "," +
AuthConstants.LAST_NAME + "," +
AuthConstants.GENDER);
request.setParameters(parameters);
request.executeAsync();
}
Where
public static final String FIELDS = "fields";
public static final String ID = "id";
public static final String BIRTHDAY = "birthday";
public static final String FIRST_NAME = "first_name";
public static final String GENDER = "gender";
public static final String LAST_NAME = "last_name";
Related
Problem Description
How to Load Stickers Packs from firebase?
Links
Already I've been through -
https://github.com/idoideas/StickerMaker-for-Whatsapp
https://github.com/viztushar/stickers-internet
Well, you have to make a class with the sticker properties, a provider and a couple more things before loading the stickers from firebase(you can easily know how to retrieve data from firebase, it's the same for any data, so im going to skip that step)..
A dynamic WAStickers app should have following Characteristics:
Content Provider for necessary Details
It should Send an Intent to Whatsapp Sharing necessary details about the Sticker Pack All the
images must be in (or converted to) webp format
Why it should have a Content Provider?
A content provider is a class that sits between an application and its data source, and its job is to provide easy access to the underlying data source. This data can also be accessed by other applications on your device.
To provide necessary information about the StickerPack to WhatsApp you need to create a class called StickerPack which will hold the following parameters.
class StickerPack implements Parcelable {
String identifier;
String name;
String publisher;
String trayImageFile;
final String publisherEmail;
final String publisherWebsite;
final String privacyPolicyWebsite;
final String licenseAgreementWebsite;
String iosAppStoreLink;
private List<Sticker> stickers;
private long totalSize;
String androidPlayStoreLink;
private boolean isWhitelisted;
StickerPack(String identifier, String name, String publisher, String trayImageFile, String publisherEmail, String publisherWebsite, String privacyPolicyWebsite, String licenseAgreementWebsite) {
this.identifier = identifier;
this.name = name;
this.publisher = publisher;
this.trayImageFile = trayImageFile;
this.publisherEmail = publisherEmail;
this.publisherWebsite = publisherWebsite;
this.privacyPolicyWebsite = privacyPolicyWebsite;
this.licenseAgreementWebsite = licenseAgreementWebsite;
}
}
For additional information about this class follow the Link.
This class also contains an ArrayList of Stickers, where Sticker is defined by the following class.
package com.example.samplestickerapp;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.List;
class Sticker implements Parcelable {
String imageFileName;
List<String> emojis;
long size;
Sticker(String imageFileName, List<String> emojis) {
this.imageFileName = imageFileName;
this.emojis = emojis;
}
protected Sticker(Parcel in) {
imageFileName = in.readString();
emojis = in.createStringArrayList();
size = in.readLong();
}
public static final Creator<Sticker> CREATOR = new Creator<Sticker>() {
#Override
public Sticker createFromParcel(Parcel in) {
return new Sticker(in);
}
#Override
public Sticker[] newArray(int size) {
return new Sticker[size];
}
};
public void setSize(long size) {
this.size = size;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(imageFileName);
dest.writeStringList(emojis);
dest.writeLong(size);
}
}
Creating the Content Provider
For creating the content provider, first step is to:
Get permission to use the ContentProvider:
In the Android Manifest we should ask for a read/write permission to use the content provider. It’s a security feature which informs the user of what the app actually does.
<provider
android:name=".StickerContentProvider"
android:authorities="${contentProviderAuthority}"
android:enabled="true"
android:exported="true"
android:readPermission="com.whatsapp.sticker.READ" />
Where ${contentProviderAuthority} will be replaced by the authority name of your content provider.
Create a Class that extends ContentProvider
URI — Uniform Resource Identifier: URI is used to specifically identify or give the location of some data on your phone.
This location is how you know exactly what type of data we’re querying for. The location is build from 3 parts:
(1) content:// — The content provider prefix
(2) The content authority — specifies which Content Provider to use
(3) Specific
data — a string that identifies exactly what data in the Content
Provider we’re interesting in accessing.
In our Content Provider we need to mention 4 URI’S as mentioned here.
First, In the onCreate method of your ContentProvider class, create a URI Matcher object and add the URI’s to the object. Before going through the below code snippet read about Uri Matcher from the here.
Now since you are familiar with URI matcher you must be familiar with how to use it
First, we build a tree of Uri Matcher object.
Then we pass the Url to getType function which matches it against our URI
Let’s perform the first step here.
private static final UriMatcher MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
static final String METADATA = "metadata";
private static final int METADATA_CODE = 1;
private static final int METADATA_CODE_FOR_SINGLE_PACK = 2;
private static final int STICKERS_CODE = 3;
static final String STICKERS_ASSET = "stickers_asset";
private static final int STICKERS_ASSET_CODE = 4;
private static final int STICKER_PACK_TRAY_ICON_CODE = 5;
#Override
public boolean onCreate() {
final String authority = BuildConfig.CONTENT_PROVIDER_AUTHORITY;
if (!authority.startsWith(Objects.requireNonNull(getContext()).getPackageName())) {
throw new IllegalStateException("your authority (" + authority + ") for the content provider should start with your package name: " + getContext().getPackageName());
}
MATCHER.addURI(authority, METADATA, METADATA_CODE);
MATCHER.addURI(authority, METADATA + "/*", METADATA_CODE_FOR_SINGLE_PACK);
MATCHER.addURI(authority, STICKERS + "/*", STICKERS_CODE);
for (StickerPack stickerPack : getStickerPackList()) {
MATCHER.addURI(authority, STICKERS_ASSET + "/" + stickerPack.identifier + "/" + stickerPack.trayImageFile, STICKER_PACK_TRAY_ICON_CODE);
for (Sticker sticker : stickerPack.getStickers()) {
MATCHER.addURI(authority, STICKERS_ASSET + "/" + stickerPack.identifier + "/" + sticker.imageFileName, STICKERS_ASSET_CODE);
}
}
return true;
}
Here in the above method we have added a Uri pattern to our MATCHER object, now we need to match this pattern and return the exact UrI which will the location of sticker data on our device. Next the Url hit by WhatsApp is passed to the getType function to match it against our Uri’s and return the specific location of data on our device.
#Override
public String getType(#NonNull Uri uri) {
final int matchCode = MATCHER.match(uri);
switch (matchCode) {
case METADATA_CODE:
return "vnd.android.cursor.dir/vnd." + BuildConfig.CONTENT_PROVIDER_AUTHORITY + "." + METADATA;
case METADATA_CODE_FOR_SINGLE_PACK:
return "vnd.android.cursor.item/vnd." + BuildConfig.CONTENT_PROVIDER_AUTHORITY + "." + METADATA;
case STICKERS_CODE:
return "vnd.android.cursor.dir/vnd." + BuildConfig.CONTENT_PROVIDER_AUTHORITY + "." + STICKERS;
case STICKERS_ASSET_CODE:
return "image/webp";
case STICKER_PACK_TRAY_ICON_CODE:
return "image/png";
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
}
Next, depending upon the Url we call the query method which will match the Uri and return a cursor object for the specific Uri.
#Override
public Cursor query(#NonNull Uri uri, #Nullable String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
final int code = MATCHER.match(uri);
if (code == METADATA_CODE) {
return getPackForAllStickerPacks(uri);
} else if (code == METADATA_CODE_FOR_SINGLE_PACK) {
return getCursorForSingleStickerPack(uri);
} else if (code == STICKERS_CODE) {
return getStickersForAStickerPack(uri);
} else {
throw new IllegalArgumentException("Unknown URI: " + uri);
}
}
Cursors are iterators that provide read/write access to the data of a Content Provider.
See the getPackForAllStickerPacks(), getCursorForSingleStickerPack() and getStickerPackInfo() function from here. To know the type of data to be provided by the Cursor Object.
Congratulations!! By now you have reached your first milestone. So far we have learnt:
What are Content Providers?
What type of Data do we send via ContentProviders?
How do we process the Uri’s to give a specific Cursor object?
If you can answer these questions then Congrats!! You have done a wonderful job. If not then I would suggest you to read about ContentProviders and UriMatcher’s to get a proper understanding.
After that, you just need to load the content from firebase, which should have the same structure on your class.
Source: Link
I am using an addChildEventListener on the users level of my firebase database which contains usernames email and latest_post. The recyclerView will only use latest_post which is optional and not all users will have it, so I need to filter the userPosts object so that it contains only the users that have the field `latest_post'. here is the event listener:
query.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
User userPost = dataSnapshot.getValue(User.class);
System.out.println("User" + userPost.getUsername());
}
This is how I setUp the recyclerView cells:
void setPost(final User user) {
final Post post = user.getLatest_post();
final Long date = post.post_date;
final String post_id = post.getPost_id();
final String key = post.getPost_id();
final Integer reads = post.getReads();
final String titleString = post.getTitle();
final String bodyString = post.getBody();
final String usernameString = post.getAuthor();
final String category = post.getCategory();
final String author_id = post.getAuthor_id();
...
}
So unless I filter userPosts before I setUp the view it will crash because it will try even on the paths where there is no latest_post. How can I filter so that the object I use when setting up the recycler view only contains objects where latest_post is not null? I cannot change the database structure as this point. Thank you.
UPDATE:
By doing this I can see that It knows which values have latest_post and which don't, but im still not sure how to make it into a nice object I can do my setup with. I've updated the code like so:
query.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
Post latestPost = dataSnapshot.child("latest_post").getValue(Post.class);
Boolean userPost = dataSnapshot.hasChild("latest_post");
System.out.println("User" + userPost);
System.out.println("latestPost" + latestPost);
}
So somehow I can just use the Post class contained in User:
void setPost(final Post post) {
final Post latest = post;
final Long date = latest.post_date;
final String post_id = latest.getPost_id();
final String key = latest.getPost_id();
final Integer reads = latest.getReads();
final String titleString = latest.getTitle();
final String bodyString = latest.getBody();
final String usernameString = latest.getAuthor();
final String category = latest.getCategory();
final String author_id = latest.getAuthor_id();
...
}
After a lot of research, it turns out you can order a query, for example:
query = query.child("users").orderByChild("latest_post")
This would allow the recycled view to work but once you scroll to a certain point, it would crash.
You cannot filter a query to exclude items that don't exist.
I had to create my own recycler adapter, and use a list of my post class, and then filter that list after querying the database.
I'm programing an android app that connects to a MySQL server, so far I have it so the user can enter the server ip, database name, user name and password and store it to the phone. I am trying to build a string off the info the user just entered to test the connection prior to saving to the .txt files. I know it's probably right in front of my face but after a day of this I'm stuck, please help!! The problem is located in the 'TestButtonListener'
public class AppInfo extends Activity {
public static final String DEBUGTAG = "It's Broke";
public static final String DATABASEPASSWORD = "pinfo.txt";
public static final String SERVERIP = "sinfo.txt";
public static final String DATABASEUSER = "ninfo.txt";
public static final String DATABASE = "dinfo.txt";
public static final String FILESAVED = "filesaved";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_app_info);
addTestButtonListener();
///Test connection
private void addTestButtonListener() {
Button test = (Button) findViewById(R.id.testcon);
test.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
///need information from the R.id.server, R.id.database, R.id.name, R.id.pword
/// and insert it into the string as serverIp, dataBase, name, pword.
///
try {
/// everything I've tried in here spits out the name of the text file,
/// or the memory address, but not the value just typed in.
}
String serverConnect = new String("jdbc:mysql://" + serverIp
+ "/" + dataBase + ", " + name + ", " + pword);
Toast.makeText(AppInfo.this, serverConnect, Toast.LENGTH_LONG)
.show();
}
});
}
Don't bother, I figured out how to fix it with .getText().toString() and after all that come to find out Android DOES NOT WORK with jdbc connector.
I use spring-social-facebook to interact with Graph API (1.0.3.RELEASE if it's metter). And I can't find any operation to retrieve profile's image url. I found only operations which return array of bytes and they are not very convenient for the implementation.
Does any kind of operation which retrieves image url exist in Spring Social?
If not, is there any 'tidy' workaround for this?
Thanks!
Finally, I didn't find any mention of profile picture url in spring social
My solution:
Initially I planned to extend UserOperations (FacebokTemplate.userOperations) class and add new method. But it's a package-level class and doens't visible outside.
So I decided to create my own template class extending FacebookTemplate and implement the method in this way:
public String fetchPictureUrl(String userId, ImageType imageType) {
URI uri = URIBuilder.fromUri(GRAPH_API_URL + userId + "/picture" +
"?type=" + imageType.toString().toLowerCase() + "&redirect=false").build();
JsonNode response = getRestTemplate().getForObject(uri, JsonNode.class);
return response.get("data").get("url").getTextValue();
}
i just ran into same issue, hope this will help someone else
Connection<Facebook> connection = userConnectionRepository.findPrimaryConnection(Facebook.class);
connection.createData().getImageUrl()
You could take the miniature picture in this way :
"http://graph.facebook.com/" + fbUser.getId() + "/picture?type=square"
In social API you have ability just to fetch the image binary file:
byte[] profileImage = facebook.userOperations().getUserProfileImage(imageType);
To get URL you need to have something custom (as mentioned in the post above).
I took the part of code from Facebook Social API (see Facebook template source code for fetchImage) and the following utility class:
public final class FacebookUtils {
private static final String PICTURE_PATH = "picture";
private static final String TYPE_PARAMETER = "type";
private static final String WIDTH_PARAMETER = "width";
private static final String HEIGHT_PARAMETER = "height";
private FacebookUtils() {
}
public static String getUserProfileImageUrl(Facebook facebook, String userId, String width, String height, ImageType imageType) {
URIBuilder uriBuilder = URIBuilder.fromUri(facebook.getBaseGraphApiUrl() + userId + StringUtils.SLASH_CHARACTER + PICTURE_PATH);
if (imageType != null) {
uriBuilder.queryParam(TYPE_PARAMETER, imageType.toString().toLowerCase());
}
if (width != null) {
uriBuilder.queryParam(WIDTH_PARAMETER, width.toString());
}
if (height != null) {
uriBuilder.queryParam(HEIGHT_PARAMETER, height.toString());
}
URI uri = uriBuilder.build();
return uri.toString();
}
}
How can I get the accessToken from the anonymous inner class below? when I try to use the accessToken outside the class it shows up as null. I tried to display a toast with the accessToken right after I closed the inner class and it just shows up as null. I want to be able to use the accessToken in an asynctask to fetch some data. How can I go about doing this?
public class main extends Activity {
public static final String CALLBACK_URL = "url";
public static final String CLIENT_ID = "id";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String url =
"https://foursquare.com/oauth2/authenticate" +
"?client_id=" + CLIENT_ID +
"&response_type=token" +
"&redirect_uri=" + CALLBACK_URL;
// If authentication works, we'll get redirected to a url with a pattern like:
//
// http://YOUR_REGISTERED_REDIRECT_URI/#access_token=ACCESS_TOKEN
//
// We can override onPageStarted() in the web client and grab the token out.
WebView webview = (WebView)findViewById(R.id.webView);
webview.getSettings().setJavaScriptEnabled(true);
webview.setWebViewClient( new WebViewClient() {
public void onPageStarted(WebView view, String url, Bitmap favicon) {
String fragment = "#access_token=";
int start = url.indexOf(fragment);
if (start > -1) {
// You can use the accessToken for api calls now.
String accessToken = url.substring(start + fragment.length(), url.length());
Toast.makeText(main.this, "Token: " + accessToken, Toast.LENGTH_SHORT).show();
}
}
});
webview.loadUrl(url);
}
}
String accessToken =
url.substring(start + fragment.length(), url.length());
There is your access token.
You can pass it to somewhere else in your program. You need to modify the inner class given in the example to fit your needs. As of now, it just displays the token in a dialog box.