Monday, 25 April 2016

LinkedIn Integration - Andorid

Introduction

LinkedIn is one of the most popular social networking platforms available today. LinkedIn users can share status updates, respond to topics of interest, read the latest updates from contacts and companies, and participate in group discussions about topics that interest them.

The popularity of social networking platforms like Facebook, LinkedIn, and Twitter means that mobile app developers are tightly integrating these services with their applications to allow users to share content on these sites without ever leaving an application.

Overview of SDK

  • The mobile SDK for Android increases your app's time to market by providing out-of-box support for LinkedIn natively inside your Android applications.
  • The Mobile SDK for Android requires the official LinkedIn Android application is also installed to support the SDK's capabilities.
  • The minimum supported version is Android 4.4.2 (API 19).

 

SDK Features

  • Single sign-on (SSO) authentication, in conjunction with the LinkedIn mobile app.
  • A convenient wrapper for making authenticated calls to LinkedIn's REST APIs.
  • "Deep linking" to additional member data in the LinkedIn mobile app.
  • Sample application that demonstrate best-practice implementations of all of the SDK's features.

Please find steps below for LinkedIn integration in Android.

 

Step - 1 Create Application  
  • To Integrate LinkedIn in your mobile application, you need to create a new application using LinkedIn Developer’s Account.
  • Create application from LinkedIn developer account.
    https://www.linkedin.com/developer/apps



Step - 2 Set the Application Permission
  • Now, you need to set  the Default Application Permissions.
    And to do that, you have to select check box “r_basicprofile” and “r_emailaddress” and click on the “update” button to set the permission.



Step - 3 Download Mobile LinkedIn SDK

Go to https://developer.linkedin.com/docs/android-sdk  and download a Mobile SDK for Android.


Step - 4 Generate Hash Key
  • We need to generate a hash key. This generated Hash key will integrate your app with Linkedin account.
  • Go to https://www.linkedin.com/developer/apps  
  • Select your application name and click the Mobile tab. 
  • Add the package name and generated hash key in your LinkedIn Application.
  • This hash key will authenticate your mobile application. 




Login

private static final String topCardUrl = "https://" + host + "/v1/people/~:(first-name,last-name,email-address,formatted-name,phone-numbers,public-profile-url,picture-url,picture-urls::(original))"
private static Scope buildScope() {
    return Scope.build(Scope.R_BASICPROFILE, Scope.R_EMAILADDRESS, Scope.W_SHARE);
}
public void loginLinkedin() {
LISessionManager.getInstance(getApplicationContext()).init(this,
   buildScope(), new AuthListener() {
         @Override 
         public void onAuthSuccess() {

           APIHelper apiHelper = APIHelper.getInstance(getApplicationContext());
           apiHelper.getRequest(MainActivity.this, topCardUrl, new ApiListener() {
                @Override                         
                public void onApiSuccess(ApiResponse s) {
                           
                 Log.e(TAG, "Profile json" + s.getResponseDataAsJson());
                 Log.e(TAG, "Profile String" + s.getResponseDataAsString());

                   try {
                     Log.e(TAG, "Profile emailAddress" + s.getResponseDataAsJson().get("emailAddress").toString());
                     Log.e(TAG, "Profile formattedName" + s.getResponseDataAsJson().get("formattedName").toString());

                     txtFirstName.setText(s.getResponseDataAsJson().get("emailAddress").toString());
                     txtLastName.setText(s.getResponseDataAsJson().get("formattedName").toString()); 
                     Picasso.with(MainActivity.this).load(s.getResponseDataAsJson().getString("pictureUrl"))
                            .into(imgProfilePic);

                        }catch (Exception e){

                        }

              }

                @Override 
                public void onApiError(LIApiError error) {
                            //((TextView) findViewById(R.id.response)).setText(error.toString());                            Toast.makeText(getApplicationContext(), "Profile failed " + error.toString(),
                                    Toast.LENGTH_LONG).show();
                        }
                    });

                }

         @Override                 
         public void onAuthError(LIAuthError error) {

         Toast.makeText(getApplicationContext(), "failed " + error.toString(),
                            Toast.LENGTH_LONG).show();
                }
            }, true);

