iis服务器助手广告广告
返回顶部
首页 > 资讯 > 移动开发 >Android原生态实现分享转发功能实例
  • 953
分享到

Android原生态实现分享转发功能实例

2024-04-02 19:04:59 953人浏览 独家记忆
摘要

目录导读: 一、xml布局文件二、创建一个实体类 AppInfo.java,用来保存应用信息三、重写PopupWindow控件SharePopupWindow.java,自定义分享的

导读:

之前刚学安卓时,写过一篇“Android调用系统shareAPI实现分享转发功能”的文章,随着安卓版本的迭代更新以及其他APP的优化,安卓的这个shareapi好像失效了,不怎么好使,已经获取不到有分享功能的APP列表,点击分享也会直接崩溃。并不是说我之前那篇文章的代码有错,只能说是时代有了变化,旧的方法已经不能满足新的需求

 最近开发一个收款APP,想把分享功能加入进去,然后发现旧的方法已经不行,这就难过了,网上一些大佬建议用第三方APP自带的分享SDK,但是我觉得用第三方的SDK太麻烦了,每个 APP都要申请接口账号和接口密钥,即便是使用其他人封装好的分享框架,也是需要去申请账号密钥的,一点也不方便,还是喜欢安卓原生态写法,简单便捷、一劳永逸。

经过我几番研究,最终完美实现了,效果图如下:

 一、xml布局文件

1、res/layout目录下创建share_dialog.xml


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="Http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/shape_dialog_bg"
    android:orientation="vertical" >
 
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="16dp"
        android:text="分享到..." />
 
    <HorizontalScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scrollbars="none" >
 
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent" >
 
            <GridView
                android:id="@+id/sharePopupWindow_gridView"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scrollbars="none" />
        </LinearLayout>
    </HorizontalScrollView>
 
    <View
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:alpha="0.3"
        android:background="#666" />
 
    <TextView
        android:id="@+id/sharePopupWindow_close"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:padding="20dp"
        android:text="取消"
        android:textSize="16sp" />
 
</LinearLayout>

2、res/layout目录下创建appinfo_item.xml


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:orientation="vertical"
    android:paddingBottom="8dp"
    android:paddingLeft="16dp"
    android:paddingRight="16dp"
    android:paddingTop="8dp">
 
    <ImageView
        android:id="@+id/appinfo_item_icon"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:scaleType="centerCrop"
        android:src="@drawable/loGo"/>
 
    <TextView
        android:id="@+id/appinfo_item_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="2dp"
        android:ellipsize="end"
        android:singleLine="true"
        android:textSize="12sp"
        android:text="分享到……"/>
</LinearLayout>

3、在res/values/styles.xml 中,添加以下代码,用来实现弹出窗背景效果:


<style name="circleDialog" parent="android:style/Theme.Dialog">
        <!-- 背景透明,设置圆角对话框必须设置背景透明,否则四角会有背景色小块-->
        <item name="android:windowBackground">@android:color/transparent</item>
        <!-- 没有标题 -->
        <item name="android:windowNoTitle">true</item>
        <!-- 背景模糊 -->
        <item name="android:backgroundDimEnabled">true</item>
</style>

二、创建一个实体类 AppInfo.java,用来保存应用信息


package net.zy13.skhelper.entity;
 
import android.graphics.drawable.Drawable;
 

public class AppInfo {
    private String appName;
    private String packageName;
    private String versionName;
    private int versionCode;
    private String launchClassName;
    private Drawable appIcon;
 
    public String getAppName() {
        return appName;
    }
 
    public void setAppName(String appName) {
        this.appName = appName;
    }
 
    public String getPackageName() {
        return packageName;
    }
 
    public void setPackageName(String packageName) {
        this.packageName = packageName;
    }
 
    public String getVersionName() {
        return versionName;
    }
 
    public void setVersionName(String versionName) {
        this.versionName = versionName;
    }
 
    public int getVersionCode() {
        return versionCode;
    }
 
    public void setVersionCode(int versionCode) {
        this.versionCode = versionCode;
    }
 
