Xamarin.Android 项目接入微信登录授权的SDK。
可以在NuGet下搜Xamarin.Android.WeChatOpenSDK包,目前最新的是5.4.0
引入包很方便。而且是微信官方出的包。
接下就是注册等等。网上代码很多,跟java的代码也都差不多,除了个别方法名需要大些外。基本以Ctr+C 然后Ctr+v了。
只是再编写回调响应类WXEntryActivity的时候,遇到微信也启动了,也点击授权了,就是没有反应
查了不少资料,都是针对Android代码的。问题代码贴出来给大家看看,从微信Android Demo转换过来的,基本跟上C#编写的java代码,如下:
using Android.App;
using Android.Content;
using Android.OS;
using Android.Util;
using Android.Widget;
using Com.Tencent.MM.Opensdk.Constants;
using Com.Tencent.MM.Opensdk.Modelbase;
using Com.Tencent.MM.Opensdk.Modelmsg;
using Com.Tencent.MM.Opensdk.Openapi;
using DKB.P2PLive.AndroidAPP.Code.Business;
using Org.Json;
using System;
using Exception = Java.Lang.Exception;
namespace AndroidAPP.wxapi
{
[Activity(Label = "@string/app_name", Exported = true, LaunchMode = Android.Content.PM.LaunchMode.SingleTask, TaskAffinity = "AndroidAPP")]
public class WXEntryActivity : Activity, IWXAPIEventHandler
{
private string TAG = "MyHandler";
private MyHandler handler;
private IWXAPI api;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
api = WXAPIFactory.CreateWXAPI(this, GlobalData.WX_APPID, false);
handler = new MyHandler(this);
try
{
Intent intent = this.Intent;
bool b = api.HandleIntent(intent, this);
}
catch (Exception e)
{
Log.Error(TAG, e.StackTrace);
}
}
public new void Dispose()
{
this.Dispose();
}
protected void onNewIntent(Intent intent)
{
base.OnNewIntent(intent);
this.Intent = intent;
api.HandleIntent(intent, this);
}
// 微信发送请求到第三方应用时,会回调到该方法
public void OnReq(BaseReq req)
{
switch (req.Type)
{
case ConstantsAPI.CommandGetmessageFromWx:
break;
case ConstantsAPI.CommandShowmessageFromWx:
break;
default:
break;
}
}
// 第三方应用发送到微信的请求处理后的响应结果,会回调到该方法
public void OnResp(BaseResp resp)
{
int result = 0;
Toast.MakeText(this, "baseresp.getType = " + resp.Type, ToastLength.Long).Show();
//成功后发送请求
switch (resp.errCode)
{
//ERR_OK = 0(用户同意) ERR_AUTH_DENIED = -4(用户拒绝授权) ERR_USER_CANCEL = -2(用户取消)
case BaseResp.ErrCode.ErrOk:
result = Resource.String.errcode_success;
string code = ((SendAuth.Resp)resp).Code;//需要转换一下才可以
break;
case BaseResp.ErrCode.ErrUserCancel:
result = Resource.String.errcode_cancel; // 发送取消
break;
case BaseResp.ErrCode.ErrAuthDenied:
result = Resource.String.errcode_deny; // 发送被拒绝
break;
case BaseResp.ErrCode.ErrUnsupport:
result = Resource.String.errcode_unsupported; // 不支持错误
break;
default:
result = Resource.String.errcode_unknown; // 发送返回
break;
}
Toast.MakeText(this, GetString(result) + ", type=" + resp.Type, ToastLength.Long).Show();
}
class MyHandler : Handler
{
private string TAG = "MyHandler";
private WeakReference<WXEntryActivity> wxEntryActivityWeakReference;
public MyHandler(WXEntryActivity wxEntryActivity)
{
wxEntryActivityWeakReference = new WeakReference<WXEntryActivity>(wxEntryActivity);
}
public void handleMessage(Message msg)
{
int tag = msg.What;
switch (tag)
{
case NetworkUtil.GET_TOKEN:
Bundle data = msg.Data;
JSONObject json = null;
try
{
json = new JSONObject(data.GetString("result"));
string openId, accessToken, refreshToken, scope;
openId = json.GetString("openid");
accessToken = json.GetString("access_token");
refreshToken = json.GetString("refresh_token");
scope = json.GetString("scope");
WXEntryActivity wxentry;
wxEntryActivityWeakReference.TryGetTarget(out wxentry);
Intent intent = new Intent(wxentry, typeof(LoginActivity));
intent.PutExtra("openId", openId);
intent.PutExtra("accessToken", accessToken);
intent.PutExtra("refreshToken", refreshToken);
intent.PutExtra("scope", scope);
wxentry.StartActivity(intent);
}
catch (JSONException ex)
{
Log.Error(TAG, ex.Message);
}
break;
}
}
}
}
}
百度了不少,始终没解决。
后来一篇文章提到,AndroidManifest 中注册Activity的要类及包名要写全,xxx.xx.wxapi.WXEntryActivity 回头看自己代码发现
[Activity(Label = "@string/app_name", Exported = true, LaunchMode = Android.Content.PM.LaunchMode.SingleTask, TaskAffinity = "AndroidAPP")] 中只设置了Label没有设置Name
所以不能回调的原因基本就是activity没有设置Name参数,导致注册失败
解决办法就是加上Name属性,正确代码如下:
[Activity(Name = "androidapp.wxapi.WXEntryActivity", Label = "@string/app_name", Exported = true, LaunchMode = Android.Content.PM.LaunchMode.SingleTask, TaskAffinity = "AndroidAPP")]
总结一下:
主要问题,还是对Xamarin 下的代码结构不熟悉。由于是第一次从AS java代码转到VS C# 的代码开发。所以对Xamarin框架不熟悉,导致踩坑无数。