Logout

LISessionManager.getInstance(getApplicationContext()).clearSession();

Check Login

private boolean isLogin(){
    LISessionManager sessionManager = LISessionManager.getInstance(getApplicationContext());
    LISession session = sessionManager.getSession();
    boolean accessTokenValid = session.isValid();
    return accessTokenValid;
}
Share Message
private static final String shareUrl = "https://" + host + "/v1/people/~/shares";
 
public void shareMessage() {
    APIHelper apiHelper = APIHelper.getInstance(getApplicationContext());
    apiHelper.postRequest(MainActivity.this, shareUrl, buildShareMessage("Hello World", "Hello Title", "Hello Descriptions", "http://ankitthakkar90.blogspot.in/", "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZ7yxE4LwG4HieBIXz35yzPKqdF5RZCqY_35Dq-YvjbPTUt74y8Yv7HFCew0E3TIascumbykrTa__0pdzFuKb0al3xYxc2Jzj1DIiO14oRHbm51IL7FMnYFSFVKervlri41xOo-mo6ir_9/s320/10333099_1408666882743423_2079696723_n.png"), new ApiListener() {
        @Override 
        public void onApiSuccess(ApiResponse apiResponse) {
            // ((TextView) findViewById(R.id.response)).setText(apiResponse.toString());            Toast.makeText(getApplicationContext(), "Share success:  " + apiResponse.toString(),
                    Toast.LENGTH_LONG).show();
            Log.e(TAG, "share success" + apiResponse.toString());
        }

        @Override         
        public void onApiError(LIApiError error) {
            //   ((TextView) findViewById(R.id.response)).setText(error.toString());            Toast.makeText(getApplicationContext(), "Share failed " + error.toString(),
                    Toast.LENGTH_LONG).show();
        }
    });
} 

public String buildShareMessage(String comment,String title,String descriptions,String linkUrl,String imageUrl  ){
    String shareJsonText = "{ \n" +
            "   \"comment\":\"" + comment + "\"," +
            "   \"visibility\":{ " +
            "      \"code\":\"anyone\"" +
            "   }," +
            "   \"content\":{ " +
            "      \"title\":\""+title+"\"," +
            "      \"description\":\""+descriptions+"\"," +
            "      \"submitted-url\":\""+linkUrl+"\"," +
            "      \"submitted-image-url\":\""+imageUrl+"\"" +
            "   }" +
            "}";
    return shareJsonText;
}
Open Current User Profile
public void openUserProfile(){
    DeepLinkHelper deepLinkHelper = DeepLinkHelper.getInstance();
    deepLinkHelper.openCurrentProfile(MainActivity.this, new DeepLinkListener() {
        @Override         
        public void onDeepLinkSuccess() {
            Log.e(TAG, "openUserProfile success");
        }

        @Override 
        public void onDeepLinkError(LIDeepLinkError error) {
            Log.e(TAG, "openUserProfile error" + error.toString());
        }
    });
}

Best Practices

Posting on member's behalf
  •  Members assume that they will have control on what content is posted and shared on their behalf. You should assure users that you will not post or send mail on their behalf without their consent, and give them the option to edit content before it is posted or not share content if they choose.

Permission Request
  • You should educate users on which permissions you are requesting and how this data will be used. LinkedIn does not support incremental permission request, so all permissions must be granted during the authorization step.  
  •  Requesting too many permissions may cause users not to authorize your application, so you should only ask for the permissions that you need.
Authentication
  • Whenever possible, remind the user that they are logged into your application by displaying their name, portrait, and/or account settings.
  • You should also avoid multiple log in prompts. 
  • Cache the user's access token after they grant your application and do not bring the user through the authentication flow again unless they log out or the access token expires or is otherwise invalid.
  • You should allow the user to log out, and when they do log out you should destroy the access token you had been granted.

 

Cancelling in-progress requests

During your application's workflow, you may wish to cancel any in-progress API requests.  This is done by calling APIHelper.cancelCalls() method.

Using ProGaurd with your application 

If you intend to use ProGuard on the release build of your mobile application, you will need to add the following lines to your project's proguard-project.txt file to preserve information required for the SDK to function properly:

