Android 获取当前 手机/平板 安装程序并将apk文件进行社会化分享

 目的:获取当前设备所有安装应用,并将该应用的安装包通过社会化分享 分享到其他地方!

解决问题:在应用安装完成之后,系统会自动或者半自动的将安装包进行清除,当想用这个apk文件的时候反而就找不到了,就得重新网络下载,通过此功能可以解决此一部分的问题,功能就是这么功能,具体功能使用怎么延伸就看各自的需求了。

结果演示:

                                                           

 实现思路:

通过packageManger来获取当前系统安装的应用数量,再分别获取应用的图标、包名、应用名、安装时间,获取应用路径获取Uri然后后实现应用的分享。文字比较简洁,思路也就是这么个思路

实现过程:

在真正的开发之前,有必要了解一下packageManager、packageInfo等类有哪些方法,附上链接大家有兴趣的可以看看(你得看啊,不然你能学到啥啊~~~)下图就是贴了个局部

 一、首先创建APKUtils工具类,不要问我权限申请为什么这么多,因为我还有其他用处,你可以只申请读写内存的权限即可

public class APKUtils {

    /**
     * 获取应用的名称
     * @param packageName
     * @param context
     * @return
     */
    public static String getApplicationName(String packageName, Context context) {
        PackageManager packageManager = context.getPackageManager();
            String label = null;
        try {
            ApplicationInfo applicationInfo = packageManager.getApplicationInfo(packageName, 0);
             label = (String) packageManager.getApplicationLabel(applicationInfo);
        } catch (PackageManager.NameNotFoundException e) {
        }
        return label;
    }

    /**
     * 获取应用图标
     * @param context
     * @param packageName
     * @return
     */
    public static Drawable loadIcon(Context context, String packageName) {
        PackageManager packageManager = context.getPackageManager();
        try {
            return packageManager.getApplicationIcon(packageName);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
            return context.getResources().getDrawable(R.mipmap.ic_launcher);
        }
    }

    /**
     * 计算apk文件大小
     * @param packageInfo
     * @return
     */
    public static String getSize(PackageInfo packageInfo) {
        String result = null;
        String sourceDir = packageInfo.applicationInfo.sourceDir;
        File file = new File(sourceDir);
        long l = file.length() / 1024;
        if (l >= 1024) {
            long size = l / 1024;
            result = size + " M";
        } else {
            result = l + " K";
        }
        return result;
    }

    /**
     * 权限申请
     * @param activity
     */
    public static void getPermission(Activity activity) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            // Android M Permission check
            if (activity.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                activity.requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION,
                                Manifest.permission.READ_EXTERNAL_STORAGE,
                                Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.ACCESS_FINE_LOCATION,
                                Manifest.permission.READ_PHONE_STATE},
                        1);
            }
        }
    }

二、配置 FileProvider 因为android7.0以上必须通过provider的形式进行文件访问

res文件下面创建xml文件,在xml文件中创建file_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <!--
   1、name对应的属性值,开发者可以自由定义;
   2、path对应的属性值,当前external-path标签下的相对路径
   比如:/storage/emulated/0/92Recycle-release.apk
   sdcard路径:/storage/emulated/0
   相对路径:/
   -->
    <!--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="/" />
    <!--4、对应外部内存卡根目录下的APP公共目录:Context.getExternalFileDir(String)-->
    <external-files-path
        name="ext_pub"
        path="/" />
    <!--5、对应外部内存卡根目录下的APP缓存目录:Context.getExternalCacheDir()-->
    <external-cache-path
        name="ext_cache"
        path="/" />
    <root-path
        name="r_root"
        path="/" />
</paths>

创建好之后再清单文件AndroidManifest.xml的 application节点内添加provider

 <provider
// v4包name 和androidx的FileProvider会有不同 v4的是 android.support.v4.content.FileProvider
            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/file_paths" />
        </provider>

三、布局我用的是recyclerView 适配器如下(很简单,不详细介绍了):

public class APKAdapter extends RecyclerView.Adapter<APKAdapter.ViewHolder> implements View.OnClickListener {
    private List<PackageInfo> mList;
    private Context mContext;

    public APKAdapter(List<PackageInfo> list, Context context) {
        mList = list;
        mContext = context;
    }

