How to save apk sahre apk file and backup

How to get apk file in Android device programatically

In this tutorial we will see how to save and share installed APK from the device. In this post we will see how we can copy or share apk file of applications installed in the user device.

Steps to save APK file:

  1. Get list of installed applications in the device.
  2. Get public source directory of the application
  3. Make a copy of apk file from public source directory to desired location.

Get List Of Apps:

First we will call PackageManager getInstalledApplications api to get information of installed application. getInstalledApplications returns all the applications installed for the user.

     List<ApplicationInfo> applicationInfos = getPackageManager().getInstalledApplications(PackageManager.GET_META_DATA);

We will create a handler thread to get the list of applications installed in a background thread.

package com.codeexa.com.applicationinfo;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;

import java.util.List;

public class ApplicationInfoLoader extends HandlerThread {

    private PackageManager mPackageManager;
    private Handler mWorkerHandler;
    private Handler mResponseHandler;
    private Callback mCallback;

    public interface Callback {
        public void onApplicationInfoFetched(List<ApplicationInfo> data);
    }

    public ApplicationInfoLoader(Context ctx, Handler responseHandler, Callback callback) {
        super("ApplicationInfoLoader");
        mResponseHandler = responseHandler;
        mCallback = callback;
        mPackageManager = ctx.getPackageManager();
    }

    public void queueTask() {
        mWorkerHandler.obtainMessage(1)
                .sendToTarget();
    }


    public void prepareHandler() {
        mWorkerHandler = new Handler(getLooper(), new Handler.Callback() {
            @Override
            public boolean handleMessage(Message msg) {
                handleRequest();
                try {
                    msg.recycle();
                } catch (IllegalStateException e) {
                    mWorkerHandler.removeMessages(msg.what);
                }
                return true;
            }
        });
    }

    private void handleRequest() {
        final List<ApplicationInfo> applicationInfos = mPackageManager.getInstalledApplications(PackageManager.GET_META_DATA);

        mResponseHandler.post(new Runnable() {
            @Override
            public void run() {

                mCallback.onApplicationInfoFetched(applicationInfos);
            }
        });
    }
}

We will be using HandlerThread to get the list of apps in background thread. After receiving installed application list HandlerThread will pass the list back to main UI thread.

 ApplicationInfoLoader mWorkerThread = new ApplicationInfoLoader(this, new Handler(), data -> {

        });

        mWorkerThread.start();
        mWorkerThread.prepareHandler();
        mWorkerThread.queueTask();

 

RecyclerView to Show List Of Installed Apps:

get list of all apps installed in android

We have fetched list of apps installed in the device. Now it’s time to create RecyclerView Adapter to display the list in the view.

Create adapter class

package com.codeexa.com.applicationinfo;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.Locale;

public class AppInfoDataAdapter extends RecyclerView.Adapter<AppInfoDataAdapter.TargetViewHolder>{

    private final PackageManager mPackageManager;
    ArrayList<ApplicationInfo> targetsArrayList;

    public interface OnRecycleItemClick {

        void onItemClick(View view, int position);
    }

    OnRecycleItemClick mListener;

    public AppInfoDataAdapter(Context ctx, ArrayList<ApplicationInfo> mTargetData, OnRecycleItemClick itemListener) {
        mPackageManager = ctx.getPackageManager();
        targetsArrayList = mTargetData;
        mListener = itemListener;
    }

