前言
如何能迅速做一个分享功能,那主要就是根据第一个步骤来做就好了,因为友盟的sdk包已经集成很多的内容了,只要你有相应的app和平台账号就可以能马上分享。进阶的内容就是从第三部分开始,这些内容不难,目的就是为了更好的优化分享体验。
1.先做一个简单的分享效果。
1.1 创建一个Android项目
以下项目所需要的jar包,图片等资源可到该网站下载SDK即可。
http://dev.umeng.com/social/android/quick-integration?spm=0.0.0.0.LkoxNn |
首先要引入相应的jar包,我用了友盟集成的jar包,选择相应的进行导入。
在下载的SDK中有一个工具:umeng_integrate_tool.jar,使用它生成自己想要的jar包和资源
1.2 然后导入相应的drawable图片以及其他的资源
即用umeng_integrate_tool.jar生成的资源可以一一拷到相应的项目包下。
1.3 在activity_main.xml添加一个按钮
<?xml version="1.0"encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:background="@color/colorWhite" tools:context="com.bingo.starjuly.share.HomeActivity" ><Button android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/fenxiang" android:text="@string/app_name"/> </RelativeLayout> |
1.4 在share_menu.xml也添加一个按钮
<Button android:id="@+id/share_menu_bottom2" android:layout_width="match_parent" android:layout_height="wrap_content" android:textAlignment="center" android:textSize="25dp" android:textColor="@color/colorWhite" android:background="@color/colorBlack" android:text="@string/app_menu"/> |
1.5. 创建一个命名为APP的application用于存放APP ID和APP KEY
public class App extends Application { @Override public void onCreate() { super.onCreate(); //开启debug模式,方便定位错误,具体错误检查方式可以查看http://dev.umeng.com/social/android/quick-integration的报错必看,正式发布,请关闭该模式 Config.DEBUG = true; UMShareAPI.get(this); //使用新浪微博,需要在这里设置回调地址: // Config.REDIRECT_URL = "您新浪后台的回调地址" } { PlatformConfig.setQQZone("1105988460", "tlwdrPlNbMWCgEY9"); } } |
同时要在AndroidManifest.xml的application中配置
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:name=".App" android:theme="@style/AppTheme"> <activity android:name=".HomeActivity"> |
1.6 创建一个HomeActivity的主类
package com.bingo.starjuly.share; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; public class HomeActivity extends Activity implements View.OnClickListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.fenxiang).setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()){ case R.id.fenxiang: Intent menuintent = new Intent(HomeActivity.this,ShareMenuActivity.class); startActivity(menuintent); break; } } } |
1.7 创建一个ShareActivity类
package com.bingo.starjuly.share; import android.app.Activity; import android.os.Bundle; import android.os.PersistableBundle; import android.view.View; import android.widget.Toast; import com.bingo.starjuly.share.model.Defaultcontent; import com.umeng.socialize.ShareAction; import com.umeng.socialize.UMShareListener; import com.umeng.socialize.bean.SHARE_MEDIA; import com.umeng.socialize.shareboard.ShareBoard; import com.umeng.socialize.shareboard.ShareBoardConfig; import com.umeng.socialize.shareboard.SnsPlatform; import com.umeng.socialize.utils.Log; import com.umeng.socialize.utils.ShareBoardlistener; import java.lang.ref.WeakReference; /** * Created by Starjuly on 2017/2/15. */ public class ShareMenuActivity extends Activity{ private UMShareListener mShareListener; private ShareAction mShareAction; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.share_menu); mShareListener = new CustomShareListener(this); /*增加自定义按钮的分享面板*/ mShareAction = new ShareAction(ShareMenuActivity.this).setDisplayList( SHARE_MEDIA.WEIXIN, SHARE_MEDIA.WEIXIN_CIRCLE, SHARE_MEDIA.WEIXIN_FAVORITE, SHARE_MEDIA.SINA, SHARE_MEDIA.QQ, SHARE_MEDIA.QZONE, SHARE_MEDIA.ALIPAY, SHARE_MEDIA.RENREN, SHARE_MEDIA.DOUBAN, SHARE_MEDIA.SMS, SHARE_MEDIA.EMAIL, SHARE_MEDIA.YNOTE, SHARE_MEDIA.EVERNOTE, SHARE_MEDIA.LAIWANG, SHARE_MEDIA.LAIWANG_DYNAMIC, SHARE_MEDIA.LINKEDIN, SHARE_MEDIA.YIXIN, SHARE_MEDIA.YIXIN_CIRCLE, SHARE_MEDIA.TENCENT, SHARE_MEDIA.FACEBOOK, SHARE_MEDIA.TWITTER, SHARE_MEDIA.WHATSAPP, SHARE_MEDIA.GOOGLEPLUS, SHARE_MEDIA.LINE, SHARE_MEDIA.INSTAGRAM, SHARE_MEDIA.KAKAO, SHARE_MEDIA.PINTEREST, SHARE_MEDIA.POCKET, SHARE_MEDIA.TUMBLR, SHARE_MEDIA.FLICKR, SHARE_MEDIA.FOURSQUARE, SHARE_MEDIA.MORE) .addButton("share_sharebutton_copy", "umeng_sharebutton_copy", "umeng_socialize_copy", "umeng_socialize_copy") .addButton("umeng_sharebutton_copyurl", "share_sharebutton_copyurl", "umeng_socialize_copyurl", "umeng_socialize_copyurl") .setShareboardclickCallback(new ShareBoardlistener() { @Override public void onclick(SnsPlatform snsPlatform, SHARE_MEDIA share_media) { if(snsPlatform.mShowWord.equals("share_sharebutton_copy")){ Toast.makeText(ShareMenuActivity.this,"复制文本按钮",Toast.LENGTH_SHORT).show(); }else if(snsPlatform.mShowWord.equals("share_sharebutton_copyurl")){ Toast.makeText(ShareMenuActivity.this, "复制链接按钮", Toast.LENGTH_LONG).show(); }else{ new ShareAction(ShareMenuActivity.this).withText(Defaultcontent.text+"—MoSon") .setPlatform(share_media) .setCallback(mShareListener) .share(); } } }); findViewById(R.id.share_menu_bottom2).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { ShareBoardConfig config = new ShareBoardConfig(); config.setMenuItemBackgroundShape(ShareBoardConfig.BG_SHAPE_NONE); mShareAction.open(config); } }); } private static class CustomShareListener implements UMShareListener{ private WeakReference<ShareMenuActivity> mActivity; private CustomShareListener(ShareMenuActivity activity){ mActivity = new WeakReference(activity); } @Override public void onResult(SHARE_MEDIA platform) { if(platform.name().equals("WEIXIN_FAVORITE")){ Toast.makeText(mActivity.get(),platform+"收藏成功啦",Toast.LENGTH_SHORT).show(); }else{ if(platform != SHARE_MEDIA.MORE && platform != SHARE_MEDIA.SMS && platform != SHARE_MEDIA.EMAIL && platform != SHARE_MEDIA.FLICKR && platform != SHARE_MEDIA.FOURSQUARE && platform != SHARE_MEDIA.TUMBLR && platform != SHARE_MEDIA.POCKET && platform != SHARE_MEDIA.PINTEREST && platform != SHARE_MEDIA.LINKEDIN && platform != SHARE_MEDIA.INSTAGRAM && platform != SHARE_MEDIA.GOOGLEPLUS && platform != SHARE_MEDIA.YNOTE && platform != SHARE_MEDIA.EVERNOTE){ Toast.makeText(mActivity.get(),platform + " 分享成功啦", Toast.LENGTH_SHORT).show(); } } } @Override public void onError(SHARE_MEDIA platform, Throwable t) { if (platform != SHARE_MEDIA.MORE && platform != SHARE_MEDIA.SMS && platform != SHARE_MEDIA.EMAIL && platform != SHARE_MEDIA.FLICKR && platform != SHARE_MEDIA.FOURSQUARE && platform != SHARE_MEDIA.TUMBLR && platform != SHARE_MEDIA.POCKET && platform != SHARE_MEDIA.PINTEREST && platform != SHARE_MEDIA.LINKEDIN && platform != SHARE_MEDIA.INSTAGRAM && platform != SHARE_MEDIA.GOOGLEPLUS && platform != SHARE_MEDIA.YNOTE && platform != SHARE_MEDIA.EVERNOTE) { Toast.makeText(mActivity.get(), platform + " 分享失败啦", Toast.LENGTH_SHORT).show(); if (t != null){ Log.d("throw","throw:"+t.getMessage()); } } } @Override public void onCancel(SHARE_MEDIA platform) { Toast.makeText(mActivity.get(), platform + " 分享取消了", Toast.LENGTH_SHORT).show(); } } } |
1.8效果如下:
在主界面点击分享按钮跳转到分享页面
在分享页面点击“分享菜单”按钮即可弹出分享菜单
2.授权登录功能
2.1 现在activity_main.xml添加一个按钮
<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/fenxiang" android:layout_marginTop="11dp" android:id="@+id/auth" android:layout_alignParentRight="true" android:layout_alignParentEnd="true" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:text="@string/auth" /> |
2.2 然后新建一个app_authadapter.xml用于授权
<?xml version="1.0"encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical"android:layout_width="match_parent" android:background="@color/colorWhite" android:layout_height="match_parent" ><ImageView android:layout_width="48dp" android:layout_height="48dp" android:id="@+id/adapter_image" android:layout_centerVertical="true" android:layout_margin="10dp" android:src="@drawable/umeng_socialize_wechat" /> <TextView android:layout_width="wrap_content" android:layout_centerVertical="true" android:layout_marginLeft="60dp" android:textColor="@color/share_text_color" android:textStyle="bold" android:id="@+id/name" android:text="微信" android:layout_height="wrap_content"/> <TextView android:layout_width="100dp" android:layout_centerInParent="true" android:textColor="@color/share_blue" android:layout_centerVertical="true" android:layout_alignParentRight="true" android:gravity="center" android:text="@string/share_auth_title" android:id="@+id/auth_button" android:layout_marginRight="40dp" android:background="@drawable/btnbg" android:padding="6dp" android:layout_height="wrap_content"/> <View android:layout_width="match_parent" android:background="@color/share_divide" android:layout_alignParentBottom="true" android:layout_marginLeft="60dp" android:id="@+id/divider" android:layout_height="1dp"/> </RelativeLayout> |
2.3 再新建一个share_auth.xml来设置LIstView
<?xml version="1.0"encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:background="@color/share_background" android:layout_height="match_parent" ><include android:id="@+id/title_bar" android:layout_width="match_parent" android:layout_height="54dp" layout="@layout/titlebar"/> <ListView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/list" android:layout_below="@+id/title_bar" android:dividerHeight="0dp" android:divider="@null"></ListView> </RelativeLayout> |
2.4 在主类HomeActivity添加这个按钮事件用于跳转
public class HomeActivityextends Activity implementsView.OnClickListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // ((TextView)findViewById(R.id.share_title)).setText("Share"); findViewById(R.id.fenxiang).setOnClickListener(this); findViewById(R.id.auth).setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()){ case R.id.fenxiang: Intent menuintent = startActivity(menuintent); break; case R.id.auth: Intent authintent = new Intent(HomeActivity.this, AuthActivity.class); startActivity(authintent); break; } } } |
2.5 再新建一个AuthActivity类
package com.bingo.starjuly.share; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.os.PersistableBundle; import android.view.View; import android.widget.ListView; import android.widget.TextView; import com.bingo.starjuly.share.model.AuthAdapter; import com.umeng.socialize.UMShareAPI; import com.umeng.socialize.bean.SHARE_MEDIA; import com.umeng.socialize.shareboard.SnsPlatform; import java.util.ArrayList; /** * Created by Starjuly on 2017/2/16. */ public class AuthActivityextends private ListView listView; private AuthAdapter private ArrayList<SnsPlatform>platforms private SHARE_MEDIA[] SHARE_MEDIA.DOUBAN, SHARE_MEDIA.RENREN}; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.share_auth); listView = (ListView)findViewById(R.id.list); initPlatforms(); shareAdapter = listView.setAdapter(shareAdapter); ((TextView)findViewById(R.id.share_title)).setText(R.string.share_auth_title); findViewById(R.id.share_back).setVisibility(View.VISIBLE); findViewById(R.id.share_back).setOnClickListener(newView.OnClickListener() { @Override public void onClick(View v) { finish(); } }); } private void initPlatforms() { platforms.clear(); for(SHARE_MEDIA e : if(!e.toString().equals(SHARE_MEDIA.GENERIC.toString())){ platforms.add(e.toSnsPlatform()); } } } //回调 @Override protected void onActivityResult(intrequestCode, super.onActivityResult(requestCode, resultCode, data); UMShareAPI.get(this).onActivityResult(requestCode,resultCode,data); } @Override protected void onDestroy() { super.onDestroy(); UMShareAPI.get(this).release(); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); UMShareAPI.get(this).onSaveInstanceState(outState); } } |
2.6 测试分享
在主页面点击“授权”
进入到授权页面
点击授权QQ,分享效果如下:
设置分享内容的代码如下:
分享到QQ空间。
3. 获取网页标题
3.1解决bug
之前都是在代码中固定死的内容,是不符合业务需要的,所以就要做到动态获取页面内容。
找了很多个方法,都不大管用,最后决定使用Jsoup,但要导包。
使用Jsoup会出现一个问题:
android.os.NetworkOnMainThreadException
网上搜索后知道是因为版本问题,在4.0之后在主线程里面执行Http请求都会报这个错,也许是怕Http请求时间太长造成程序假死的情况吧。
解决方法,在初始化时添加如下代码就可以解决以上错误:
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectDiskReads(). detectDiskWrites().detectNetwork().penaltyLog().build()); StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectLeakedSqlLiteObjects(). detectLeakedClosableObjects().penaltyLog().penaltyDeath().build()); |
3.2 修改页面
在share_meun.xml中添加WebView用于显示页面
<WebView android:layout_width="match_parent" android:layout_below="@+id/share_menu_bottom2" android:layout_height="match_parent" android:id="@+id/share_content" ></WebView> |
3.3 获取网页内容
使用Jsonp获取网页需要的内容,我只是获取标题,很简单,知道id就行
try { //获取网页内容 Document document =Jsoup.connect(url).get(); //获取标题 title = document.getElementById("activity-name").text(); } catch (IOException e) { e.printStackTrace(); } |
最后在关键代码上添加获取的内容就可以啦。
3.4 显示效果
页面效果:
分享效果:
QQ空间的
4. 复制链接与文本
这个比较简单,获取系统服务中的剪贴板功能,然后将内容放进去就可以啦。
4.1 复制链接
核心代码如下:
//获取剪贴板管理器 ClipboardManager cm = (ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE); //创建普通字符型ClipData ClipData mClipData = ClipData.newPlainText("URL",url); //将ClipData内容放到系统剪贴板里 cm.setPrimaryClip(mClipData); |
4.2 复制文本
核心代码一样,变化取决与获取的内容。这里就只获取网页的内容,但没有筛选。
5.获取用户相册图片
这个功能是为了能够使分享出去时的图片可以不一样,用户自定义相册图片。
5.1 发送请求
通过隐式启动activity,跳转到相册选择一张返回结果
关键代码如下:
发送请求:
private static final int PICTURE = 10086; //requestcode Intent intent = new Intent(); if (Build.VERSION.SDK_INT < 19) {//因为Android SDK在4.4版本后图片action变化了 所以在这里先判断一下 intent.setAction(Intent.ACTION_GET_CONTENT); } else { intent.setAction(Intent.ACTION_OPEN_DOCUMENT); } intent.setType("image/*"); intent.addCategory(Intent.CATEGORY_OPENABLE); startActivityForResult(intent, PICTURE); |
5.2 接收结果:
//返回数据 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (data == null) { this.finish(); return; } Uri uri = data.getData(); switch (requestCode) { case PICTURE: image = FileUtils.getUriPath(this, uri); //(因为4.4以后图片uri发生了变化)通过文件工具类 对uri进行解析得到图片路径 initMedia(); break; default: break; } // this.finish();i如果不注释就会发生一下错误 //窗体泄漏:WindowManager: android.view.WindowLeaked: //打开分享菜单面板 openDialog(); } |
5.3 文件工具类
public class FileUtils { private static final String TAG = "FileUtils"; private static final boolean DEBUG = false; /** * 获取可读的文件大小 */ public static String getReadableFileSize(int size) { final int BYTES_IN_KILOBYTES = 1024; final DecimalFormat dec = new DecimalFormat("###.#"); final String KILOBYTES = " KB"; final String MEGABYTES = " MB"; final String GIGABYTES = " GB"; float fileSize = 0; String suffix = KILOBYTES; if(size > BYTES_IN_KILOBYTES) { fileSize = size / BYTES_IN_KILOBYTES; if(fileSize > BYTES_IN_KILOBYTES) { fileSize = fileSize / BYTES_IN_KILOBYTES; if(fileSize > BYTES_IN_KILOBYTES) { fileSize = fileSize / BYTES_IN_KILOBYTES; suffix = GIGABYTES; } else { suffix = MEGABYTES; } } } return String.valueOf(dec.format(fileSize) + suffix); } /** * 获取文件的文件名(不包括扩展名) */ public static String getFileNameWithoutExtension(String path) { if(path == null) { return null; } int separatorIndex = path.lastIndexOf(File.separator); if(separatorIndex < 0) { separatorIndex = 0; } int dotIndex = path.lastIndexOf("."); if(dotIndex < 0) { dotIndex = path.length(); } else if(dotIndex < separatorIndex) { dotIndex = path.length(); } return path.substring(separatorIndex + 1, dotIndex); } /** * 获取文件名 */ public static String getFileName(String path) { if(path == null) { return null; } int separatorIndex = path.lastIndexOf(File.separator); return (separatorIndex < 0) ? path : path.substring(separatorIndex + 1, path.length()); } /** * 获取扩展名 */ public static String getExtension(String path) { if(path == null) { return null; } int dot = path.lastIndexOf("."); if(dot >= 0) { return path.substring(dot); } else { return ""; } } public static File getUriFile(Context context, Uri uri) { String path = getUriPath(context, uri); if(path == null) { return null; } return new File(path); } public static String getUriPath(Context context, Uri uri) { if(uri == null) { return null; } if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && DocumentsContract.isDocumentUri(context, uri)) { if("com.android.externalstorage.documents".equals(uri.getAuthority())) { final String docId = DocumentsContract.getDocumentId(uri); final String[] split = docId.split(":"); final String type = split[0]; if("primary".equalsIgnoreCase(type)) { return Environment.getExternalStorageDirectory() + "/" + split[1]; } } else if("com.android.providers.downloads.documents".equals(uri.getAuthority())) { final String id = DocumentsContract.getDocumentId(uri); final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); return getDataColumn(context, contentUri, null, null); } else if("com.android.providers.media.documents".equals(uri.getAuthority())) { final String docId = DocumentsContract.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); } } else if("content".equalsIgnoreCase(uri.getScheme())) { if("com.google.android.apps.photos.content".equals(uri.getAuthority())) { return uri.getLastPathSegment(); } return getDataColumn(context, uri, null, null); } else if("file".equalsIgnoreCase(uri.getScheme())) { return uri.getPath(); } return null; } 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 column_index = cursor.getColumnIndexOrThrow(column); return cursor.getString(column_index); } } finally { if(cursor != null) cursor.close(); } return null; } } |
而那个openDialog ()方法的代码只是抽取出来了而已,就是之前打开面板的操作
还是写出来吧
private void openDialog() { ShareBoardConfig config = new ShareBoardConfig(); config.setMenuItemBackgroundShape(ShareBoardConfig.BG_SHAPE_NONE); mShareAction.open(config); } |
测试微博分享