    @NonNull
    @Override
    public APKAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        ViewHolder holder = null;
        View inflate = null;
        if (holder != null) {
            return holder;
        }else {
             inflate = LayoutInflater.from(mContext).inflate(R.layout.apk_item, viewGroup, false);
            holder = new ViewHolder(inflate);
        }
        inflate.setOnClickListener(this);
        return holder;
    }

    @Override
    public void onBindViewHolder(@NonNull APKAdapter.ViewHolder viewHolder, int i) {
        PackageInfo packageInfo = mList.get(i);
        long updateTime = packageInfo.lastUpdateTime;
        String packageName = packageInfo.packageName;
        viewHolder.iv_icon.setImageDrawable(APKUtils.loadIcon(mContext,packageName));
        viewHolder.tv_name.setText(packageName);
        viewHolder.tv_date.setText(NumUtil.getDateFormat(updateTime));
        viewHolder.tv_size.setText(APKUtils.getSize(packageInfo));
        viewHolder.tv_app.setText(APKUtils.getApplicationName(packageName,mContext));
        viewHolder.itemView.setTag(i);

    }

    @Override
    public int getItemCount() {
        int size = mList.size();
        if (size>0){
            return size;
        }
        return 0;
    }

    @Override
    public void onClick(View v) {
        if (onItemClickListener!=null){
            onItemClickListener.onItemClickListener((Integer) v.getTag());
        }
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        ImageView iv_icon;
        TextView tv_app,tv_name,tv_size,tv_date;
        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            iv_icon = itemView.findViewById(R.id.iv_icon);
            tv_name = itemView.findViewById(R.id.tv_name);
            tv_size = itemView.findViewById(R.id.tv_size);
            tv_date = itemView.findViewById(R.id.tv_date);
            tv_app = itemView.findViewById(R.id.tv_app);
        }
    }

    private OnItemClickListener onItemClickListener;
    public interface OnItemClickListener{
        void onItemClickListener(int position);
    }
    public void setOnItemClickListener(OnItemClickListener onItemClickListener){
        this.onItemClickListener = onItemClickListener;
    }
}

布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:background="@drawable/ll_shape"
    android:padding="5dp">
    <ImageView
        android:id="@+id/iv_icon"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:src="@mipmap/logo512"
        />

    <LinearLayout
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_marginLeft="5dp"
        android:orientation="vertical"
        android:paddingLeft="@dimen/dp_10"
        android:layout_height="wrap_content">
        <TextView
            android:id="@+id/tv_app"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="@dimen/sp_18"
            android:textColor="@android:color/black"
            android:text="applicationname"/>
        <TextView
            android:id="@+id/tv_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="@dimen/sp_18"
            android:text="appname"/>
        <TextView
            android:id="@+id/tv_size"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="@dimen/sp_14"
            android:text="100M"/>
        <TextView
            android:id="@+id/tv_date"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="@dimen/sp_14"
            android:text="2019年10月24日16:07:36"/>
    </LinearLayout>

</LinearLayout>

四、activity功能实现

public class APKActivity extends BaseActivity {
    private RecyclerView mRecyclerView;
    private List<PackageInfo> list;
    private PackageManager mPackageManager;
    private APKAdapter mAdapter;
    private LinearLayoutManager mLinearLayoutManager;

    @Override
    public void onClick(View v) {

    }

    @Override
    public int getLayoutId() {
        return R.layout.activity_apk;
    }

    @Override
    public void initView() {
        APKUtils.getPermission(this);
        mRecyclerView = findViewById(R.id.recyleView);

    }

    @Override
    public void initData() {
        mPackageManager = getApplicationContext().getPackageManager();
        list = mPackageManager.getInstalledPackages(0);
        mLinearLayoutManager = new LinearLayoutManager(this);
        mRecyclerView.setLayoutManager(mLinearLayoutManager);
        mAdapter = new APKAdapter(list, APKActivity.this);
        mRecyclerView.setAdapter(mAdapter);
        mAdapter.setOnItemClickListener(new APKAdapter.OnItemClickListener() {
            @Override
            public void onItemClickListener(int position) {
                PackageInfo packageInfo = list.get(position);
                String sourceDir = packageInfo.applicationInfo.sourceDir;
                File apkFile = new File(sourceDir);
                Uri uri = null;
                if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.N){ // android 7.0+
                    uri = FileProvider.getUriForFile(APKActivity.this,"包名.fileprovider",apkFile);
                }else { // android 7.0-
                    uri = Uri.fromFile(new File(sourceDir));
                }
                Intent in = new Intent(Intent.ACTION_SEND);
                in.setType("*/*");
                in.putExtra(Intent.EXTRA_STREAM, uri);
                startActivity(in);
            }
        });
    }


}

activity的布局就是一个recyclerView 没什么好贴的了,整体实现就是这个样子,代码也基本算是完整的,如果用的话注意将包名进行一下替换就可以了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值