前言
如何能迅速做一个分享功能,那主要就是根据第一个步骤来做就好了,因为友盟的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"/>
<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 HomeActivityextendsActivity 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 = new Intent(HomeActivity.this,ShareMenuActivity.class);
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 AuthActivityextendsActivity {
private ListView listView;
private AuthAdapter shareAdapter;
private ArrayList<SnsPlatform>platforms= newArrayList<>();
private SHARE_MEDIA[] list={SHARE_MEDIA.QQ, SHARE_MEDIA.SINA, SHARE_MEDIA.WEIXIN,
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 = new AuthAdapter(this,platforms);
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 : list){
if(!e.toString().equals(SHARE_MEDIA.GENERIC.toString())){
platforms.add(e.toSnsPlatform());
}
}
}
//回调
@Override
protected void onActivityResult(intrequestCode,int resultCode, Intent data) {
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);
}
测试微博分享