十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
申请应用 AppKey
在顺城等地区,都构建了全面的区域性战略布局,加强发展的系统性、市场前瞻性、产品创新能力,以专注、极致的服务理念,为客户提供做网站、网站建设 网站设计制作按需网站策划,公司网站建设,企业网站建设,品牌网站制作,网络营销推广,外贸营销网站建设,顺城网站建设费用合理。
申请方法:访问友推网站后台,登录后进入应用列表,添加需要集成友推组件的 App,如下图,添加成功后可获取应用的 AppKey。
如何把app分享到微信
2
申请社交平台appkey
集成前您需要为您的应用在各大社交网站的开放平台申请账号并通过审核,否则只能调用系统的分享菜单,无法跟踪分享的回调事件及统计平台
如何把app分享到微信
3
引用youtui库项目
将youtui-lib项目库和应用工程放在同一个目录下
在 Package Explorer 中右键点击工程的根目录,选择 Properties(属性),然后点击,在Android选项点击Add添加youtui-lib
如何把app分享到微信
4
注册需要分享的平台
1.配置各分享平台key,该配置文件为youtui_sdk.xml,配置完放入工程的assets文件夹。
2.如果需要分享到哪个平台就将该平台的Enable属性设置为true.
3.如果需要将某个平台排列到前面,只需要改变它在youtui_sdk.xml文件中的位置即可。
5
各平台需要注意的事项:
新浪微博:
新浪微博需要验证应用签名,请一定要在新浪开放平台管理中心应用信息 - 基本信息 - Android签名包名信息 配置该信息
每次包名变化或者使用的.keystore变化都会导致应用签名变化,请重新到新浪微博开放平台设置。
运行Demo时如果重新编译,因为使用的.keystore文件变化也会导致应用签名变化,导致Demo新浪微博分享无法正常工作,请运行Demo时使用Demo工程包中提供的debug.keystore替换C:\Users\Administrator.android中的debug.keystore文件
微信和朋友圈:
微信和朋友圈也需要验证应用签名,请在微信开放平台管理中心修改应用 - 开发信息配置。
QQ和QQ空间:
QQ和QQ空间使用的是腾讯开放平台api,请在腾讯开放平台申请账号和注册应用,请不要使用QQ互联(用于网站账号登录)的配置,虽然都是腾讯的,但是两个平台并不通用,除了需要在youtui_sdk.xml配置信息,还需要在manifest文件中的android:scheme中的tencent后的一串数字换成自己应用的appid。
?xml version="1.0" encoding="utf-8"?
最后一行配置说明:选用调用系统分享菜单功能
在AndroidManifest.xml 注册权限
在 AndroidManifest.xml 注册需要的Activity
微信和朋友圈回调设置
如果需要分享微信和朋友圈,必需建一个 应用包名+ .wxapi 的包,在该包下建 WXEntryActivity.java,将该类继承cn.bidaround.youtui.wxapi.WXEntryActivity即可(里面不用写代码)
public class WXEntryActivity extends cn.bidaround.youtui.wxapi.WXEntryActivity { }
如图:(将com.xingxinglangtuoche替换成你应用的package名,微信回调会使用到)
如何把app分享到微信
初始化友推
开发者请在自己的程序开始,最好是在MainActivity的onCreate方法调用YtTemplate.init(this)初始化友推sdk,这样友推sdk才能进行后续调用(否则分享等操作会出现空指针异常),例如:
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); YtTemplate.init(this);/初始化友推/ initView(); } 应用退出时:
在您项目的出口Activity的 onDestroy 方法的第一行插入下面的代码 YtTemplate.release(this); 此方法用于释放内存,统计用户使用情况,一旦调用了release,就必须重新调用init才能使用友推的功能,否则会出现空指针异常;
创建 ShareData 实例,调用该实例的set方法设置需要分享的数据: 创建ShareData实例,调用该实例的set方法设置自己需要分享的数据,关于该实例具体内容见下文,如果只是分享应用则只需要设置 setIsAppShare(true) 就可以分享应用在友推后台填写的信息和下载链接。
ShareData 包含的字段:
isAppShare text imagePath imageUrl description title target_url 判断是否为分享应用 待分享的文字,短信要小于70个字符,微博要小于140个字符,如果需要分享链接,最好将链接url放在最后 待分享的本地图片地址,分享图片的话需要在本地和网络图片中选一,如果都有则优先分享本地图片 待分享网络图片url,分享图片的话需要在本地和网络图片中选一,如果都有则优先分享本地图片 待分享内容的描述 待分享内容的标题 待分享内容的跳转链接
通过创建该类实例,调用实例的set方法设置这些参数,例如:
ShareData shareData = new ShareData(); shareData.isAppShare = false;//设置为true则分享的信息从友推后台填写的应用信息中读取,可动态更新,后面的值不用设置。 shareData.setDescription("友推积分组件"); shareData.setTitle("友推分享"); shareData.setText("通过友推积分组件,开发者几行代码就可以为应用添加分享送积分功能,并提供详尽的后台统计数据,除了本身具备的分享功能外,开发者也可将积分功能单独集成在已有分享组件的app上,");
shareData.setTarget_url("");
shareData.setImageUrl("");
shareData.setImagePath("");
各个平台分享数据的限制和注意事项:
因为各个平台的分享限制,请分享时尽量分享图片+链接,依靠链接来了解更多信息
1) 微信 朋友圈 微信分享为linkcard形式,超出的文字部分不会显示
2) 新浪微博 很低版本的新浪微博不支持发多类型微博,进行图文分享时只会分享图片,新浪微博分享消息最长为140字
3) QQ、QQ空间 QQ分享的消息最长40字,分享的标题最长30字,多余的部分将被忽略,description将被忽略 QQ空间分享的消息最长200字,分享的标题最长600字,多余的部分将被忽略,description将被忽略
4) 腾讯微博 只有image(imagePath或imageUrl)和text被分享,其他字段忽略,腾讯微博分享消息最长为140字
5) 人人网 只有image(imagePath或imageUrl)和text被分享,其他字段忽略
6) 短信 只有text被分享,其他字段忽略
7) 邮件 只有text被分享,其他字段忽略
如何把app分享到微信
调用友推分享推荐组件
为应用添加一个分享推荐按钮,如:
如何把app分享到微信
在分享按钮事件中调用youtui的组件即可,示例代码:
public void onClick(View v) { if(v.getId()==R.id.popup_bt)
{ /调用友推分享推荐组件,YouTuiViewType类的常量为分享样式参数,目前支持白色列表和黑色网格两种/ /创建分享的模板,第一个参数为activity,第二个参数为分享窗口样式,第三个参数为是否需要积分/
YtTemplate blackTemp = new YtTemplate(this, YouTuiViewType.BLACK_POPUP,false); //黑色网格样式不需要积分活动 /YtTemplate blackTemp = new YtTemplate(this, YouTuiViewType.WHITE_LIST,ture);/ //白色列表样式需要积分活动
ShareData shareData = new ShareData();
shareData.isAppShare = false;//设置为true则分享的信息从友推后台填写的应用信息中读取,可动态更新后面的值不用设置。
shareData.setDescription("友推积分组件");
shareData.setTitle("友推分享");
shareData.setText("通过友推积分组件,开发者几行代码就可以为应用添加分享送积分功能,并提供详尽的后台统计数据,除了本身具备的分享功能外,开发者也可将积分功能单独集成在已有分享组件的app上,快来试试吧 ");
shareData.setTarget_url("");
shareData.setImageUrl("");
shareData.setImagePath("");
blackTemp.setShareData(shareData);//设置默认的分享数据;shareData 设置参看4.6
//**如果要为某个平台设置不一样的分享信息。则单独设置*/ //blackTemp.addData(YtPlatform.PLATFORM_QQ, shareData); //调出分享窗口 blackTemp.show();
//如果需要自定义分享事件,可以创建监听事件,然后在回调中处理 YtShareListener listener1 = new YtShareListener() {
@Override
public void onSuccess(ErrorInfo arg0)
{
}
@Override public void onPreShare()
{
}
@Override
public void onError(ErrorInfo arg0)
{
}
@Override
public void onCancel() {
}
};//给新浪微博添加分享监听 blackTemp.addListener(YtPlatform.PLATFORM_SINAWEIBO, listener1);
//给QQ添加分享监听 //
blackTemp.addListener(YtPlatform.PLATFORM_QQ, listener2); }
你好,调用微信js最简单的办法,就是在java代码调用微信的Android SDK(具体用法看微信开发品台的示例,很简单), 在js里使用jsb.reflection调用你的java方法。IOS也一样。
有JAVA的,你参考一下
主要思路
从UI获取文本信息是最为简单的方法,于是应该优先逆向UI代码部分。
逆向微信apk
首先解包微信apk,用dex2jar反编译classes.dex,然后用JD-GUI查看jar源码。当然,能看到的源码都是经过高度混淆的。但是,继承自安卓重要组件(如Activity、Service等)的类名无法被混淆,于是还是能从中看到点东西。
首先定位到微信APP package。我们知道这个是 com.tencent.mm
。
在 com.tencent.mm
中,我们找到一个 ui
包,有点意思。
展开 com.tencent.mm.ui
,发现多个未被混淆的类,其中发现 MMBaseActivity
直接继承自 Activity
, MMFragmentActivity
继承自 ActionBarActivity
, MMActivity
继承自 MMFragmentActivity
,并且 MMActivity
是微信中大多数Activity的父类:
public class MMFragmentActivity
extends ActionBarActivity
implements SwipeBackLayout.a, b.a {
...
}
public abstract class MMActivity
extends MMFragmentActivity {
...
}
public class MMBaseActivity
extends Activity {
...
}
现在需要找出朋友圈的Activity,为此要用Xposed hook MMActivity
。
创建一个Xposed模块
参考 [TUTORIAL]Xposed module devlopment
,创建一个Xposed项目。
简单Xposed模块的基本思想是:hook某个APP中的某个方法,从而达到读写数据的目的。
小编尝试hook com.tencent.mm.ui.MMActivity.setContentView
这个方法,并打印出这个Activity下的全部TextView内容。那么首先需要遍历这个Activity下的所有TextView,遍历ViewGroup的方法参考了SO的以下代码:
private void getAllTextViews(final View v) {
if (v instanceof ViewGroup) {
ViewGroup vg = (ViewGroup) v;
for (int i = 0; i vg.getChildCount(); i++) {
View child = vg.getChildAt(i);
getAllTextViews(child);
}
} else if (v instanceof TextView ) {
dealWithTextView((TextView)v); //dealWithTextView(TextView tv)方法:打印TextView中的显示文本
}
}
Hook MMActivity.setContentView
的关键代码如下:
findAndHookMethod("com.tencent.mm.ui.MMActivity", lpparam.classLoader, "setContentView", View.class, new XC_MethodHook() {
...
});
在findAndHookMethod方法中,第一个参数为完整类名,第三个参数为需要hook的方法名,其后若干个参数分别对应该方法的各形参类型。在这里, Activity.setContentView(View view)
方法只有一个类型为 View
的形参,因此传入一个 View.class
。
现在,期望的结果是运行时可以从Log中读取到每个Activity中的所有的TextView的显示内容。
但是,因为View中的数据并不一定在 setContentView()
时就加载完毕,因此小编的实验结果是,log中啥都没有。
意外的收获
当切换到朋友圈页面时,Xposed模块报了一个异常,异常源从 com.tencent.mm.plugin.sns.ui.SnsTimeLineUI
这个类捕捉到。从类名上看,这个很有可能是朋友圈首页的UI类。展开这个类,发现更多有趣的东西:
这个类下有个子类 a
(被混淆过的类名),该子类下有个名为 gyO
的 ListView
类的实例。我们知道, ListView
是显示列表类的UI组件,有可能就是用来展示朋友圈的列表。
顺藤摸瓜
那么,我们先要获得一个 SnsTimeLineUI.a.gyO
的实例。但是在这之前,要先获得一个 com.tencent.mm.plugin.sns.ui.SnsTimeLineUI.a
的实例。继续搜索,发现 com.tencent.mm.plugin.sns.ui.SnsTimeLineUI
有一个名为 gLZ
的 SnsTimeLineUI.a
实例,那么我们先取得这个实例。
经过测试, com.tencent.mm.plugin.sns.ui.SnsTimeLineUI.a(boolean, boolean, String, boolean)
这个方法在每次初始化微信界面的时候都会被调用。因此我们将hook这个方法,并从中取得 gLZ
。
findAndHookMethod("com.tencent.mm.plugin.sns.ui.SnsTimeLineUI", lpparam.classLoader, "a", boolean.class, boolean.class, String.class, boolean.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
XposedBridge.log("Hooked. ");
Object currentObject = param.thisObject;
for (Field field : currentObject.getClass().getDeclaredFields()) { //遍历类成员
field.setAccessible(true);
Object value = field.get(currentObject);
if (field.getName().equals("gLZ")) {
XposedBridge.log("Child A found.");
childA = value;
//这里获得了gLZ
...
}
}
}
});
现在取得了 SnsTimeLineUI.a
的一个实例 gLZ
,需要取得这个类下的 ListView
类型的 gyO
属性。
private void dealWithA() throws Throwable{
if (childA == null) {
return;
}
for (Field field : childA.getClass().getDeclaredFields()) { //遍历属性
field.setAccessible(true);
Object value = field.get(childA);
if (field.getName().equals("gyO")) { //取得了gyO
ViewGroup vg = (ListView)value;
for (int i = 0; i vg.getChildCount(); i++) { //遍历这个ListView的每一个子View
...
View child = vg.getChildAt(i);
getAllTextViews(child); //这里调用上文的getAllTextViews()方法,每一个子View里的所有TextView的文本
...
}
}
}
}
现在已经可以将朋友圈页面中的全部文字信息打印出来了。我们需要根据TextView的子类名判断这些文字是朋友圈内容、好友昵称、点赞或评论等。
private void dealWithTextView(TextView v) {
String className = v.getClass().getName();
String text = ((TextView)v).getText().toString().trim().replaceAll("\n", " ");
if (!v.isShown())
return;
if (text.equals(""))
return;
if (className.equals("com.tencent.mm.plugin.sns.ui.AsyncTextView")) {
//好友昵称
...
}
else if (className.equals("com.tencent.mm.plugin.sns.ui.SnsTextView")) {
//朋友圈文字内容
...
}
else if (className.equals("com.tencent.mm.plugin.sns.ui.MaskTextView")) {
if (!text.contains(":")) {
//点赞
...
} else {
//评论
...
}
}
}
自此,我们已经从微信APP里取得了朋友圈数据。当然,这部分抓取代码需要定时执行。因为从 ListView
中抓到的数据只有当前显示在屏幕上的可见部分,为此需要每隔很短一段时间再次执行,让用户在下滑加载的过程中抓取更多数据。
剩下的就是数据分类处理和格式化输出到文件,受本文篇幅所限不再赘述,详细实现可参考作者GitHub上的源码。
这个调用第三方接口,如果是在微信中,那就需要调用微信的jssdk