    public String getLaunchClassName() {
        return launchClassName;
    }
 
    public void setLaunchClassName(String launchClassName) {
        this.launchClassName = launchClassName;
    }
 
    public Drawable getAppIcon() {
        return appIcon;
    }
 
    public void setAppIcon(Drawable appIcon) {
        this.appIcon = appIcon;
    }
}

三、重写PopupWindow控件SharePopupWindow.java,自定义分享的弹窗


package net.zy13.skhelper.view;
 
import java.io.File;
import java.util.List;
 
import android.app.ActionBar.LayoutParams;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.GridView;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.TextView;
 
import androidx.core.content.FileProvider;
 
import net.zy13.skhelper.R;
import net.zy13.skhelper.adapter.AppInfoAdapter;
import net.zy13.skhelper.entity.AppInfo;
import net.zy13.skhelper.utils.LogUtil;
import net.zy13.skhelper.utils.MapTable;
import net.zy13.skhelper.utils.ShareUtil;
 
public class SharePopupWindow extends PopupWindow {
 
    //每行显示多少个
    private static final int NUM = 5;
 
    private View mMenuView;
    private GridView mGridView;
    private TextView mTextViewClose;
    private AppInfoAdapter mAdapter;
 
    private List<AppInfo> mAppinfoList;
 
    private String imgpath;
    private String shareTitle;
    private String shareContent;
    public void setImgpath(String imgpath) {
        this.imgpath = imgpath;
    }
    public void setShareTitle(String shareTitle) {
        this.shareTitle = shareTitle;
    }
    public void setShareContent(String shareContent) {
        this.shareContent = shareContent;
    }
 
    
    public SharePopupWindow(final Context context) {
        super(context);
        LayoutInflater inflater = (LayoutInflater) context  .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mMenuView = inflater.inflate(R.layout.share_dialog, null);
        //获取控件
        mGridView=(GridView) mMenuView.findViewById(R.id.sharePopupWindow_gridView);
        mTextViewClose=(TextView) mMenuView.findViewById(R.id.sharePopupWindow_close);
        //获取所有的非系统应用
        mAppinfoList = ShareUtil.getAllApps(context);
        //适配GridView
        mAdapter=new AppInfoAdapter(context, mAppinfoList);
        mGridView.setAdapter(mAdapter);
 
        //修改GridView
        changeGridView(context);
 
        mGridView.setOnItemClickListener(new OnItemClickListener() {
 
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position,
                                    long id) {
                // TODO Auto-generated method stub
                //使用其他APP打开文件
                Intent intent = new Intent();
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
                intent.setAction(Intent.ACTION_VIEW);
                //LogUtil.debug("图片地址:"+imgpath);
                //我这里分享的是图片,如果你要分享链接和文本,可以在这里自行发挥
                Uri uri = FileProvider.getUriForFile(context, "fileprovider", new File(imgpath));
                intent.setDataAndType(uri, MapTable.getMIMEType(imgpath));
                context.startActivity(intent);
            }
        });
        //取消按钮
        mTextViewClose.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                dismiss();
            }
        });
        //设置SelectPicPopupWindow的View
        this.setContentView(mMenuView);
        //设置SelectPicPopupWindow弹出窗体的宽
        this.setWidth(LayoutParams.FILL_PARENT);
        //设置SelectPicPopupWindow弹出窗体的高
        this.setHeight(LayoutParams.WRAP_CONTENT);
        //设置SelectPicPopupWindow弹出窗体可点击
        this.setFocusable(true);
        //设置窗口外也能点击(点击外面时,窗口可以关闭)
        this.setOutsideTouchable(true);
        //设置SelectPicPopupWindow弹出窗体动画效果
        this.setAnimationStyle(R.style.circleDialog);
        //实例化一个ColorDrawable颜色为半透明
        ColorDrawable dw = new ColorDrawable(0x00000000);
        //设置SelectPicPopupWindow弹出窗体的背景
        this.setBackgroundDrawable(dw);
    }
 
    
    private void changeGridView(Context context) {
        // item宽度
        int itemWidth = dip2px(context, 90);
        // item之间的间隔
        int itemPaddingH = dip2px(context, 1);
        //计算一共显示多少行;
        int size = mAppinfoList.size();
        //int row=(size<=NUM) ? 1 :( (size%NUM>0) ? size/NUM+1 : size/NUM );
        //每行真正显示多少个
        int rowitem = (size<NUM)?size:NUM;
        // 计算GridView宽度
        int gridviewWidth = rowitem * (itemWidth + itemPaddingH);
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                gridviewWidth, LinearLayout.LayoutParams.MATCH_PARENT);
        mGridView.setLayoutParams(params);
        mGridView.setColumnWidth(itemWidth);
        mGridView.setHorizontalSpacing(itemPaddingH);
        mGridView.setStretchMode(GridView.NO_STRETCH);
        mGridView.setNumColumns(rowitem);
    }
 
    
    public static int dip2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }
 
}

