记授权登录和支付拉起功能开发(非SDK)
一. 功能需求
需求:模仿支付宝授权登录效果,实现支付App跟商城App的交互,授权使用auth2.0模式,流程大概如下

二. 开工
经过找资料,android App之间相互唤醒有很多种方式,详情看www.jb51.net/article/158…,这几种方式的基本数据搬运工都是Intent,所以相互唤醒App之间通过Intent传递数据,如果使用广播 8.0以上有限制,要注意数据传输安全加密。 在开发过程中,发现蛮多坑,在阅读Google开发文档的时候发现,谷歌建议应用间交互使用隐式Intent的方式developer.android.com/guide/compo… 所以,这次开发使用隐式Intent方式做唤醒功能。
唤醒端代码:
private String mUri = "http://com.comp.pay/sign";
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setData(Uri.parse(mUri));//参数拼接在URI后面
intent.putExtra("type", "third_login");//这里Intent传值
intent.putExtra("appId", "");
intent.putExtra("result_activity", "com.xiaozhai.merchant.AgentPayActivity");
intent.putExtra("application_id", BaseApp.getApplication().getPackageName());
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// Always use string resources for UI text.
// This says something like "Share this photo with"
String title = getResources().getString(R.string.text_tips);
// Create intent to show chooser
Intent chooser = Intent.createChooser(intent, title);
// Verify the intent will resolve to at least one activity
if (intent.resolveActivity(getPackageManager()) != null) {//判断手机能是否有能响应的Intent
startActivity(chooser);
}
启动的时候注意看需求是否要取消页面切换效果,控制不好可能会造成切换的时候看着想启动闪屏。
被唤醒端App处理:
1.清单文件入口Activity注册的位置写好uri协议 的intent-filter
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data
android:host="com.comp.pay"
android:path="/sign"
android:scheme="http" />
</intent-filter>
2.返回结果
private void setResult(String result, String data) {
// Intent intent = getPackageManager().getLaunchIntentForPackage("");
Intent intent = new Intent();
if (intent != null) {
//不指定activity会导致agent Main启动异常 先这么处理
ComponentName componentName = new ComponentName(mPackName, mResultActivity);
intent.setComponent(componentName);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
intent.putExtra("result_type", "result_auth");
intent.putExtra("result_status", result);
intent.putExtra("data", data);//这里Intent传值
finish();
startActivity(intent);
moveTaskToBack(true);
}
}
当然结果返回也可以使用scheme方式,什么用着方便用什么,mResultActivity是发起唤醒的商城接收结果的透明Activity,至于处理数据就是商城端的事情了,数据返回后记得moveTaskToBack(),该方法可以让App不改变任务栈顺序进入后台,相当于Home键。这样在拉起授权返回结果后,不会导致商城任务栈错乱(在开发过程中发现一个坑,如果只是关闭Activity启动商城的结果页,需要商城那边的结果页设置启动模式为singleTask,这样显然很不好,不止这样,哪怕能回到商城的Task,也有个很奇怪的现象,被唤醒App的任务栈莫名其妙地跑到了唤醒App的最下面,导致唤醒App不能正常关闭,关闭后会再次打开被唤醒App的Task,具体原因,能力有限,未知),在找到这个方法之前,为了达到某宝的先拉起App在授权或者支付的效果,搞得头都大。
接收结果的页面处理就写了,看情况处理就好。
相互唤醒的时候最好把发起唤醒请求的页面的关闭动画取消
/**
* @param exitAnim //退出时的动画对应的资源id,设置0,不播放任何动画
*/
@Override
public void overridePendingTransition(int enterAnim, int exitAnim) {
super.overridePendingTransition(enterAnim, 0);
}
end.