1

I am new to react-native and I seek your help please. What I am planning to do is to get the app icon associated with an app that the user has installed on his device. I did take a look at this code and realized that I have no way of passing it back to my JS.

Here is what I am doing currently.

    private List<String> getNonSystemApps() {
        List<PackageInfo> packages = this.reactContext
            .getPackageManager()
            .getInstalledPackages(0);
        List<String> ret = new ArrayList<>();
        for (final PackageInfo p: packages) {
            if ((p.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
                JSONObject jsonObject = new JSONObject();
                try {

                    jsonObject.put("name", p.packageName);
                    jsonObject.put("firstInstallTime", p.firstInstallTime);
                    jsonObject.put("installLocation", p.installLocation);
                    jsonObject.put("applicationInfo", p.applicationInfo);
                    jsonObject.put("permissions", getPermissionsByPackageName(p.packageName));
                    Drawable icon = reactContext.getPackageManager().getApplicationIcon(p.packageName);

                    ret.add(jsonObject.toString());

                } catch (JSONException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }    
            }
        }
        return ret;
    }

Can you please help me out with this ?

Thanks

Edit I managed to get it working, based on Aaron's suggestion, I created another private function just to work with the images. This function will generate the base 64 version of an app's icon.

private String getBitmapOfAnAppAsBase64(String packageName) {
    if(packageName.isEmpty() ) return new String("");

    String base64Encoded = "";
    Bitmap bitmap;

    try {
        Drawable appIcon = this.reactContext.getPackageManager().getApplicationIcon(packageName);
        if(appIcon instanceof BitmapDrawable) {
            bitmap= ((BitmapDrawable)appIcon).getBitmap();
        } else {
            bitmap = Bitmap.createBitmap(appIcon.getIntrinsicWidth(), appIcon.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
        }

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 90, byteArrayOutputStream);
        byte[] byteArray = byteArrayOutputStream .toByteArray();
        base64Encoded = Base64.encodeToString(byteArray, Base64.DEFAULT);

    } catch(Exception e) {
        Log.d(TAG,"An error was encounted while getting the package information. The error follows : " + e.toString());
    }


    return  base64Encoded;
}

I then use this generated string in my original function, with the following modifications.

Old Non working code

Drawable icon = reactContext.getPackageManager().getApplicationIcon(p.packageName);

New working code

jsonObject.put("icon", getBitmapOfAnAppAsBase64(p.packageName));

and then in React-Native - its a piece of pie, since it supports base64 already.

"icon" : 'data:image/png;base64,'+installAppObj.icon

Huge thanks to Aaron , for guiding me in the correct direction.

Gagan
  • 5,416
  • 13
  • 58
  • 86

1 Answers1

0

If you haven't already, read through the entire Android Native Modules page. It's not that long and addresses several issues you're likely to run into.

Only these types can be sent to your JS code (via a @ReactMethod):

Boolean -> Bool
Integer -> Number
Double -> Number
Float -> Number
String -> String
Callback -> function
ReadableMap -> Object
ReadableArray -> Array

So you effectively have two options:

  1. Encode the Drawable to one of these types, then decode it on the JavaScript side, or
  2. Write the file to disk, and send the path over

I'm not sure what type of Drawable the icon is or if there are guarantees. But any of them should be convertible in some way. For example if it's a Bitmap you can do a Bitmap to Base64 String conversion.

Aaron Brager
  • 65,323
  • 19
  • 161
  • 287
  • thanks for the pointer.. Much appreciated. Will mark this as the correct answer because it does not lead me astray :) – Gagan Apr 05 '18 at 12:25