proguard configuration

-keep class com.linkedin.** { *; }
-keepattributes Signature

Mobile vs. server-side access tokens            

It is important to note that access tokens that are acquired via the Mobile SDK are only useable with the Mobile SDK, and cannot be used to make server-side REST API calls.

Similarly, access tokens that you already have stored from your users that authenticated using a server-side REST API call will not work with the Mobile SDK.

Partnership Program

  • All other APIs (e.g. Connections, Groups, People Search, Invitation, Job Search, etc.) will require developers to become a member of one of our partnership programs.  
  • Partnering with LinkedIn provides you with additional API functionality & data access, increased call limits & dedicated support.
  • Applications are only accepted when we feel that they're providing value to members, developers and LinkedIn.
https://developer.linkedin.com/partner-programs

References

https://developer.linkedin.com/docs/android-sdk
https://developer.linkedin.com/docs/android-sdk-auth
https://developer.linkedin.com/downloads#androidsdk
https://www.numetriclabz.com/android-linkedin-integration-login-tutorial/
https://developer.linkedin.com/docs/oauth2
https://developer.linkedin.com/partner-programs/apply
https://developer.linkedin.com/support/developer-program-transition
http://www.solutionanalysts.com/blog/step-by-step-developers-guide-to-integrate-linkedin-with-an-android-application/

You can Download source code of this example from Github.



Tuesday, 10 November 2015

Facebook App Deep Linking - Andoid

One of the most interesting aspects of sharing to Facebook from your app is that when people engage with the feed stories posted from your app, those stories can send people to your app or your app's Google Play listing, driving traffic and app installs. You can implement this behavior using App Links.

   App link Flow


Facebook's Mobile Hosting API for App Links:


If your application doesn't have a website for content you want to share to Facebook, you don't have public web URLs which you can annotate to support App Links.

For these types of apps, Facebook provides an App Links Hosting API that will host App Links for you. With the Hosting API you can create and manage your App Links for all the mobile environments you support.

This is the typical flow to configure an App Link for a piece of content:
  1. Create a new App Link object. You can set up an object for one platform or several at the same time.
  2. Save the App Link object ID that's returned.
  3. Use that ID to get the URL you can use to share the content.
  4. Configure additional platforms that you support.
  5. If supporting Android, configure your app's manifest file for the configured URLs.

Please follow below steps for generate app linking.


For web service, In request Params we need to send below parameters.

iOS: url, name
Android: url, name

Step #1: Generate App Access Token (Ref. https://developers.facebook.com/docs/facebook-login/access-tokens#apptokens)

GET /oauth/access_token?     client_id={app-id}    &client_secret={app-secret}    &grant_type=client_credentials


Step #2: Generate App Link using generated App Access Token (Ref. https://developers.facebook.com/docs/applinks/hosting-api)


You create a new App Link object for a content targeted to iOS & Android  like this

curl https://graph.facebook.com/app/app_link_hosts \
-F access_token="APP_ACCESS_TOKEN" \
-F name="iOS App Link Object Example" \
-F ios=' [
    {
      "url" : "applinkFB://showApp/54eee6292658c7df25000004",
      "app_store_id" : 570281083,
      "app_name" : “appName”,
    },
  ]' \
-F android=' [
    {
      "url" : "applinkFB://showApp/54eee6292658c7df25000004",
      "package" : "com.packagename”,
      "app_name" : “appName”,
    },
  ]' \

-F web=' {
    "should_fallback" : false,
  }'


A successful call returns an ID that represents the App Link object hosted on Facebook,
for example:

Return : {"id":"643402985734254"}

Step #3: Using generated ID(YOUR_APP_LINK_HOST_ID) which represents the App Link, you need to call another API which will return "canonical_url"


You can retrieve the canonical URL that points to your new App Link object through this API call:

curl -G https://graph.facebook.com/YOUR_APP_LINK_HOST_ID \
-d access_token="APP_ACCESS_TOKEN" \
-d fields=canonical_url \
-d pretty=true

Where YOUR_APP_LINK_HOST_ID represents the id returned from creating your App Link object. Your response will look like this:

Return:
{
   "canonical_url": "https://fb.me/643402985734254",   "id": "643402985734254"
}