四、使用provider

1、在清单文件AndroidManifest.xml的<application>标签内添加provider


<provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/filepaths"/>
        </provider>

注意:要与activity标签同级 

 2、在res/xml目录添加filepaths.xml,代码如下:


<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <!--
    1、name对应的属性值,开发者可以自由定义;
    2、path对应的属性值,当前external-path标签下的相对路径
    -->
    <!--1、对应内部内存卡根目录:Context.getFileDir()-->
    <files-path
        name="int_root"
        path="/" />
    <!--2、对应应用默认缓存根目录:Context.getCacheDir()-->
    <cache-path
        name="app_cache"
        path="/" />
    <!--3、对应外部内存卡根目录:Environment.getExternalStorageDirectory()-->
    <external-path
        name="ext_root"
        path="Documents/" />
    <!--4、对应外部内存卡根目录下的APP公共目录:Context.getExternalFileDir(Environment.DIRECTORY_PICTURES)-->
    <external-files-path
        name="ext_pub"
        path="/" />
    <!--5、对应外部内存卡根目录下的APP缓存目录:Context.getExternalCacheDir()-->
    <external-cache-path
        name="ext_cache"
        path="/" />
</paths>

五、写一个工具类 

ShareUtil.java


package net.zy13.skhelper.utils;
 
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
 
import net.zy13.skhelper.MainApplication;
import net.zy13.skhelper.entity.AppInfo;
 
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
 
public class ShareUtil {
    
    public static List<AppInfo> getAllApps(Context context) {
        List<AppInfo> appList = new ArrayList<AppInfo>();
        PackageManager pm=context.getPackageManager();
        List<PackageInfo> packages = pm.getInstalledPackages(0);
        for (int i = 0;i< packages.size();i++) {
            PackageInfo packageInfo = packages.get(i);
            AppInfo tmpInfo = new AppInfo();
            tmpInfo.setAppName(packageInfo.applicationInfo.loadLabel(pm).toString());
            tmpInfo.setPackageName(packageInfo.packageName);
            tmpInfo.setVersionName(packageInfo.versionName);
            tmpInfo.setVersionCode(packageInfo.versionCode);
            tmpInfo.setAppIcon(packageInfo.applicationInfo.loadIcon(pm));
            //如果非系统应用,则添加至appList
            if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
                //排除当前应用(替换成你的应用包名即可)
                if(!packageInfo.packageName.equals("net.zy13.skhelper")) {
                    appList.add(tmpInfo);
                }
            }
        }
        return  appList;
    }
    
    public static String SaveTitmapToCache(Bitmap bitmap){
        // 默认保存在应用缓存目录里 Context.getCacheDir()
        File file=new File(MainApplication.getAppContext().getCacheDir(),System.currentTimeMillis()+".png");
        try {
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
            bitmap.compress(Bitmap.CompressFORMat.JPEG, 100, bos);
            bos.flush();
            bos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return file.getPath();
    }
}

六、GridView的适配器 AppInfoAdapter.java


package net.zy13.skhelper.adapter;
 
import android.annotation.SuppressLint;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
 
import net.zy13.skhelper.R;
import net.zy13.skhelper.entity.AppInfo;
 
import java.util.List;
 