    @NonNull
    @Override
    public TargetViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View v= LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.app_row,viewGroup,false);
        return new TargetViewHolder(v, mListener);
    }

    @Override
    public void onBindViewHolder(@NonNull TargetViewHolder viewHolder, int i) {
        Drawable d = targetsArrayList.get(i).loadIcon(mPackageManager);
        CharSequence appName = targetsArrayList.get(i).loadLabel(mPackageManager);
        viewHolder.appIcon.setImageDrawable(d);
        viewHolder.appName.setText(appName);
        viewHolder.appPackage.setText(targetsArrayList.get(i).packageName);
    }

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

    public static class TargetViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        protected ImageView appIcon;
        protected TextView appName;
        protected TextView appPackage;
        OnRecycleItemClick itemClickInterface;
        public TargetViewHolder(@NonNull View itemView, OnRecycleItemClick listener) {
            super(itemView);
            appIcon=  itemView.findViewById(R.id.appIcon);
            appName=  itemView.findViewById(R.id.textView3);
            appPackage=  itemView.findViewById(R.id.textView4);
            itemClickInterface = listener;
            itemView.setOnClickListener(this);
        }

        @Override
        public void onClick(View v) {
            itemClickInterface.onItemClick(v, getAdapterPosition());
        }
    }
}

Create layout view app_row.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <ImageView
        android:id="@+id/appIcon"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginBottom="8dp"
        android:gravity="center"
        android:scaleType="fitCenter"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <LinearLayout
        android:id="@+id/linearLayout"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="8dp"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/appIcon"
        app:layout_constraintTop_toTopOf="parent">

        <TextView
            android:id="@+id/textView3"
            android:gravity="center_vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textStyle="bold"
            android:layout_marginBottom="8dp"
            android:text="App Name" />

        <TextView
            android:layout_marginTop="8dp"
            android:id="@+id/textView4"
            android:gravity="center_vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Package" />
    </LinearLayout>
</android.support.constraint.ConstraintLayout>

Save APK file to SD-card with AsyncTask

In order to get apk file we need to filter application list based on package name and get its public source directory. Once we get the path to the apk file we can copy it to sdcard. Let’s create a simple AsyncTask to copy apk file from source to destination.

   private class FileSaveTask extends AsyncTask<Void, Integer, File> {

        private final ApplicationInfo apkInfo;
        private  WeakReference<Context> mContext;

        public FileSaveTask(Context ctx, ApplicationInfo file) {
            this.apkInfo = file;
            mContext = new WeakReference<>(ctx);
        }

        @Override
        protected File doInBackground(Void... params) {
            int i = 0;
            File outputFile = Environment.getExternalStorageDirectory() ;
            outputFile = new File(outputFile.getPath() + File.separator + "MyAppDirectory");
            if (!outputFile.exists()) {
                outputFile.mkdirs();
            }

            try {
                String fileName = apkInfo.loadLabel(mContext.get().getPackageManager()).toString();
                File apkFile = new File(outputFile.getPath() + File.separator + fileName +".apk");
                InputStream in = new FileInputStream(apkInfo.publicSourceDir);
                OutputStream out = new FileOutputStream(apkFile);
                byte[] buf = new byte[1024];
                int len;
                while ((len = in.read(buf)) > 0) {
                    out.write(buf, 0, len);
                }
                in.close();
                out.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                return null;
            } catch (IOException e) {
                e.printStackTrace();
                return null;
            }
            publishProgress(i);
            return outputFile;
        }

        @Override
        protected void onPostExecute(File result) {

             if (result != null) {
                AlertDialog.Builder alert = new AlertDialog.Builder(mContext.get());
                alert.setCancelable(false);
                alert.setTitle("File Saved");
                alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dg, int arg1) {
                        dg.dismiss();
                    }
                });
                alert.show();
            } else {
                Toast.makeText(mContext.get(), "Failed tp save APK", Toast.LENGTH_LONG).show();
            }
        }
    }

We have created a AsyncTask and we pass Context and ApplicationInfo of the source application as parameters. ApplicationInfo contains information about the package like label, icon, apk location.

This is how our asynctask needs to be called.

   new FileSaveTask(this, appInfo).execute();

Download Android Source Code

The code demonstrates how to fetch list of all the apps in a background thread created using HandlerThread. Furthermore it also shows how to save the apk file of the selected app in SD-Card location.

APK Save Code
APK Save Code
ApplicationInfoCode.zip
Version: 1.0
200.9 KiB
269 Downloads
Details

Leave a Reply