1

I want to make an application that could send itself (apk file) by bluetooth. but i have trouble with finding the apk file path. i tried this code:

final PackageManager pm = this.getPackageManager();
    List<PackageInfo> packages =  pm.getInstalledPackages(PackageManager.GET_META_DATA);
    String st = null;
    for (PackageInfo packageInfo : packages) {
        if(packageInfo.packageName.contains("testbutton"))
        st=packageInfo.packageName;
    }

    Intent intent = new Intent();  
    intent.setAction(Intent.ACTION_SEND);  
    intent.setType("image/*");

    String uri = "/data/app/";
    uri+=st;
    intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(uri)));
    startActivity(intent);

but st returns null value. please help me with this. thanks in advance

Nahid OG
  • 131
  • 4
  • 16

2 Answers2

3

finally i'd found the right answer that works in this purpose, thanks to @Kanak for her help :)

PackageManager pm = getPackageManager();
    String uri = null;
    for (ApplicationInfo app : pm.getInstalledApplications(0)) {
        if(!((app.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) == 1))
            if(!((app.flags & ApplicationInfo.FLAG_SYSTEM) == 1)){
                uri=app.sourceDir;
                  if(uri.contains("com.example.test"))
                  break;
            }
    }

    Intent intent = new Intent();  
    intent.setAction(Intent.ACTION_SEND);  
    intent.setType("image/*");
    intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(uri)));
    startActivity(intent);
Nahid OG
  • 131
  • 4
  • 16
  • Hey, my apk is going out as base.apk instead of appname.apk. Is there a way to change the name just as it is going out? – Visionwriter Sep 30 '15 at 14:53
  • @Visionwriter I haven't tried it but i think you can do it by copying the file and renaming it and then sending the renamed file. [here's](http://stackoverflow.com/a/4770586/3234630) an example of how to do the copy and rename, i hope it helps. – Nahid OG Oct 01 '15 at 15:41
  • Uri.fromFile doesn't work anymore when you use targetSdk 24 or above. – android developer Dec 03 '16 at 21:06
3

There is no need to iteration. Getting the application itself APK file uri is as easy as this:

String appUri = getApplicationInfo().publicSourceDir;

Also note that doc says this about publicSourceDir:

Full path to the publicly available parts of sourceDir, including resources and manifest. This may be different from sourceDir if an application is forward locked.

And also note that to send an APK file, you need to set the type to application/vnd.android.package-archive instead of image/*

So the complete snippet would be:

String appUri = getApplicationInfo().publicSourceDir;
Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
sharingIntent.setType("application/vnd.android.package-archive");
sharingIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(appUri)));
startActivity(Intent.createChooser(sharingIntent, "Share via"));
Ali Lotfi
  • 856
  • 3
  • 18
  • 40
  • 1
    What's the difference between publicSourceDir and sourceDir? Both seem to have the same value... – android developer Dec 03 '16 at 21:05
  • @androiddeveloper As documentation says, it's **different** in **Forward Locked** application. For more information about forward locking applications, you can see [adb documentation](https://developer.android.com/studio/command-line/adb.html) under `pm install` options. – Ali Lotfi Dec 04 '16 at 08:37
  • 1
    You mean this "-l: Install the package with forward lock." ? But what does it mean? What is "forward locked application" ? Suppose I wish to share the APK of the app, should I use publicSourceDir, or should I use sourceDir ? – android developer Dec 05 '16 at 08:27
  • 4
    @androiddeveloper A forward locked application is an application which the installer don't want the user to share the application's package. So even if you wish, you can't access sourceDir of a forward locked application (without root access at least). So for normal usage, always use `publicSourceDir`. – Ali Lotfi Dec 05 '16 at 11:09
  • I see. How can I know (via Android framework API) if an app is in this state, that its APK can't be shared? Also, do apps really do it? Is there even an API to make the app non-shareable ("forward lock" ) ? – android developer Dec 05 '16 at 18:55
  • 1
    I don't think the "-l" works. The "adb" tool says it's an unknown parameter... Here: https://issuetracker.google.com/issues/139965909 . Also, in all my app (including system apps), both files have the same path. – android developer Aug 25 '19 at 06:41