[Windows Phone]解决人人网SDK上传照片失败问题
本文纯属本人粗心所致
人人SDK For Window PHone调用一键上传照片,按照官方提供的文档
private void btn_share_renren_Click(object sender, EventArgs e) { api = new RenrenAPI(AppID, AppKey, AppSecret); if (api.IsAccessTokenValid() == false) { api.Login(this, renren_LoginCompletHandler); } else { Stream stream = App.GetResourceStream( new Uri("Background.png", UriKind.Relative)).Stream; BitmapImage bitmap = new BitmapImage(); bitmap.SetSource(stream); api.PublishPhotoSimple(bitmap, "test", "test"); } }
出现上传失败,也不提示任何错误代码,无奈只好查看源代码
经调试,找到错误代码为202:需要用户授予[photo_upload]权限,上网查了一下,原来是OAuth授权的时候缺少权限设置
官方文档中说明
默认情况下,会要求用户授予用于访问基本信息的权限,例如用户公共信息、好友关系等。如果应用需要的权限超过基本信息权限,就需要要求用户授予深层次的权限。这个过程是通过添加人人OAuth 2.0 'scope'请求参数实现的: scope:非必须参数。以空格分隔的权限列表,若不传递此参数,代表请求用户的默认权限。全部权限请参考'权限列表'。 下面的例子展示了如何要求用户授予访问用户的相册、新鲜事的权限: https://graph.renren.com/oauth/authorize? client_id=YOUR_API_KEY&redirect_uri=YOUR_CALLBACK_URL&response_type=code&scope=ScopeCode+ScopeCode ScopeCode是权限对应的代码,如下 获取信息类权限 权限 描述 read_user_blog 获取用户日志时需要用户授予的权限。 read_user_checkin 获取用户报到信息时需要用户授予的权限。 read_user_feed 获取用户新鲜事时需要用户授予的权限。 read_user_guestbook 获取用户留言板时需要用户授予的权限。 read_user_invitation 获取用户被邀请的状况时需要用户授予的权限。 read_user_like_history 获取用户喜欢的历史信息时需要用户授予的权限。 read_user_message 获取用户站内信时需要用户授予的权限。 read_user_notification 获取用户已收到的通知时需要用户授予的权限。 read_user_photo 获取用户相册相关信息时需要用户授予的权限。 read_user_status 获取用户状态相关信息时需要用户授予的权限。 read_user_album 获取用户相册相关信息时需要用户授予的权限。 read_user_comment 获取用户评论相关信息时需要用户授予的权限。 read_user_share 获取用户分享相关信息时需要用户授予的权限。 read_user_request 获取用户好友请求、圈人请求等信息时需要用户授予的权限。 发布信息类权限 权限 描述 publish_blog 以用户身份发布日志时需要用户授予的权限。 publish_checkin 以用户身份发布报到时需要用户授予的权限。 publish_feed 以用户身份发送新鲜事时需要用户授予的权限。 publish_share 以用户身份发送分享时需要用户授予的权限。。 write_guestbook 以用户身份进行留言时需要用户授予的权限。 send_invitation 以用户身份发送邀请时需要用户授予的权限。 send_request 以用户身份发送好友申请、圈人请求等时需要用户授予的权限。 send_message 以用户身份发送站内信时需要用户授予的权限。 send_notification 以用户身份发送通知(user_to_user)时需要用户授予的权限。 photo_upload 以用户身份上传照片时需要用户授予的权限。 status_update 以用户身份发布状态时需要用户授予的权限。 create_album 以用户身份发布相册时需要用户授予的权限。 publish_comment 以用户身份发布评论时需要用户授予的权限。 operate_like 以用户身份执行喜欢操作时需要用户授予的权限。 其他权限 权限 描述 admin_page 以用户的身份,管理其可以管理的公共主页的权限。
源代码中
RenrenAPI.Login()有+3重重载,分别为
/// <summary> /// 用户名密码方式,无权限 /// </summary> /// <param name="username">用户名</param> /// <param name="password">密码</param> /// <param name="callback">回调</param> public void LogIn(string username, string password, LoginCompletedHandler callback)
/// <summary> /// 用户名密码方式,有权限 /// </summary> /// <param name="username">用户名</param> /// <param name="password">密码</param> /// <param name="scope">权限列表</param> /// <param name="callback">回调</param> public void LogIn(string username, string password, List<string> scope, LoginCompletedHandler callback) /// <summary> /// 登录,页面方式,无权限设置 /// </summary> /// <param name="page">当前显示页面</param> /// <param name="redirectUri">转向</param> /// <param name="callback">回调</param> public void LogIn(PhoneApplicationPage page, string redirectUri, LoginCompletedHandler callback) /// <summary> /// 登录,页面方式,有权限设置 /// </summary> /// <param name="page">当前显示页面</param> /// <param name="scope">权限列表</param> /// <param name="redirectUri">转向</param> /// <param name="callback">回调</param> public void LogIn(PhoneApplicationPage page, List<string> scope, string redirectUri, LoginCompletedHandler callback)
我们调用的是第三重载
api.Login(this, renren_LoginCompletHandler);//redirect_Uri在SDK中已设置
而第三重载内部是调用第四重载
/// <summary> /// 登录,页面方式,无权限设置 /// </summary> /// <param name="page">当前显示页面</param> /// <param name="redirectUri">转向</param> /// <param name="callback">回调</param> public void LogIn(PhoneApplicationPage page, string redirectUri, LoginCompletedHandler callback) { LogIn(page, null, redirectUri, callback); }
第四重载
/// <summary> /// 登录,页面方式,有权限设置 /// </summary> /// <param name="page">当前显示页面</param> /// <param name="scope">权限列表</param> /// <param name="redirectUri">转向</param> /// <param name="callback">回调</param> public void LogIn(PhoneApplicationPage page, List<string> scope, string redirectUri, LoginCompletedHandler callback) { if (loginViewBS == null) { loginViewBS = new LoginViewBS(); } loginViewBS.CleanLoginEvent(); loginViewBS.LoginCompleted += callback; loginViewBS.InitView(page); loginViewBS.Login(redirectUri, scope); }
最后一行 loginViewBS.Login(redirectUri, scope);的定义如下
public void Login(string redirect_uri, List<string> scope) { if (redirect_uri == null) { return; } string uri = ConstantValue.LoginAuth; uri += "client_id=" + ConstantValue.ApiKey + "&" + "response_type=token"; if (scope != null && scope.Count > 0) { string[] arrScope = scope.ToArray<string>(); string scopeString = String.Join(" ", arrScope); uri += "&" + "scope=" + scopeString; } uri += "&" + "redirect_uri=" + redirect_uri + "&display=touch"; if (browserControl != null) { browserControl.SetUri(uri); browserControl.LoadCompleted -= new BrowserControl.LoadCompletedEventHandler(RenrenBrowser_LoadCompleted); browserControl.LoadCompleted += new BrowserControl.LoadCompletedEventHandler(RenrenBrowser_LoadCompleted); } else { return; } }
第三重载传进来的scope是null,导致OAuth授权的url中没有scope参数
看到这里,问题该怎么解决已经很明显-了,
List<string> scope = new List<string>() { "photo_upload" }; api.Login(this,scope, renren_LoginCompletHandler);
刚刚重新看了一SDK文档,其中有提到设置权限,
唉,怪我粗心呢还是文档说的不够明白