Support sharesample URLs in Android

When a shared link is tapped your Android app is launched through the URL specified in the App Link object you just created (if you didn't specify a url, then it will use the canonical URL - i.e. the https://fb.me/xxxxx URL). To set up your app to respond to this URL, you need to add an intent filter in your app's manifest file.

The filter should respond to the applinkFB scheme (if you didn't specify a URL, then your filter should respond to the fb.me host and https scheme), handle implicit intents, and accept the ACTION_VIEW action. The example below adds an intent filter to the MainActivity that handles this:



    ...
    
        
        
        
        
    


Once you've set up your web pages based App Links, 
you're ready to handle incoming links to your app.

Handling incoming links

To ensure an engaging user experience, you should process the incoming intent information when your app is activated and direct the person to the object featured in the story they're coming from. 

For example, if I see a story on my Facebook feed about one of my friends completing this share tutorial and I tap on it, I will expect to be redirected to a view in your app that features this tutorial and not to your app's main activity.

If you use the App Links Hosting API, the Intent data will look like this:


data: "applinkFB://showApp/54eee6292658c7df25000004?target_url=https%3A%2F%2Ffb.me%2F643402985734299"
extras:
  al_applink_data: <Bundle containing App Link data>

In the code sample below, we're simply logging the target URL, but you should direct people through the appropriated flow for your app:


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    FacebookSdk.sdkInitialize(this); 
    ...
    Uri targetUrl =
      AppLinks.getTargetUrlFromInboundIntent(this, getIntent());
    if (targetUrl != null) {
        Log.i("Activity", "App Link Target URL: " + targetUrl.toString());
    }
}

Wednesday, 4 November 2015

Twitter- Deep Linking with Android

Twitter - Deep Linking for Mobile Developers

The App Card provides the ability for users to download your app (if the user doesn’t already have it installed), or deep-link into your own app (if the app is already installed on the user’s mobile device).
We can achieve this things with Twitter Card.

https://dev.twitter.com/cards/mobile

We need to make dynamic Web page and host this page on any server which will be use for Sharing using Twitter from app. 

For demonstration purpose, we have implemented the same functionality in PHP with some hard-coded data but you need to convert in your back-end technology with dynamic data.

Please find PHP source code which we used for testing purpose.

Web Page Part
<html>
<head> 
<title>App Name</title>
<meta name="twitter:card" content="summary">

<meta name="twitter:site" content="App Name">
<meta name="twitter:title" content="App Name">

<meta name="twitter:description" content="App Name is a 100% free social sharing app that allows sharing of video, photo, audio and text all in one network.">
<meta name="twitter:image" content="http://app_name.vm39.sa92.info/ico.png">
<meta name="twitter:url" content="http://appname.com/">
<meta name="twitter:app:name:iphone" content="appname"/>
<meta name="twitter:app:id:iphone" content="570281083"/>
<meta name="twitter:app:name:googleplay" content="appname"/>
<meta name="twitter:app:id:googleplay" content="com.appname"/>
<meta name="twitter:app:url:iphone" content="appname://show?bid=54e58b4360afd71a53001f5e" />
<meta name="twitter:app:url:googleplay" content="appname://show?bid=54e58b4360afd71a53001f5e" />
</head>
<body>
<h1>Have something interesting here for particular Post, becasue when user click on link from Twitter it he/she will come to this page.</h1>
</body>
</html>

We have used summary card here.
https://dev.twitter.com/cards/types/summary
https://dev.twitter.com/cards/types/app

After making card, you have to validate your card with below URL.
https://cards-dev.twitter.com/validator

Android Part

At Android side, we need to do below things.
We need to add host and scheme in activity tag of Manifest file based on url defined in twitter app link url above.

Please find below code snippets below for reference.

AndroidManifest.xml

 <activity

            android:name=".ui.activities.SplashActivity"

            android:label="@string/app_name"

            android:launchMode="singleTop"

            android:screenOrientation="sensorPortrait"

            android:windowSoftInputMode="adjustResize" >

            <intent-filter>

                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />

            </intent-filter>

            <intent-filter android:label="@string/app_name" >

                <action android:name="android.intent.action.VIEW" >
                </action>
                <category android:name="android.intent.category.DEFAULT" >
                </category>
                <category android:name="android.intent.category.BROWSABLE" >
                </category>


                <!-- Accepts URIs that begin with "example://action" -->

                <data

                    android:host="show"
                    android:scheme="appname" >

                </data>

            </intent-filter>
        </activity> 



In Activity, You can retrieve app link url in oncreate() method.
With url, you can redirect user to our app's screen based on data retrieved from URL.

Please find below code snippets below for reference.

onCreate() 
if (getIntent().getData() != null

                && getIntent().getData().toString().length() > 0) {


            Logs.e(TAG, "Data:" + getIntent().getData());

        if (getIntent().getData().toString().startsWith("appname")) {


                twitterCallbackUrl = getIntent().getData().toString()
                        .substring(getIntent().getData().toString().lastIndexOf("?bid=") + 5,
                                getIntent().getData().toString().length());



                Logs.e(TAG, "twitterCallbackUrl:" + twitterCallbackUrl);
            }
        }




 
 

Sunday, 16 August 2015

Material design for Android

  Material design is a comprehensive guide for visual, motion, and interaction design across platforms and devices. Android now includes support for material design apps. To use material design in your Android apps, follow the guidelines defined in the material design specification and use the new components and functionality available in Android 5.0 (API level 21) and above.

Android provides the following elements for you to build material design apps:

  • A new theme
  • New widgets for complex views
  • New APIs for custom shadows and animations

For more information about implementing material design on Android, see Creating Apps with Material Design.

Material Theme

The material theme provides a new style for your app, system widgets that let you set their color palette, and default animations for touch feedback and activity transitions.












         Dark material theme                                                                            Light material theme  


Lists and Cards

Android provides two new widgets for displaying cards and lists with material design styles and animations:


The new RecyclerView widget is a more pluggable version of ListViewthat supports different layout types and provides performance improvements.



The new CardView widget lets you display important pieces of information inside cards that have a consistent look and feel.
For more information, see Creating Lists and Cards.

View Shadows
In addition to the X and Y properties, views in Android now have a Z property. This new property represents the elevation of a view, which determines:
  • The size of the shadow: views with higher Z values cast bigger shadows.
  • The drawing order: views with higher Z values appear on top of other views.
For more information, see Defining Shadows and Clipping Views.

Animations
The new animation APIs let you create custom animations for touch feedback in UI controls, changes in view state, and activity transitions.

These APIs let you:
  • Respond to touch events in your views with touch feedbackanimations.
  • Hide and show views with circular reveal animations.
  • Switch between activities with custom activity transitionanimations.
  • Create more natural animations with curved motion.
  • Animate changes in one or more view properties with view state change animations.
  • Show animations in state list drawables between view state changes.

Touch feedback animations are built into several standard views, such as buttons. The new APIs let you customize these animations and add them to your custom views.

For more information, see Defining Custom Animations.

Drawables

These new capabilities for drawables help you implement material design apps:
  • Vector drawables are scalable without losing definition and are perfect for single-color in-app icons.
  • Drawable tinting lets you define bitmaps as an alpha mask and tint them with a color at runtime.
  • Color extraction lets you automatically extract prominent colors from a bitmap image
For more information, see Working with Drawables.

References:

https://developer.android.com/design/get-started/principles.html
http://www.google.com/design/spec/material-design/introduction.html
https://developer.android.com/design/material/index.html 
https://www.youtube.com/watch?v=p4gmvHyuZzw
https://www.youtube.com/watch?v=XOcCOBe8PTc
https://www.youtube.com/watch?v=YaG_ljfzeUw

Friday, 17 October 2014

This blog useful when we have to update status on user's fan page/friend page instead of user's wall using Facebook sdk.

This kind of functionality implemented in Instagram.
After a lots of search I  have find some useful things which is useful to me.
I would like to share this thing with you. This might be useful to u also.

Parameter list Used in Request:
  • name
  • caption
  • description
  • picture
  • link
  • to
  • message
This is parameter required when we want to post on user's fan page. You can add or remove more parameter as per requirement.

We have to pass bundle in parameter so bundle created for parameter.
Bundle requestParams =new Bundle (); 

requestParams.putString(

                        "picture", filePath);

requestParams.putString("name",

                         TheApplication.getInstance().getString(R.string.app_name));

requestParams.putString("link",
                           "http://url");
Permission:
  <string-array name="fb_advance_permissions">

        <item>manage_pages</item>

   </string-array> 

1.) Retrieve login user's page list

