赞
踩
第一步:
打开连接下载配置文件到自己项目的libs中
http://wiki.open.qq.com/wiki/mobile/SDK下载
解压Android_SDK_V2.6 ,把open-sdk.jar文件和mta_sdk_x.x.x.jar文件拷贝到libs(或lib)目录下 。
第二步:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <application> <activity android:name="com.tencent.tauth.AuthActivity" android:noHistory="true" android:launchMode="singleTask" > <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> <application>
SDK_V2.0引入了AssistActivity,开发者需在androidManifest.xml中注册。代码如下:
<activity android:name="com.tencent.connect.common.AssistActivity"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
android:configChanges="orientation|keyboardHidden|screenSize"
/>
第三步:
1.在你要调用分享的Activity的onCreate里(your APP ID == tencent你的AppId)
private Tencent mTencent;// 新建Tencent实例用于调用分享方法
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTencent = Tencent.createInstance("your APP ID",getApplicationContext());
}
*第四步:
实现回调
所有的SDK接口调用,都会传入一个回调,用以接收SDK返回的调用结果。回调的主要接口有两种:
实现回调 IUiListener
调用SDK已经封装好的接口时,例如:登录、快速支付登录、应用分享、应用邀请等接口,需传入该回调的实例。
IUiListener的实现示例代码如下:
public class BaseUIListener implements IUiListener { private Context mContext; private String mScope; private boolean mIsCaneled; private static final int ON_COMPLETE = 0; private static final int ON_ERROR = 1; private static final int ON_CANCEL = 2; private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case ON_COMPLETE: JSONObject response = (JSONObject)msg.obj; Util.showResultDialog(mContext, response.toString(), "onComplete"); Util.dismissDialog(); break; case ON_ERROR: UiError e = (UiError)msg.obj; Util.showResultDialog(mContext, "errorMsg:" + e.errorMessage + "errorDetail:" + e.errorDetail, "onError"); Util.dismissDialog(); break; case ON_CANCEL: Util.toastMessage((Activity)mContext, "onCancel"); break; } } }; public BaseUIListener(Context mContext) { super(); this.mContext = mContext; } public BaseUIListener(Context mContext, String mScope) { super(); this.mContext = mContext; this.mScope = mScope; } public void cancel() { mIsCaneled = true; } @Override public void onComplete(Object response) { if (mIsCaneled) return; Message msg = mHandler.obtainMessage(); msg.what = ON_COMPLETE; msg.obj = response; mHandler.sendMessage(msg); } @Override public void onError(UiError e) { if (mIsCaneled) return; Message msg = mHandler.obtainMessage(); msg.what = ON_ERROR; msg.obj = e; mHandler.sendMessage(msg); } @Override public void onCancel() { if (mIsCaneled) return; Message msg = mHandler.obtainMessage(); msg.what = ON_CANCEL; mHandler.sendMessage(msg); } public Context getmContext() { return mContext; } public void setmContext(Context mContext) { this.mContext = mContext; } }
4.2:实现Util类
public class Util { private static final String TAG = "SDK_Sample.Util"; private static Dialog mProgressDialog; private static Toast mToast; /* Convert byte[] to hex string.这里我们可以将byte转换成int,然后利用Integer.toHexString(int)来转换成16进制字符串。 * @param src byte[] data * @return hex string */ public static String bytesToHexString(byte[] src){ StringBuilder stringBuilder = new StringBuilder(""); if (src == null || src.length <= 0) { return null; } for (int i = 0; i < src.length; i++) { int v = src[i] & 0xFF; String hv = Integer.toHexString(v); if (hv.length() < 2) { stringBuilder.append(0); } stringBuilder.append(hv); } return stringBuilder.toString(); } /** * Convert hex string to byte[] * @param hexString the hex string * @return byte[] */ public static byte[] hexStringToBytes(String hexString) { if (hexString == null || hexString.equals("")) { return null; } hexString = hexString.toUpperCase(); int length = hexString.length() / 2; char[] hexChars = hexString.toCharArray(); byte[] d = new byte[length]; for (int i = 0; i < length; i++) { int pos = i * 2; d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1])); } return d; } /** * Convert char to byte * @param c char * @return byte */ private static byte charToByte(char c) { return (byte) "0123456789ABCDEF".indexOf(c); } /* * 16进制数字字符集 */ private static String hexString="0123456789ABCDEF"; /* * 将字符串编码成16进制数字,适用于所有字符(包括中文) */ public static String toHexString(String str) { //根据默认编码获取字节数组 byte[] bytes = null; try { bytes = str.getBytes("UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } if (bytes == null) return null; StringBuilder sb=new StringBuilder(bytes.length*2); //将字节数组中每个字节拆解成2位16进制整数 for(int i=0;i<bytes.length;i++) { sb.append(hexString.charAt((bytes[i]&0xf0)>>4)); sb.append(hexString.charAt((bytes[i]&0x0f)>>0)); } return sb.toString(); } //转换十六进制编码为字符串 public static String hexToString(String s) { if("0x".equals(s.substring(0, 2))) { s =s.substring(2); } byte[] baKeyword = new byte[s.length()/2]; for(int i = 0; i < baKeyword.length; i++) { try { baKeyword[i] = (byte)(0xff & Integer.parseInt(s.substring(i*2, i*2+2),16)); } catch(Exception e) { e.printStackTrace(); } } try { s = new String(baKeyword, "utf-8");//UTF-16le:Not } catch (Exception e1) { e1.printStackTrace(); } return s; } public static byte[] bmpToByteArray(final Bitmap bmp, final boolean needRecycle) { ByteArrayOutputStream output = new ByteArrayOutputStream(); bmp.compress(CompressFormat.PNG, 100, output); if (needRecycle) { bmp.recycle(); } byte[] result = output.toByteArray(); try { output.close(); } catch (Exception e) { e.printStackTrace(); } return result; } public static byte[] getHtmlByteArray(final String url) { URL htmlUrl = null; InputStream inStream = null; try { htmlUrl = new URL(url); URLConnection connection = htmlUrl.openConnection(); HttpURLConnection httpConnection = (HttpURLConnection)connection; int responseCode = httpConnection.getResponseCode(); if(responseCode == HttpURLConnection.HTTP_OK){ inStream = httpConnection.getInputStream(); } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } byte[] data = inputStreamToByte(inStream); return data; } public static byte[] inputStreamToByte(InputStream is) { try{ ByteArrayOutputStream bytestream = new ByteArrayOutputStream(); int ch; while ((ch = is.read()) != -1) { bytestream.write(ch); } byte imgdata[] = bytestream.toByteArray(); bytestream.close(); return imgdata; }catch(Exception e){ e.printStackTrace(); } return null; } public static byte[] readFromFile(String fileName, int offset, int len) { if (fileName == null) { return null; } File file = new File(fileName); if (!file.exists()) { Log.i(TAG, "readFromFile: file not found"); return null; } if (len == -1) { len = (int) file.length(); } Log.d(TAG, "readFromFile : offset = " + offset + " len = " + len + " offset + len = " + (offset + len)); if(offset <0){ Log.e(TAG, "readFromFile invalid offset:" + offset); return null; } if(len <=0 ){ Log.e(TAG, "readFromFile invalid len:" + len); return null; } if(offset + len > (int) file.length()){ Log.e(TAG, "readFromFile invalid file len:" + file.length()); return null; } byte[] b = null; try { RandomAccessFile in = new RandomAccessFile(fileName, "r"); b = new byte[len]; in.seek(offset); in.readFully(b); in.close(); } catch (Exception e) { Log.e(TAG, "readFromFile : errMsg = " + e.getMessage()); e.printStackTrace(); } return b; } public static int computeSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) { int initialSize = computeInitialSampleSize(options, minSideLength, maxNumOfPixels); int roundedSize; if (initialSize <= 8) { roundedSize = 1; while (roundedSize < initialSize) { roundedSize <<= 1; } } else { roundedSize = (initialSize + 7) / 8 * 8; } return roundedSize; } private static int computeInitialSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) { double w = options.outWidth; double h = options.outHeight; int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels)); int upperBound = (minSideLength == -1) ? 128 : (int) Math.min(Math.floor(w / minSideLength), Math.floor(h / minSideLength)); if (upperBound < lowerBound) { // return the larger one when there is no overlapping zone. return lowerBound; } if ((maxNumOfPixels == -1) && (minSideLength == -1)) { return 1; } else if (minSideLength == -1) { return lowerBound; } else { return upperBound; } } /** * 以最省内存的方式读取图片 */ public static Bitmap readBitmap(final String path){ try{ FileInputStream stream = new FileInputStream(new File(path+"test.jpg")); BitmapFactory.Options opts = new BitmapFactory.Options(); opts.inSampleSize = 8; opts.inPurgeable=true; opts.inInputShareable=true; Bitmap bitmap = BitmapFactory.decodeStream(stream , null, opts); return bitmap; } catch (OutOfMemoryError e) { return null; } catch (Exception e) { return null; } } private static final int MAX_DECODE_PICTURE_SIZE = 1920 * 1440; public static Bitmap extractThumbNail(final String path, final int height, final int width, final boolean crop) { Assert.assertTrue(path != null && !path.equals("") && height > 0 && width > 0); BitmapFactory.Options options = new BitmapFactory.Options(); try { options.inJustDecodeBounds = true; Bitmap tmp = BitmapFactory.decodeFile(path, options); if (tmp != null) { tmp.recycle(); tmp = null; } Log.d(TAG, "extractThumbNail: round=" + width + "x" + height + ", crop=" + crop); final double beY = options.outHeight * 1.0 / height; final double beX = options.outWidth * 1.0 / width; Log.d(TAG, "extractThumbNail: extract beX = " + beX + ", beY = " + beY); options.inSampleSize = (int) (crop ? (beY > beX ? beX : beY) : (beY < beX ? beX : beY)); if (options.inSampleSize <= 1) { options.inSampleSize = 1; } // NOTE: out of memory error while (options.outHeight * options.outWidth / options.inSampleSize > MAX_DECODE_PICTURE_SIZE) { options.inSampleSize++; } int newHeight = height; int newWidth = width; if (crop) { if (beY > beX) { newHeight = (int) (newWidth * 1.0 * options.outHeight / options.outWidth); } else { newWidth = (int) (newHeight * 1.0 * options.outWidth / options.outHeight); } } else { if (beY < beX) { newHeight = (int) (newWidth * 1.0 * options.outHeight / options.outWidth); } else { newWidth = (int) (newHeight * 1.0 * options.outWidth / options.outHeight); } } options.inJustDecodeBounds = false; Log.i(TAG, "bitmap required size=" + newWidth + "x" + newHeight + ", orig=" + options.outWidth + "x" + options.outHeight + ", sample=" + options.inSampleSize); Bitmap bm = BitmapFactory.decodeFile(path, options); if (bm == null) { Log.e(TAG, "bitmap decode failed"); return null; } Log.i(TAG, "bitmap decoded size=" + bm.getWidth() + "x" + bm.getHeight()); final Bitmap scale = Bitmap.createScaledBitmap(bm, newWidth, newHeight, true); if (scale != null) { bm.recycle(); bm = scale; } if (crop) { final Bitmap cropped = Bitmap.createBitmap(bm, (bm.getWidth() - width) >> 1, (bm.getHeight() - height) >> 1, width, height); if (cropped == null) { return bm; } bm.recycle(); bm = cropped; Log.i(TAG, "bitmap croped size=" + bm.getWidth() + "x" + bm.getHeight()); } return bm; } catch (final OutOfMemoryError e) { Log.e(TAG, "decode bitmap failed: " + e.getMessage()); options = null; } return null; } public static final void showResultDialog(Context context, String msg, String title) { if(msg == null) return; String rmsg = msg.replace(",", "\n"); Log.d("Util", rmsg); new AlertDialog.Builder(context).setTitle(title).setMessage(rmsg) .setNegativeButton("知道了", null).create().show(); } public static final void showProgressDialog(Context context, String title, String message) { dismissDialog(); if (TextUtils.isEmpty(title)) { title = "请稍候"; } if (TextUtils.isEmpty(message)) { message = "正在加载..."; } mProgressDialog = ProgressDialog.show(context, title, message); } public static AlertDialog showConfirmCancelDialog(Context context, String title, String message, DialogInterface.OnClickListener posListener) { AlertDialog dlg = new AlertDialog.Builder(context).setMessage(message) .setPositiveButton("确认", posListener) .setNegativeButton("取消", null).create(); dlg.setCanceledOnTouchOutside(false); dlg.show(); return dlg; } public static final void dismissDialog() { if (mProgressDialog != null) { mProgressDialog.dismiss(); mProgressDialog = null; } } /** * 打印消息并且用Toast显示消息 * * @param activity * @param message * @param logLevel * 填d, w, e分别代表debug, warn, error; 默认是debug */ public static final void toastMessage(final Activity activity, final String message, String logLevel) { if ("w".equals(logLevel)) { Log.w("sdkDemo", message); } else if ("e".equals(logLevel)) { Log.e("sdkDemo", message); } else { Log.d("sdkDemo", message); } activity.runOnUiThread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub if (mToast != null) { mToast.cancel(); mToast = null; } mToast = Toast.makeText(activity, message, Toast.LENGTH_SHORT); mToast.show(); } }); } /** * 打印消息并且用Toast显示消息 * * @param activity * @param message * @param logLevel * 填d, w, e分别代表debug, warn, error; 默认是debug */ public static final void toastMessage(final Activity activity, final String message) { toastMessage(activity, message, null); } /** * 根据一个网络连接(String)获取bitmap图像 * * @param imageUri * @return * @throws MalformedURLException */ public static Bitmap getbitmap(String imageUri) { Log.v(TAG, "getbitmap:" + imageUri); // 显示网络上的图片 Bitmap bitmap = null; try { URL myFileUrl = new URL(imageUri); HttpURLConnection conn = (HttpURLConnection) myFileUrl .openConnection(); conn.setDoInput(true); conn.connect(); InputStream is = conn.getInputStream(); bitmap = BitmapFactory.decodeStream(is); is.close(); Log.v(TAG, "image download finished." + imageUri); } catch (OutOfMemoryError e) { e.printStackTrace(); bitmap = null; } catch (IOException e) { e.printStackTrace(); Log.v(TAG, "getbitmap bmp fail---"); bitmap = null; } return bitmap; } public static void release() { mProgressDialog = null; mToast = null; } // ========= // =通过URI获取本地图片的path // =兼容android 5.0 // ========== public static String ACTION_OPEN_DOCUMENT = "android.intent.action.OPEN_DOCUMENT"; public static int Build_VERSION_KITKAT = 19; public static String getPath(final Context context, final Uri uri) { final boolean isKitKat = Build.VERSION.SDK_INT >= 19; // DocumentProvider if (isKitKat && isDocumentUri(context, uri)) { // ExternalStorageProvider if (isExternalStorageDocument(uri)) { final String docId = getDocumentId(uri); final String[] split = docId.split(":"); final String type = split[0]; if ("primary".equalsIgnoreCase(type)) { return Environment.getExternalStorageDirectory() + "/" + split[1]; } } // DownloadsProvider else if (isDownloadsDocument(uri)) { final String id = getDocumentId(uri); final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); return getDataColumn(context, contentUri, null, null); } // MediaProvider else if (isMediaDocument(uri)) { final String docId = getDocumentId(uri); final String[] split = docId.split(":"); final String type = split[0]; Uri contentUri = null; if ("image".equals(type)) { contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; } else if ("video".equals(type)) { contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; } else if ("audio".equals(type)) { contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; } final String selection = "_id=?"; final String[] selectionArgs = new String[] { split[1] }; return getDataColumn(context, contentUri, selection, selectionArgs); } } // MediaStore (and general) else if ("content".equalsIgnoreCase(uri.getScheme())) { // Return the remote address if (isGooglePhotosUri(uri)) return uri.getLastPathSegment(); return getDataColumn(context, uri, null, null); } // File else if ("file".equalsIgnoreCase(uri.getScheme())) { return uri.getPath(); } return null; } private static final String PATH_DOCUMENT = "document"; /** * Test if the given URI represents a {@link Document} backed by a * {@link DocumentsProvider}. */ private static boolean isDocumentUri(Context context, Uri uri) { final List<String> paths = uri.getPathSegments(); if (paths.size() < 2) { return false; } if (!PATH_DOCUMENT.equals(paths.get(0))) { return false; } return true; } private static String getDocumentId(Uri documentUri) { final List<String> paths = documentUri.getPathSegments(); if (paths.size() < 2) { throw new IllegalArgumentException("Not a document: " + documentUri); } if (!PATH_DOCUMENT.equals(paths.get(0))) { throw new IllegalArgumentException("Not a document: " + documentUri); } return paths.get(1); } /** * Get the value of the data column for this Uri. This is useful for * MediaStore Uris, and other file-based ContentProviders. * * @param context * The context. * @param uri * The Uri to query. * @param selection * (Optional) Filter used in the query. * @param selectionArgs * (Optional) Selection arguments used in the query. * [url=home.php?mod=space&uid=7300]@return[/url] The value of * the _data column, which is typically a file path. */ public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) { Cursor cursor = null; final String column = "_data"; final String[] projection = { column }; try { cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null); if (cursor != null && cursor.moveToFirst()) { final int index = cursor.getColumnIndexOrThrow(column); return cursor.getString(index); } } finally { if (cursor != null) cursor.close(); } return null; } /** * @param uri * The Uri to check. * @return Whether the Uri authority is ExternalStorageProvider. */ public static boolean isExternalStorageDocument(Uri uri) { return "com.android.externalstorage.documents".equals(uri.getAuthority()); } /** * @param uri * The Uri to check. * @return Whether the Uri authority is DownloadsProvider. */ public static boolean isDownloadsDocument(Uri uri) { return "com.android.providers.downloads.documents".equals(uri.getAuthority()); } /** * @param uri * The Uri to check. * @return Whether the Uri authority is MediaProvider. */ public static boolean isMediaDocument(Uri uri) { return "com.android.providers.media.documents".equals(uri.getAuthority()); } /** * @param uri * The Uri to check. * @return Whether the Uri authority is Google Photos. */ public static boolean isGooglePhotosUri(Uri uri) { return "com.google.android.apps.photos.content".equals(uri.getAuthority()); } }
第五步:在你分享按钮的位置添加这个方法就可以实现分享的功能了
private void onClickShare() { if(isQQClientAvailable(mContext)) { Bitmap bitmap = base64ToBitmap(arg.split("base64,")[1]); final 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, "要分享的标题"); params.putString(QQShare.SHARE_TO_QQ_SUMMARY, "要分享的摘要"); params.putString(QQShare.SHARE_TO_QQ_TARGET_URL, "http://www.qq.com/news/1.html"); params.putString(QQShare.SHARE_TO_QQ_IMAGE_URL, saveBitmap(mContext, bitmap)); params.putString(QQShare.SHARE_TO_QQ_APP_NAME, "测试应用222222"); mTencent.shareToQQ((Activity) mContext, params, new BaseUIListener(mContext)); //这个是分享纯图片的类似二维码的 可以扫一扫的那种 根据自己的需要来定 // if (isQQClientAvailable(mContext)) { // Bitmap bitmap = base64ToBitmap(arg.split("base64,")[1]); // Toast.makeText(mContext, saveBitmap(mContext, bitmap), Toast.LENGTH_SHORT).show(); // final Bundle params = new Bundle(); // params.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE, QQShare.SHARE_TO_QQ_TYPE_IMAGE);// 设置分享类型为纯图片分享 也可以设置更多 看自己自己的需要 可以传网址和标题什么的 // params.putString(QQShare.SHARE_TO_QQ_IMAGE_LOCAL_URL, saveBitmap(mContext,bitmap));// 需要分享的本地图片URL // mTencent.shareToQQ((Activity) mContext, params, new BaseUIListener(mContext));; // // } else { // Toast.makeText(mContext, "您还没有安装微信,请先安装QQ客户端", Toast.LENGTH_SHORT).show(); // } }else { Toast.makeText(mContext, "您还没有安装微信,请先安装QQ客户端", Toast.LENGTH_SHORT).show(); } } /** * 判断 用户是否安装QQ客户端 */ public static boolean isQQClientAvailable(Context context) { final PackageManager packageManager = context.getPackageManager(); List<PackageInfo> pinfo = packageManager.getInstalledPackages(0); if (pinfo != null) { for (int i = 0; i < pinfo.size(); i++) { String pn = pinfo.get(i).packageName; LogUtils.e("pn = "+pn); if (pn.equalsIgnoreCase("com.tencent.qqlite") || pn.equalsIgnoreCase("com.tencent.mobileqq")) { return true; } } } return false; }
第六步:特别注意在特别注意一定要填写
应用调用Andriod_SDK接口时,如果要成功接收到回调,需要在调用接口的Activity的onActivityResult方法中增加如下代码:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
mTencent.onActivityResult(requestCode, resultCode, data);
}
我之前犯错误:第一:以为在配置文件中设置APP ID 了 所以在mTencent = Tencent.createInstance(“1105704113”, this.getApplicationContext());这话中的直接饮用的APPID 结果报错没有APN权限。
特别提醒大家 一定要在自己的此方法中添加APPID账号而且一定要找对。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。