public class AppInfoAdapter extends BaseAdapter {
 
    private Context context;
    private List<AppInfo> mAppinfoList;
    private OnItemClickListener mOnItemClickLitener;
 
    public AppInfoAdapter(Context context, List<AppInfo> mAppinfoList) {
        super();
        this.context = context;
        this.mAppinfoList = mAppinfoList;
    }
 
    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return mAppinfoList.size();
    }
 
    @Override
    public Object getItem(int arg0) {
        // TODO Auto-generated method stub
        return null;
    }
 
    @Override
    public long getItemId(int arg0) {
        // TODO Auto-generated method stub
        return 0;
    }
 
    @SuppressLint("NewApi")
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub
        AppInfo appInfo = mAppinfoList.get(position);
        // 加载布局
        View view;
        ViewHolder viewHolder;
        if (convertView == null) {
            view = LayoutInflater.from(context).inflate(R.layout.appinfo_item, null);
            viewHolder = new ViewHolder(view);
            // 将ViewHolder存储在View中
            view.setTag(viewHolder);
        } else {
            view = convertView;
            // 重新获取ViewHolder
            viewHolder = (ViewHolder) view.getTag();
 
        }
        //设置控件的值
        viewHolder.imageViewIcon.setImageDrawable(appInfo.getAppIcon());
        String name=appInfo.getAppName();
        viewHolder.textViewName.setText(name);
        return view;
    }
 
    class ViewHolder {
        ImageView imageViewIcon;
        TextView textViewName;
 
        public ViewHolder(View view) {
            this.imageViewIcon = (ImageView) view.findViewById(R.id.appinfo_item_icon);
            this.textViewName = (TextView) view.findViewById(R.id.appinfo_item_name);
        }
    }
 
}

七、自定义分享窗口SharePopupWindow的调用 


 private LinearLayout mLayoutRoot;
 private ImageView mImageView;
 
//获取根布局
mLayoutRoot=(LinearLayout)view.findViewById(R.id.LayoutRoot);
//获取图片控件
mImageView=(ImageView)view.findViewById(R.id.image_qrcode);
 
 
// 获取ImageView图片
mImageView.setDrawinGCacheEnabled(true);
Bitmap bitmap =Bitmap.createBitmap(mImageViewQrcode.getDrawingCache());
mImageView.setDrawingCacheEnabled(false);
String imgpath=ShareUtil.SaveTitmapToCache(bitmap);
//实例化分享窗口
SharePopupWindow spw = new SharePopupWindow(mContext);
spw.setImgpath(imgpath);
// 显示窗口
spw.showAtLocation(mLayoutRoot, Gravity.BOTTOM, 0, 0);

到此这篇关于Android原生态实现分享转发功能实例的文章就介绍到这了,更多相关Android分享转发功能内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Android原生态实现分享转发功能实例