This method retrieve page list created by login user. manage_page permission required to fetch user's page list.
/**

     * retrieve facebook user page list and ask for permission

     * 

     * @param pageListener

     *            - call success, error

     */

    public static void getUserPageList(

            final IFacebookCommonListener<String> pageListener) {

        Session session = Session.getActiveSession();

        sFBRedirectionState = FbRedirectionState.GET_PAGE_LIST;

        getPagesCallback = pageListener;



        if (getPagesCallback == null) {

            return;

        }

        if (session != null) {

            // if (!session.isOpened()) {

            // openSession();

            // }



            if (!session.isOpened()) {

                Logs.d(DEBUG_FACEBOOK_PUBLISH,

                        "Page error: !session.isOpened()");

                closeSession();

                openSession();

              

                return;

            }



            if (!canRetrievePages() && !isPagePermissionCalled) {

                getPagesPermissions(mStatusCallback);

                isPagePermissionCalled = true;

                return;

            }



            if (!canRetrievePages() && isPagePermissionCalled) {

                if (pageListener != null) {

                    pageListener.onError("Facebook can't retrieve pages");

                }

                session.removeCallback(statusCallback);

                sFBRedirectionState = FbRedirectionState.NONE;

                isPagePermissionCalled = false;

                return;

            }



            try {

                /* make the API call */

                Request request = new Request(session, "/me/accounts", null,

                        HttpMethod.GET, new Request.Callback() {

                            public void onCompleted(Response response) {

                                /* handle the result */

                                Logs.e(TAG, "Response:" + response);

                                if (response.getError() == null) {

                                    Logs.d("Pages",

                                            "Page success"

                                                    + response.getRawResponse());

                                    if (pageListener != null) {

                                        

                                        pageListener.onSuccess(response

                                                .getRawResponse());

                                    }

                                } else {

                                    Logs.d("Pages", "Page error: "

                                            + response.getError()

                                                    .getErrorMessage());

                                    if (pageListener != null) {

                                        pageListener

                                                .onError("Facebook can't retrieve pages");

                                    }

                                }

                            }

                        });



                Bundle requestParams = request.getParameters();

                requestParams.putString("access_token",

                        session.getAccessToken());

                request.setParameters(requestParams);

                request.executeAsync();

            } catch (Exception e) {

                // TODO: handle exception

                if (pageListener != null)

                    pageListener.onError("Facebook can't retrieve pages");

            }

            sFBRedirectionState = FbRedirectionState.NONE;

            getPagesCallback = null;

            isPagePermissionCalled = false;

        } else {

            startLogin();

        }

    }

