Android移动开发-在Android应用里集成QQ分享的实现
2017-11-01 13:56
573 查看
QQ分享分为QQ好友分享与QQ空间分享同属QQ互联平台上的QQ分享,该QQ互联的网址为:https://connect.qq.com/ 。然后在该网址里申请开发者应用id。
创建工程并配置工程
新建工程并导入SDK的jar文件(SDK下载地址)
创建一个工程,并把open-sdk.jar文件拷贝到libs目录下并依赖到项目工程里,如下图所示:
配置AndroidManifest
在应用的AndroidManifest.xml增加配置的节点下增加以下配置(注:不配置将会导致无法调用API);
通过以上两个步骤,工程就已经配置完成了。接下来就可以在代码里使用QQ互联的SDK进行开发了。
layout/activity_share_qq.xml界面布局代码如下:
layout/dialog_share.xml界面布局代码如下:
ShareQQActivity.java逻辑代码如下:
ShareGridAdapter.java逻辑代码如下:
ShareGridDialog.java逻辑代码如下:
注意:由于该程序不仅需要访问网络,而且还要启动QQ。因此还需要在清单文件AndroidManifest.xml文件中授权该程序访问网络、QQ、QQ空间所需权限的权限:
Demo程序运行效果界面截图如下:
Demo程序源码下载地址一(GitHub)
Demo程序源码下载地址二(Gitee)
创建工程并配置工程
新建工程并导入SDK的jar文件(SDK下载地址)
创建一个工程,并把open-sdk.jar文件拷贝到libs目录下并依赖到项目工程里,如下图所示:
配置AndroidManifest
在应用的AndroidManifest.xml增加配置的节点下增加以下配置(注:不配置将会导致无法调用API);
<!-- QQ登录鉴权页面 --> <activity android:name="com.tencent.tauth.AuthActivity" android:launchMode="singleTask" android:noHistory="true"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="填写tencent你的AppId" /> </intent-filter> </activity> <activity android:name="com.tencent.connect.common.AssistActivity" android:configChanges="orientation|keyboardHidden|screenSize" android:screenOrientation="portrait" android:theme="@android:style/Theme.Translucent.NoTitleBar" />
通过以上两个步骤,工程就已经配置完成了。接下来就可以在代码里使用QQ互联的SDK进行开发了。
layout/activity_share_qq.xml界面布局代码如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="5dp" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="5dp" android:orientation="horizontal" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="分享标题:" android:textColor="@color/black" android:textSize="17sp" /> <EditText android:id="@+id/et_share_title" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:padding="5dp" android:background="@drawable/editext_selector" android:text="CSDN博客分享" android:textColor="@color/black" android:textSize="17sp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="5dp" android:orientation="horizontal" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="分享内容:" android:textColor="@color/black" android:textSize="17sp" /> <EditText android:id="@+id/et_share_content" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:padding="5dp" android:background="@drawable/editext_selector" android:text="哈哈,这是我的CSDN博客地址" android:textColor="@color/black" android:textSize="17sp" /> </LinearLayout> <Button android:id="@+id/btn_share_qq" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:text="分享到QQ" android:textColor="@color/black" android:textSize="17sp" /> </LinearLayout>
layout/dialog_share.xml界面布局代码如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/white" android:orientation="vertical" > <GridView android:id="@+id/gv_share_channel" android:layout_width="match_parent" android:layout_height="wrap_content" android:horizontalSpacing="0dp" android:verticalSpacing="0dp" android:listSelector="@null" android:numColumns="4" android:paddingTop="10dp" android:paddingBottom="10dp" android:stretchMode="columnWidth" /> <TextView android:id="@+id/tv_share_cancel" android:layout_width="match_parent" android:layout_height="40dp" android:gravity="center" android:background="@color/blue_light" android:text="取 消" android:textColor="@color/black" android:textSize="17sp" /> </LinearLayout>
ShareQQActivity.java逻辑代码如下:
package com.fukaimei.shareqq; import com.fukaimei.shareqq.adapter.ShareGridAdapter; import com.fukaimei.shareqq.widget.ShareGridDialog; import com.tencent.connect.common.Constants; import com.tencent.tauth.Tencent; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.EditText; public class ShareQQActivity extends AppCompatActivity implements OnClickListener { private static final String TAG = "ShareQQActivity"; private EditText et_share_title; private EditText et_share_content; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_share_qq); et_share_title = (EditText) findViewById(R.id.et_share_title); et_share_content = (EditText) findViewById(R.id.et_share_content); findViewById(R.id.btn_share_qq).setOnClickListener(this); } @Override public void onClick(View v) { if (v.getId() == R.id.btn_share_qq) { ShareGridDialog dialog = new ShareGridDialog(this, null); dialog.setUrl("http://blog.csdn.net/fukaimei"); dialog.setTitle(et_share_title.getText().toString()); dialog.setContent(et_share_content.getText().toString()); dialog.setImgUrl(""); dialog.show(); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { Log.d(TAG, "-->onActivityResult " + requestCode + " resultCode=" + resultCode); if (requestCode == Constants.REQUEST_LOGIN || requestCode == Constants.REQUEST_APPBAR) { Tencent.onActivityResultData(requestCode, resultCode, data, ShareGridAdapter.mLoginListener); } else if (requestCode == Constants.REQUEST_QQ_SHARE || requestCode == Constants.REQUEST_QZONE_SHARE) { Tencent.onActivityResultData(requestCode, resultCode, data, ShareGridAdapter.mShareListener); } super.onActivityResult(requestCode, resultCode, data); } }
ShareGridAdapter.java逻辑代码如下:
package com.fukaimei.shareqq.adapter; import java.util.ArrayList; import org.json.JSONObject; import android.app.Activity; import android.content.Context; import android.os.Bundle; import android.os.Handler; import android.util.Log; import android.util.Patterns; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; import android.widget.AdapterView.OnItemClickListener; import android.widget.Toast; import com.fukaimei.shareqq.R; import com.fukaimei.shareqq.bean.ShareChanels; import com.fukaimei.shareqq.util.CacheUtil; import com.tencent.connect.common.Constants; import com.tencent.connect.share.QQShare; import com.tencent.connect.share.QzoneShare; import com.tencent.tauth.IUiListener; import com.tencent.tauth.Tencent; import com.tencent.tauth.UiError; public class ShareGridAdapter extends BaseAdapter implements OnItemClickListener { private final static String TAG = "ShareGridAdapter"; private LayoutInflater mInflater; private static Context mContext; private Handler mHandler; private String mUrl; private String mTitle; private static String mContent; private static String mImageUrl; private ArrayList<ShareChanels> mChannelList; private final String QQ_APPID = "填写QQ互联平台里申请到的应用id"; // 这里替换为开发者在QQ互联平台申请的应用id private static Tencent mTencent; private int QQ = 0; private int QZONE = 1; private int WEIBO = 2; private int[] mShareIcons = {R.drawable.logo_qq, R.drawable.logo_qzone, R.drawable.logo_tencentweibo}; public ShareGridAdapter(final Context context, Handler handler, String url, String title, String content, final String imageUrl, ArrayList<ShareChanels> channelList) { mInflater = LayoutInflater.from(context); mContext = context; mHandler = handler; mUrl = url; mTitle = title; mContent = content; if (imageUrl != null && Patterns.WEB_URL.matcher(imageUrl).matches()) { new Thread(new Runnable() { public void run() { try { mImageUrl = CacheUtil.getImagePath(imageUrl, CacheUtil.getFileCache(context)); } catch (Exception e) { e.printStackTrace(); } } }).start(); } else { mImageUrl = imageUrl; } if (channelList == null) { mChannelList = new ArrayList<ShareChanels>(); mChannelList.add(new ShareChanels("QQ好友", QQ)); mChannelList.add(new ShareChanels("QQ空间", QZONE)); } else { mChannelList = channelList; } // 创建一个QQ实例,用于QQ分享、QQ空间分享 mTencent = Tencent.createInstance(QQ_APPID, mContext); } @Override public int getCount() { return mChannelList.size(); } @Override public Object getItem(int position) { return mChannelList.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if (convertView == null) { holder = new ViewHolder(); convertView = mInflater.inflate(R.layout.item_share, null); holder.tv_share_name = (TextView) convertView .findViewById(R.id.tv_share_name); holder.iv_share_icon = (ImageView) convertView .findViewById(R.id.iv_share_icon); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } ShareChanels item = mChannelList.get(position); holder.tv_share_name.setText(item.channelName); holder.tv_share_name.setPadding(0, 0, 0, 0); holder.iv_share_icon.setImageResource(mShareIcons[item.channelType]); return convertView; } public final class ViewHolder { public TextView tv_share_name; public ImageView iv_share_icon; } public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { ShareChanels item = mChannelList.get(arg2); mHandler.sendEmptyMessageDelayed(0, 1500); if (item.channelType == QQ) { mShareListener = new ShareQQListener(mContext, item.channelName); Bundle params = new Bundle(); params.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE, QQShare.SHARE_TO_QQ_TYPE_DEFAULT); params.putString(QQShare.SHARE_TO_QQ_TITLE, mTitle); params.putString(QQShare.SHARE_TO_QQ_SUMMARY, mContent); params.putString(QQShare.SHARE_TO_QQ_TARGET_URL, mUrl); params.putString(QQShare.SHARE_TO_QQ_IMAGE_URL, mImageUrl); params.putString(QQShare.SHARE_TO_QQ_APP_NAME, mContext.getPackageName()); mTencent.shareToQQ((Activity) mContext, params, mShareListener); } else if (item.channelType == QZONE) { mShareListener = new ShareQQListener(mContext, item.channelName); ArrayList<String> urlList = new ArrayList<String>(); urlList.add(mImageUrl); Log.d(TAG, "mImageUrl=" + mImageUrl); Bundle params = new Bundle(); params.putInt(QzoneShare.SHARE_TO_QZONE_KEY_TYPE, QzoneShare.SHARE_TO_QZONE_TYPE_IMAGE_TEXT); params.putString(QzoneShare.SHARE_TO_QQ_TITLE, mTitle); params.putString(QzoneShare.SHARE_TO_QQ_SUMMARY, mContent); params.putString(QzoneShare.SHARE_TO_QQ_TARGET_URL, mUrl); params.putStringArrayList(QzoneShare.SHARE_TO_QQ_IMAGE_URL, urlList); Log.d(TAG, "begin shareToQzone"); mTencent.shareToQzone((Activity) mContext, params, mShareListener); Log.d(TAG, "end shareToQzone"); } else if (item.channelType == WEIBO) { // 腾讯微博分享需要QQ登录授权 mTencent.login((Activity) mContext, "all", mLoginListener); } } public static final int REQUEST_ADD_PIC_T = 1001; public static IUiListener mLoginListener = new IUiListener() { @Override public void onComplete(Object object) { Log.d(TAG, "登录完成:" + object.toString()); try { JSONObject jsonObject = (JSONObject) object; String token = jsonObject.getString(Constants.PARAM_ACCESS_TOKEN); String expires = jsonObject.getString(Constants.PARAM_EXPIRES_IN); String openId = jsonObject.getString(Constants.PARAM_OPEN_ID); } catch (Exception e) { Log.d(TAG, "登录异常:" + e.getMessage()); } } @Override public void onError(UiError error) { Log.d(TAG, "登录失败:" + error.errorMessage); } @Override public void onCancel() { Log.d(TAG, "登录取消"); } }; public static ShareQQListener mShareListener; private static class ShareQQListener implements IUiListener { private Context context; private String channelName; public ShareQQListener(final Context context, final String channelName) { this.context = context; this.channelName = channelName; } @Override public void onComplete(Object object) { Toast.makeText(context, channelName + "分享完成:" + object.toString(), Toast.LENGTH_LONG).show(); } @Override public void onError(UiError error) { Toast.makeText(context, channelName + "分享失败:" + error.errorMessage, Toast.LENGTH_LONG).show(); } @Override public void onCancel() { Toast.makeText(context, channelName + "分享取消", Toast.LENGTH_LONG).show(); } } }
ShareGridDialog.java逻辑代码如下:
package com.fukaimei.shareqq.widget; import java.util.ArrayList; import android.app.Dialog; import android.content.Context; import android.os.Handler; import android.os.Message; import android.util.Log; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.Window; import android.view.WindowManager; import android.view.View.OnClickListener; import android.view.ViewGroup.LayoutParams; import android.widget.GridView; import android.widget.TextView; import com.fukaimei.shareqq.R; import com.fukaimei.shareqq.adapter.ShareGridAdapter; import com.fukaimei.shareqq.bean.ShareChanels; public class ShareGridDialog implements OnClickListener { private final static String TAG = "ShareDialog"; private Dialog dialog; private View view; private Context mContext; private GridView gv_share_channel; private TextView tv_share_cancel; private ShareGridAdapter shareItemAdapter; private String mUrl; private String mTitle; private String mContent; private String mImgUrl; private ArrayList<ShareChanels> mChannelList; public ShareGridDialog(final Context context, ArrayList<ShareChanels> channelList) { mContext = context; mChannelList = channelList; view = LayoutInflater.from(context).inflate(R.layout.dialog_share, null); dialog = new Dialog(context, R.style.dialog_layout_bottom); Window dialogWindow = dialog.getWindow(); dialogWindow.setGravity(Gravity.BOTTOM); gv_share_channel = (GridView) view.findViewById(R.id.gv_share_channel); tv_share_cancel = (TextView) view.findViewById(R.id.tv_share_cancel); tv_share_cancel.setOnClickListener(this); } private Handler mHandler = new Handler() { public void handleMessage(Message msg) { super.handleMessage(msg); if (msg.what == 0) { dismiss(); } else if (msg.what == 9) { Log.d(TAG, (String) msg.obj); // Toast.makeText(mContext, (String)msg.obj, // Toast.LENGTH_LONG).show(); } } }; public String getUrl() { return mUrl; } public void setUrl(String url) { mUrl = url; } public String getTitle() { return mTitle; } public void setTitle(String title) { mTitle = title; } public String getContent() { return mContent; } public void setContent(String content) { mContent = content; } public String getImgUrl() { return mImgUrl; } public void setImgUrl(String imgUrl) { mImgUrl = imgUrl; } public void setSysAlert() { dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); } public void setCancelableOnTouchOutside(boolean flag) { dialog.setCanceledOnTouchOutside(flag); } public void show() { shareItemAdapter = new ShareGridAdapter(mContext, mHandler, mUrl, mTitle, mContent, mImgUrl, mChannelList); gv_share_channel.setAdapter(shareItemAdapter); gv_share_channel.setOnItemClickListener(shareItemAdapter); dialog.getWindow().setContentView(view); dialog.getWindow().setLayout(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); dialog.show(); } public void dismiss() { if (dialog != null && dialog.isShowing()) { dialog.dismiss(); } } public boolean isShowing() { if (dialog != null) return dialog.isShowing(); return false; } public void setCancelable(boolean flag) { dialog.setCancelable(flag); } @Override public void onClick(View v) { if (v.getId() == R.id.tv_share_cancel) { dismiss(); } } }
注意:由于该程序不仅需要访问网络,而且还要启动QQ。因此还需要在清单文件AndroidManifest.xml文件中授权该程序访问网络、QQ、QQ空间所需权限的权限:
<!-- 上网 --> <uses-permission android:name="android.permission.INTERNET" /> <!-- QQ、QQ空间所需权限 --> <uses-permission android:name="android.permission.GET_TASKS" /> <uses-permission android:name="android.permission.SET_DEBUG_APP" /> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <uses-permission android:name="android.permission.GET_ACCOUNTS" /> <uses-permission android:name="android.permission.USE_CREDENTIALS" /> <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
Demo程序运行效果界面截图如下:
Demo程序源码下载地址一(GitHub)
Demo程序源码下载地址二(Gitee)
相关文章推荐
- 主流移动应用开发框架(1)——实现左右滑隐藏菜单的开源框架AndroidResideMenu二次开发
- 【Android应用开发详解】第01期:第三方授权认证(一)实现第三方授权登录、分享以及获取用户资料
- Android开发 APP集成QQ、微信和微博分享
- 【Android应用开发详解】第01期:第三方授权认证(一)实现第三方授权登录、分享以及获取用户资料
- 【Android应用开发详解】实现第三方授权登录、分享以及获取用户资料
- 【Android应用开发详解】第01期:第三方授权认证(一)实现第三方授权登录、分享以及获取用户资料
- 【Android应用开发详解】第01期:第三方授权认证(一)实现第三方授权登录、分享以及获取用户资料
- [置顶] Android移动开发-在Android项目里集成调用微信支付开发的实现
- [置顶] 【Android】开发干货-技术分享之高仿QQ换肤SkinEngine实现
- android开发之&集成qq分享的那些坑
- Android开发实现QQ登陆并获取信息、分享消息到QQ
- 【Android应用开发详解】第01期:第三方授权认证(一)实现第三方授权登录、分享以及获取用户资料
- [置顶] Android移动开发-在Android项目里集成讯飞语音识别与合成的实现
- android移动应用开发学习笔记(五)——模拟qq登陆界面
- Android应用开发-小巫CSDN博客客户端之集成友盟社会化分享组件
- Android网络开发回顾之旅 ① 在Android手机集成使用MQTT协议 ,实现搞掂移动控制硬件端。(附带Demo)
- 【Android应用开发详解】第01期:第三方授权认证(一)实现第三方授权登录、分享以及获取用户资料
- [置顶] 【Android】 开发干货-技术分享高仿QQToast实现
- Android应用开发-小巫CSDN博客客户端之集成友盟社会化分享组件
- 【Android应用开发详解】第01期:第三方授权认证(一)实现第三方授权登录、分享以及获取用户资料