Pkpass on Android

26,986

You can download the full specification for the .pkpass bundle from here. The pass content is stored in a JSON file named pass.json. The .pkpass bundle is a zip file containing pass.json, the pass images, optional locale files and a manifest file.

The manifest needs to be signed with an Apple issued Pass ID certificate. However for Android, or any other third party App, everything required to build the pass can be read from pass.json and the bundled images.

Share:
26,986
ePeace
Author by

ePeace

Developer at DN https://www.d-n.be/

Updated on August 25, 2022

Comments

  • ePeace
    ePeace almost 2 years

    There is an android app, Passwallet, that is able to interpret pkpass files intented for the apple app Passbook (https://play.google.com/store/apps/details?id=com.attidomobile.passwallet)

    I was wondering how to read pkpass files.

    Pkpass files seem to be zip files with all the information inside in json files. Is there a default structure for the pkpass files? If so what is it? And what would be a good way to import that into a android app?


    For the people who wonder how read the content of the pkpass file refer to the following code:

    I set up this activity with the intent filter for pkpass files

            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
    
                <category android:name="android.intent.category.DEFAULT" />
    
                <data
                    android:mimeType="application/vnd-com.apple.pkpass"
                    android:scheme="content" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
    
                <category android:name="android.intent.category.DEFAULT" />
    
                <data
                    android:mimeType="application/vnd.apple.pkpass"
                    android:scheme="content" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
    
                <category android:name="android.intent.category.DEFAULT" />
    
                <data
                    android:mimeType="application/vnd-com.apple.pkpass"
                    android:scheme="file" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
    
                <category android:name="android.intent.category.DEFAULT" />
    
                <data
                    android:mimeType="application/vnd.apple.pkpass"
                    android:scheme="file" />
            </intent-filter>
    

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    super.onCreate(savedInstanceState);
    Intent intent = getIntent();
    Uri uri = intent.getData();
    String scheme = uri.getScheme();
    
    if(ContentResolver.SCHEME_CONTENT.equals(scheme)) {
        try {
            InputStream attachment = getContentResolver().openInputStream(uri);
            handleZipInput(attachment);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
    else {
        String path = uri.getEncodedPath();
        try {
            FileInputStream fis = new FileInputStream(path);
            handleZipInput(fis);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
    }
    
    private void handleZipInput(InputStream in) {
        try {
            ZipInputStream zis = new ZipInputStream(in);
            ZipEntry entry;
            while((entry = zis.getNextEntry()) != null) {
                String filename = entry.getName();
                if(filename.equals("pass.json")) {
                    StringBuilder s = new StringBuilder();
                    int read = 0;
                    byte[] buffer = new byte[1024];
                    while((read = zis.read(buffer, 0, 1024)) >= 0)
                        s.append(new String(buffer, 0, read));
    
                    JSONObject pass = new JSONObject(s.toString());
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    • N Sharma
      N Sharma over 10 years
      I'm able to open my activity in which i applied the intent filter..But When i open the pkpass file from the SD card browser then its says no application to open it...
    • Khobaib
      Khobaib over 10 years
      I found this library extremely helpful for this purpose - github.com/ligi/PassAndroid
    • ligi
      ligi about 10 years
      @Khobaib it is not a library - it is an app - but thanks that you find this helpful!
  • ePeace
    ePeace over 11 years
    Thanks, this is a great first step. I'll upvote, but I won't accept it as answer yet.