2.) This method check for permission.
Check user has authorize permission or not.
/**

     * check for user's has taken manage_pages permission

     * 

     * @return

     */

    private static boolean canRetrievePages() {

        Session session = FacebookHelper.getSession();

        if (session != null) {

            try {

                if (!session.isOpened()) {

                    openSession();

                } else {

                    List<String> grantedPermissions = session.getPermissions();

                    String[] publishPermissions = mActivity.getResources()

                            .getStringArray(R.array.fb_advance_permissions);

                    return grantedPermissions.containsAll(Arrays

                            .asList(publishPermissions));

                }

            } catch (FacebookException e) {

                Logs.d(TAG, e);

            } catch (Exception e) {

                Logs.d(TAG, e);

            }

        }

        return false;

    }

3.) Ask user for permission
If user has not authorize permission. we have to authorize user for manage_page permission. We can use below method to ask for permission from user.
    /**

     * ask user for page permission.

     * 

     * @param callback

     */

    public static synchronized void getPagesPermissions(StatusCallback callback) {

        Session session = FacebookHelper.getSession();

        if (session != null) {

            try {

                if (!session.isOpened()) {

                    openSession();

                }

                List<String> grantedPermissions = session.getPermissions();

                List<String> neededPermissions = new ArrayList<String>();

                String[] publishPermissions = mActivity.getResources()

                        .getStringArray(R.array.fb_advance_permissions);

                for (String p : publishPermissions) {

                    if (!grantedPermissions.contains(p)) {

                        neededPermissions.add(p);

                    }

                }

                if (!neededPermissions.isEmpty()) {

                    if (callback != null) {

                        session.removeCallback(callback);

                        session.addCallback(callback);

                    }

                    Session.NewPermissionsRequest newPermissionsRequest = new Session.NewPermissionsRequest(

                            mActivity, neededPermissions);

                    session.requestNewPublishPermissions(newPermissionsRequest);

                }

            } catch (FacebookException e) {

                Logs.e(TAG, e);

            } catch (Exception e) {

                Logs.e(TAG, e);

            }

        }

    }
