最近公司需要做一个SDK,该SDK为其他的APP可以调用我们的APP,然后通过获取我们的APP获取用户信息,返回给他们一个唯一的授权码。

说白了就是弄一个第三方登陆功能,通过登陆我们的用户中心,给他们一个用户标识。

这个SDK需要分解开来做,需要实现下面功能:


      可以检测我们的APP是否已经安装


      能够把我们给他们的APPID和APPKEY标识在跳转到我们APP的时候带过来


      可以处理在我们这边登录后的返回信息 


           1.取消登录


            2.登录成功--返回用户信息


            3.发生其他错误




而我们的APP同时也要提供这个功能:


        从别的APP跳转过来的时候,判断是否是请求用户登录(提供登录界面)


        根据用户行为返回特定信息给对方的APP



进展步骤:




        1.获取某个应用是否安装的代码:


             

public static boolean checkApkExist(Context context, String packageName) {
		if (packageName == null || "".equals(packageName)) {
			return false;
		}
		try {
			context.getPackageManager().getApplicationInfo(packageName,
					PackageManager.GET_UNINSTALLED_PACKAGES);
			return true;
		} catch (NameNotFoundException e) {
			return false;
		}
	}


2.应用之间跳转(并且带参数):


         从A跳转到B的代码是:


       

<span >		</span>ComponentName comp = new ComponentName("com.nbg.baby", 
		"com.nbg.baby.ApiLoginActivity"); 
		
		Intent intent = new Intent();
		intent.setComponent(comp);	 
		intent.setAction(Intent.ACTION_VIEW); 
		Bundle bundle = new Bundle(); 
		bundle.putString("extra", "extra.login"); 
		intent.putExtras(bundle); 
		
		if(Utils.checkApkExist(MainActivity.this, "com.nbg.baby")){
			startActivityForResult(intent, 1);
		}else{
			Toast.makeText(MainActivity.this, "应用未安装,无法跳转", Toast.LENGTH_SHORT).show();
		}</span>


A中接受B中返回数据:

@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {	
		if(requestCode ==1){
			String result = data.getStringExtra("result");
			Toast.makeText(this, result, Toast.LENGTH_SHORT).show();;
		}
	}


B中处理正常处理从A传过来数据即可。但是有一点要注意,B的ApiActivity属性,一定要设置:android:exported="true",否则会报错,权限被拒绝!



3.数据传输加密


延续2中叫法,A和B。在B中,要有我们提供给他们的appid和appkey,并且appid和appkey是成对出现,同时要把A的包名传过去,进行加密。在B中对加密的数据进行解密,确认,确实是从我们这边分配的appid和appkey,然后B中进行账号处理,返回一个唯一的openid给A,同时也把账号昵称和头像等数据传过去。




4.制作SDK


前面3个步骤都是准备工作,真正要制作SDK,还是从这一步开始,制作的SDK会导出为jar包,它的主要作用就是负责把A跳转到B之前的准备工作都做好已经处理从B中返回的数据。



该类的实现:


public class YoYo {
	
	 private static YoYo sInstance;
	 private IUiListener listener;
	 
	 private YoYo(String appId, Context context)
	 {
		 
	 }
	 
	 public static synchronized YoYo createInstance(String appId, Context context)
	 {
		 if(sInstance==null){
			 sInstance= new YoYo(appId, context);
		 }
		 return sInstance;
	 }
	 
	 public void login(Activity context, IUiListener callBack)
	 {
		ComponentName comp = new ComponentName("com.nbg.baby", 
					"com.nbg.baby.ApiLoginActivity"); 
					
		Intent intent = new Intent();
		intent.setComponent(comp);	 
		intent.setAction(Intent.ACTION_VIEW); 
		Bundle bundle = new Bundle(); 
		bundle.putString("extra", "我来自星星"); 
		intent.putExtras(bundle);
		context.startActivityForResult(intent, 1);
		this.listener = callBack;
		
	 }
	 public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
		 if(requestCode ==1){
				if(resultCode == Activity.RESULT_CANCELED){
					String result = data.getStringExtra("result");
					UiError e = new UiError(0, "取消登陆", "用户取消");
					this.listener.onError(e);
				}else{
					String result = data.getStringExtra("nickname");
					
					JSONObject object = new JSONObject();
					try {
						object.put("昵称", result);
						this.listener.onComplete(object);
					} catch (JSONException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		 return false;
	 }
}






public interface IUiListener {
	
	  public abstract void onComplete(Object response);
	  
	 
	  public abstract void onError(UiError e);
	  
	 
	  public abstract void onCancel();
}



3.打包输出sdk的jar包





5.SDK的使用


sdk打包成jar包之后,就可以给别的应用使用了,给他们分配一个appid,然后把jar发给他们,在他们的项目里面,只要把YoYo类创建,实现IUiListener接口,最后在他们的activity中的onactivityresult函数中调用yoyo.onactivityresult()就可以了(这一步骤千万不能忘!)






PS:本SDK是参照QQ第三方登陆的SDK说明文档做的,完全仿照他们的接口调用方式进行。QQ第三方登陆安卓版的地址:http://wiki.connect.qq.com/%E4%BD%BF%E7%94%A8sdk%E5%AE%9E%E7%8E%B0qq%E7%9A%84%E7%99%BB%E5%BD%95%E5%92%8C%E6%B3%A8%E9%94%80_android_sdk