本文链接: https://www.lsjlt.com/news/159447.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Android原生态实现分享转发功能实例
    目录导读: 一、xml布局文件二、创建一个实体类 AppInfo.java,用来保存应用信息三、重写PopupWindow控件SharePopupWindow.java,自定义分享的...
    99+
    2022-11-12
  • 如何使用Android原生态实现分享转发功能
    这篇文章主要介绍了如何使用Android原生态实现分享转发功能,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。导读:之前刚学安卓时,写过一篇“Android调用系统shareA...
    99+
    2023-06-22
  • Android实现分享功能
    Android应用中能很方便的完成这些功能,很多的应用中都有“分享”功能?如何分享呢?下面给大家说说看。 最近有人问到Android分享功能用那个比较好,使用Andr...
    99+
    2022-06-06
    Android
  • 原生javascript实现分享到朋友圈功能 支持ios和android
      现在主流的分享工具也有很多,例如JiaThis、bShare分享,甚至一些大公司的如百度分享,但是他们依旧停留在只是在PC端的分享,对手机端的支持不是太好。   大家都知道...
    99+
    2022-06-06
    朋友圈 IOS JavaScript Android
  • Android开发中应用程序分享功能实例
    本文实例讲述了Android开发中应用程序分享功能。分享给大家供大家参考,具体如下: Intent shareIntent = new Intent(); shareInte...
    99+
    2022-06-06
    程序 应用程序 android开发 Android
  • android分享功能如何实现
    实现Android分享功能可以使用Android系统提供的分享功能,具体步骤如下:1. 创建一个分享的按钮或菜单项,例如在布局文件中...
    99+
    2023-10-09
    android
  • Android ShareSDK快速实现分享功能
    第一步 :获取ShareSDK   为了集成ShareSDK,您首先需要到ShareSDK官方网站注册并且创建应用,获得ShareSDK的Appkey,然后到SDK的下载页面...
    99+
    2022-06-06
    Android
  • Android 分享功能的实现代码
    Android 分享功能的实现代码 一个Activity中,取出设备上安装的所有支持分享动作的Activity,在grid中显示。 实例代码: public class N...
    99+
    2022-06-06
    Android
  • Android开发中怎么实现一个分享功能
    Android开发中怎么实现一个分享功能?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。实现代码如下所示;Intent email = new Intent(android....
    99+
    2023-05-31
    android roi
  • 使用Android实现截图和分享功能的案例
    这篇文章主要介绍了使用Android实现截图和分享功能的案例,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。先给大家展示下效果图吧直接上代码:xml的布局:<Button...
    99+
    2023-05-30
    android
  • Android编程实现调用系统分享功能示例
    本文实例讲述了Android编程实现调用系统分享功能。分享给大家供大家参考,具体如下: public class ShareActivity extends Activit...
    99+
    2022-06-06
    调用 示例 系统 Android
  • Android开发中怎么实现一个缩略图分享功能
    这篇文章将为大家详细讲解有关Android开发中怎么实现一个缩略图分享功能,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。代码如下 public void wxHyShare(String ...
    99+
    2023-05-31
    android roi
  • Android开发中怎么实现一个朋友圈分享功能
    本篇文章为大家展示了Android开发中怎么实现一个朋友圈分享功能,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。先下载微信分享的jar包放在lib目录下,并且添加依赖,清单文件添加<activ...
    99+
    2023-05-31
    android roi
  • Android实现app分享文件到微信功能
    本文实例为大家分享了Android实现app分享文件到微信的具体代码,供大家参考,具体内容如下 两种实现方案: 1.使用WXFileObject构造分享方法发送到微信; 2.调用系统...
    99+
    2022-11-12
  • 如何在Android应用中实现一个动态界面分享功能
    如何在Android应用中实现一个动态界面分享功能?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。动态列表界面MomentListFragment支持 下拉刷新与...
    99+
    2023-05-31
    android roi
  • Android实现发送短信功能实例详解
    本文实例分析了Android实现发送短信功能的方法。分享给大家供大家参考,具体如下: 短信和打电话一样,都是android手机的基本功能,下面以实例说明android如何实现发...
    99+
    2022-06-06
    发送短信 Android
  • Android中使用原生MediaRecorder APi实现录音功能
    一、MediaRecorder简介 MediaRecorder是Android中的一个API,可以用来实现录音功能。它继承自android.media.MediaRecorder类,可以实现音频和视频的录制。 二、MediaRecorder...
    99+
    2023-09-30
    android
  • android原生实现多线程断点续传功能
    本文实例为大家分享了android实现多线程断点续传功能的具体代码,供大家参考,具体内容如下 需求描述: 输入一个下载地址,和要启动的线程数量,点击下载 利用多线程将文件下载到手机端...
    99+
    2022-11-13
  • 微信开发之如何实现分享功能
    这篇文章将为大家详细讲解有关微信开发之如何实现分享功能,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。 通过对需求的了解,可以将其分解为:(1...
    99+
    2022-10-19
  • nodeJS实现简单网页爬虫功能的实例(分享)
    本文将使用nodeJS实现一个简单的网页爬虫功能 网页源码 使用http.get()方法获取网页源码,以hao123网站的头条页面为例 http://tuijian.hao123.com/hotrank ...
    99+
    2022-06-04
    爬虫 实例 简单
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作