4.) Post on Fan page in background.
We require page token which is we got from page list data. we get this token from page related data. This token used for publish status on user's page. Page id required on which we want to post data.
/**

     *  This method publish status on fan page

     * @param requestParams - requested param

     * @param uploadListener - for success, failure callback

     */

    public static void postOnFanPage(Bundle requestParams,

            final IFacebookCommonListener<Void> uploadListener) {



        requestParams.putString("access_token",

                Preferences.getFaceBookPageToken());



        Request request = new Request(Session.getActiveSession(),

                Preferences.getFacebookPageId() + "/feed", requestParams,

                HttpMethod.POST, new Request.Callback() {

                    public void onCompleted(Response response) {

                        /* handle the result */

                        if (response != null) {

                            Logs.d(TAG,

                                    "Page: publish reponse:"

                                            + response.toString());



                            FacebookRequestError error = response.getError();

                            if (error != null) {

                                Logs.d(TAG,

                                        "Page: publish Errror:"

                                                + error.getErrorMessage());



                                if (uploadListener != null) {

                                    uploadListener

                                            .onError("Facebook can't publish your content");

                                }



                            } else {



                                if (uploadListener != null) {

                                    uploadListener.onSuccess(null);

                                }



                            }

                        }



                    }

                });

        requestParams.remove("message");

        request.setParameters(requestParams);

        request.executeAsync();

    }
5.) Post on Fan page using feed dialog.
 Some time we need to post on user's fan page using feed dialog. for that we can use below method.

requestParams.putString("access_token",

                             Preferences.getFaceBookPageToken()); 


private static void publishPageFeedDialog(Bundle params) {

        WebDialog feedDialog = (new WebDialog.FeedDialogBuilder(mActivity,

                Session.getActiveSession(), params)).setOnCompleteListener(

                new WebDialog.OnCompleteListener() {

                    @Override

                    public void onComplete(Bundle values,

                            FacebookException error) {

                        if (error != null) {

                            if (!(error instanceof FacebookOperationCanceledException)) {

                                mActivity.informUser(mActivity

                                        .getString(R.string.bback_shared_facebook_failed));

                            }

                            Logs.e("FACEBOOK_ANDROID", "error", error);

                        } else if (values != null

                                && values.containsKey("post_id")) {

                            mActivity.informUser(mActivity

                                    .getString(R.string.bback_shared_facebook_success));

                        }

                    }

                }).setFrom(String.valueOf(Preferences.getFacebookPageId())).build();

        feedDialog.show();

    }

I have put method here from project. So might be some reference class or not there.   
You can get basic idea how we can integrate.


Screen with FanPage list.




References:

https://developers.facebook.com/docs/graph-api/reference/v2.1/page
https://developers.facebook.com/docs/facebook-login/access-tokens#pagetokens https://developers.facebook.com/docs/graph-api/reference/v2.0/user/accounts https://developers.facebook.com/docs/sharing/reference/feed-dialog/v2.1
Please share in comment if you are facing any problem.

Thursday, 16 October 2014

This blog useful for display album list for image and video

Some times we need to display album wise image and video in android application.
I have made one sample example for this functionality.
I would like to share this example.This might be useful too you.

Below Android api used for display album wise images and videos.

Image API:

MediaStore.Images.Media.EXTERNAL_CONTENT_URI;

Video API:
MediaStore.Video.Media.EXTERNAL_CONTENT_URI;


Features included in example:
  • Album list fetch and display with count
  • Video thumbnail display with duration
  • Image and Video thumbnail display for selected album
  • Get selected image/video path





Code Snippets:

1.) This method used for fetch image album list.

    private void getPhotoList() {

       

        String[] PROJECTION_BUCKET = { ImageColumns.BUCKET_ID,

                ImageColumns.BUCKET_DISPLAY_NAME, ImageColumns.DATE_TAKEN,

                ImageColumns.DATA };

      

        String BUCKET_GROUP_BY = "1) GROUP BY 1,(2";

        String BUCKET_ORDER_BY = "MAX(datetaken) DESC";



      

        Uri images = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;



        Cursor cur = getContentResolver().query(images, PROJECTION_BUCKET,

                BUCKET_GROUP_BY, null, BUCKET_ORDER_BY);



     

        GalleryPhotoAlbum album;



        if (cur.moveToFirst()) {

            String bucket;

            String date;

            String data;

            long bucketId;



            int bucketColumn = cur

                    .getColumnIndex(MediaStore.Images.Media.BUCKET_DISPLAY_NAME);



            int dateColumn = cur

                    .getColumnIndex(MediaStore.Images.Media.DATE_TAKEN);

            int dataColumn = cur.getColumnIndex(MediaStore.Images.Media.DATA);



            int bucketIdColumn = cur

                    .getColumnIndex(MediaStore.Images.Media.BUCKET_ID);



            do {

                // Get the field values

                bucket = cur.getString(bucketColumn);

                date = cur.getString(dateColumn);

                data = cur.getString(dataColumn);

                bucketId = cur.getInt(bucketIdColumn);



                if (bucket != null && bucket.length() > 0) {

                    album = new GalleryPhotoAlbum();

                    album.setBucketId(bucketId);

                    album.setBucketName(bucket);

                    album.setDateTaken(date);

                    album.setData(data);

                    album.setTotalCount(photoCountByAlbum(bucket));

                    arrayListAlbums.add(album);

                    // Do something with the values.

                    Log.v("ListingImages", " bucket=" + bucket

                            + "  date_taken=" + date + "  _data=" + data

                            + " bucket_id=" + bucketId);

                }



            } while (cur.moveToNext());

        }

        cur.close();

          } 




2.) This method used for retrieve image count album wise.

    private int photoCountByAlbum(String bucketName) {

        try {

            final String orderBy = MediaStore.Images.Media.DATE_TAKEN;

            String searchParams = null;

            String bucket = bucketName;

            searchParams = "bucket_display_name = \"" + bucket + "\"";



            // final String[] columns = { MediaStore.Images.Media.DATA,

            // MediaStore.Images.Media._ID };

            Cursor mPhotoCursor = getContentResolver().query(

                    MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null,

                    searchParams, null, orderBy + " DESC");



            if (mPhotoCursor.getCount() > 0) {

                return mPhotoCursor.getCount();

            }

            mPhotoCursor.close();

        } catch (Exception e) {

            e.printStackTrace();

        }



        return 0;



    }
 
3.) This method used for retrieve albumwise image list.
private void initPhotoImages(String bucketName) {

        try {

            final String orderBy = MediaStore.Images.Media.DATE_TAKEN;

            String searchParams = null;

            String bucket = bucketName;

            searchParams = "bucket_display_name = \"" + bucket + "\"";



            // final String[] columns = { MediaStore.Images.Media.DATA,

            // MediaStore.Images.Media._ID };

            mPhotoCursor = getContentResolver().query(

                    MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null,

                    searchParams, null, orderBy + " DESC");



            if (mPhotoCursor.getCount() > 0) {



                cursorData = new ArrayList<MediaObject>();



                cursorData.addAll(Utils.extractMediaList(mPhotoCursor,

                        MediaType.PHOTO));         

            }

            // setAdapter(mImageCursor);

        } catch (Exception e) {

            e.printStackTrace();

        }

    }
 
For Video you have to change only video uri in above queries.

You can download source code from Github.