diff options
| author | Dominik Schürmann <dominik@dominikschuermann.de> | 2015-02-23 21:52:04 +0100 | 
|---|---|---|
| committer | Dominik Schürmann <dominik@dominikschuermann.de> | 2015-02-23 21:52:04 +0100 | 
| commit | 2064d81aef27492e5f9f13a14375fc505bf105ad (patch) | |
| tree | f3727fb723f81619182e0af643f33a683522fbe7 /OpenKeychain/src/main/java | |
| parent | dd3af50956ec80502f9f14e91cffbd271cc232fd (diff) | |
| download | open-keychain-2064d81aef27492e5f9f13a14375fc505bf105ad.tar.gz open-keychain-2064d81aef27492e5f9f13a14375fc505bf105ad.tar.bz2 open-keychain-2064d81aef27492e5f9f13a14375fc505bf105ad.zip | |
Refactor AppsListFragment
Diffstat (limited to 'OpenKeychain/src/main/java')
| -rw-r--r-- | OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java | 278 | 
1 files changed, 142 insertions, 136 deletions
| diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java index 976ce20d6..506b2da7f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java @@ -1,5 +1,5 @@  /* - * Copyright (C) 2013-2014 Dominik Schürmann <dominik@dominikschuermann.de> + * Copyright (C) 2013-2015 Dominik Schürmann <dominik@dominikschuermann.de>   *   * This program is free software: you can redistribute it and/or modify   * it under the terms of the GNU General Public License as published by @@ -50,8 +50,7 @@ import org.sufficientlysecure.keychain.util.Log;  public class AppsListFragment extends ListFragment implements          LoaderManager.LoaderCallbacks<Cursor> { -    // This is the Adapter being used to display the list's data. -    RegisteredAppsAdapter mAdapter; +    AppsAdapter mAdapter;      @Override      public void onActivityCreated(Bundle savedInstanceState) { @@ -66,7 +65,7 @@ public class AppsListFragment extends ListFragment implements                  if (installed) {                      if (registered) { -                        // edit app settings +                        // Edit app settings                          Intent intent = new Intent(getActivity(), AppSettingsActivity.class);                          intent.setData(KeychainContract.ApiApps.buildByPackageNameUri(selectedPackageName));                          startActivity(intent); @@ -75,9 +74,10 @@ public class AppsListFragment extends ListFragment implements                          PackageManager manager = getActivity().getPackageManager();                          try {                              i = manager.getLaunchIntentForPackage(selectedPackageName); -                            if (i == null) +                            if (i == null) {                                  throw new PackageManager.NameNotFoundException(); -                            // start like the Android launcher would do +                            } +                            // Start like the Android launcher would do                              i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);                              i.addCategory(Intent.CATEGORY_LAUNCHER);                              startActivity(i); @@ -91,30 +91,32 @@ public class AppsListFragment extends ListFragment implements                                  Uri.parse("market://details?id=" + selectedPackageName)));                      } catch (ActivityNotFoundException anfe) {                          startActivity(new Intent(Intent.ACTION_VIEW, -                                Uri.parse("http://play.google.com/store/apps/details?id=" + selectedPackageName))); +                                Uri.parse("https://play.google.com/store/apps/details?id=" + selectedPackageName)));                      }                  }              }          }); -        // Give some text to display if there is no data. In a real -        // application this would come from a resource. -        setEmptyText(getString(R.string.api_no_apps)); +        // NOTE: No setEmptyText(), we always have the default entries          // We have a menu item to show in action bar.          setHasOptionsMenu(true);          // Create an empty adapter we will use to display the loaded data. -        mAdapter = new RegisteredAppsAdapter(getActivity(), null, 0); +        mAdapter = new AppsAdapter(getActivity(), null, 0);          setListAdapter(mAdapter); -        // Loader is started in onResume! +        // NOTE: Loader is started in onResume!      }      @Override      public void onResume() {          super.onResume(); -        // after coming back from Google Play -> reload + +        // Start out with a progress indicator. +        setListShown(false); + +        // After coming back from Google Play -> reload          getLoaderManager().restartLoader(0, null, this);      } @@ -123,7 +125,6 @@ public class AppsListFragment extends ListFragment implements      private static final String TEMP_COLUMN_REGISTERED = "REGISTERED";      private static final String TEMP_COLUMN_ICON_RES_ID = "ICON_RES_ID"; -    // These are the Contacts rows that we will retrieve.      static final String[] PROJECTION = new String[]{              ApiApps._ID, // 0              ApiApps.PACKAGE_NAME, // 1 @@ -149,106 +150,17 @@ public class AppsListFragment extends ListFragment implements          // Now create and return a CursorLoader that will take care of          // creating a Cursor for the data being displayed. -        return new CursorLoader(getActivity(), baseUri, PROJECTION, null, null, +        return new AppsLoader(getActivity(), baseUri, PROJECTION, null, null,                  ApiApps.PACKAGE_NAME + " COLLATE LOCALIZED ASC");      }      public void onLoadFinished(Loader<Cursor> loader, Cursor data) { -        MatrixCursor availableAppsCursor = new MatrixCursor(new String[]{ -                ApiApps._ID, -                ApiApps.PACKAGE_NAME, -                TEMP_COLUMN_NAME, -                TEMP_COLUMN_INSTALLED, -                TEMP_COLUMN_REGISTERED, -                TEMP_COLUMN_ICON_RES_ID -        }); -        // NOTE: SORT ascending by package name, this is REQUIRED for CursorJoiner! -        // Drawables taken from projects res/drawables-xxhdpi/ic_launcher.png -        availableAppsCursor.addRow(new Object[]{1, "com.fsck.k9", "K-9 Mail", 0, 0, R.drawable.apps_k9}); -        availableAppsCursor.addRow(new Object[]{1, "com.zeapo.pwdstore", "Password Store", 0, 0, R.drawable.apps_password_store}); -        availableAppsCursor.addRow(new Object[]{1, "eu.siacs.conversations", "Conversations (Instant Messaging)", 0, 0, R.drawable.apps_conversations}); - -        MatrixCursor mergedCursor = new MatrixCursor(new String[]{ -                ApiApps._ID, -                ApiApps.PACKAGE_NAME, -                TEMP_COLUMN_NAME, -                TEMP_COLUMN_INSTALLED, -                TEMP_COLUMN_REGISTERED, -                TEMP_COLUMN_ICON_RES_ID -        }); - -        CursorJoiner joiner = new CursorJoiner( -                availableAppsCursor, -                new String[]{ApiApps.PACKAGE_NAME}, -                data, -                new String[]{ApiApps.PACKAGE_NAME}); -        for (CursorJoiner.Result joinerResult : joiner) { -            switch (joinerResult) { -                case LEFT: { -                    // handle case where a row in availableAppsCursor is unique -                    String packageName = availableAppsCursor.getString(INDEX_PACKAGE_NAME); - -                    mergedCursor.addRow(new Object[]{ -                            1, // no need for unique _ID -                            packageName, -                            availableAppsCursor.getString(INDEX_NAME), -                            isInstalled(packageName), -                            0, -                            availableAppsCursor.getInt(INDEX_ICON_RES_ID) -                    }); -                    break; -                } -                case RIGHT: { -                    // handle case where a row in data is unique -                    String packageName = data.getString(INDEX_PACKAGE_NAME); - -                    mergedCursor.addRow(new Object[]{ -                            1, // no need for unique _ID -                            packageName, -                            null, -                            isInstalled(packageName), -                            1, // registered! -                            R.drawable.ic_launcher // icon is retrieved later -                    }); -                    break; -                } -                case BOTH: { -                    // handle case where a row with the same key is in both cursors -                    String packageName = data.getString(INDEX_PACKAGE_NAME); - -                    String name; -                    if (isInstalled(packageName) == 1) { -                        name = data.getString(INDEX_NAME); -                    } else { -                        // if not installed take name from available apps list -                        name = availableAppsCursor.getString(INDEX_NAME); -                    } - -                    mergedCursor.addRow(new Object[]{ -                            1, // no need for unique _ID -                            packageName, -                            name, -                            isInstalled(packageName), -                            1, // registered! -                            R.drawable.ic_launcher // icon is retrieved later -                    }); -                    break; -                } -            } -        } -          // Swap the new cursor in. (The framework will take care of closing the          // old cursor once we return.) -        mAdapter.swapCursor(mergedCursor); -    } +        mAdapter.swapCursor(data); -    private int isInstalled(String packageName) { -        try { -            getActivity().getPackageManager().getApplicationInfo(packageName, 0); -            return 1; -        } catch (final PackageManager.NameNotFoundException e) { -            return 0; -        } +        // The list should now be shown. +        setListShown(true);      }      public void onLoaderReset(Loader<Cursor> loader) { @@ -258,12 +170,127 @@ public class AppsListFragment extends ListFragment implements          mAdapter.swapCursor(null);      } -    private class RegisteredAppsAdapter extends CursorAdapter { +    /** +     * Besides the queried cursor with all registered apps, this loader also returns non-installed +     * proposed apps using a MatrixCursor. +     */ +    private static class AppsLoader extends CursorLoader { + +        public AppsLoader(Context context) { +            super(context); +        } + +        public AppsLoader(Context context, Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { +            super(context, uri, projection, selection, selectionArgs, sortOrder); +        } + +        @Override +        public Cursor loadInBackground() { +            // Load registered apps from content provider +            Cursor data = super.loadInBackground(); + +            MatrixCursor availableAppsCursor = new MatrixCursor(new String[]{ +                    ApiApps._ID, +                    ApiApps.PACKAGE_NAME, +                    TEMP_COLUMN_NAME, +                    TEMP_COLUMN_INSTALLED, +                    TEMP_COLUMN_REGISTERED, +                    TEMP_COLUMN_ICON_RES_ID +            }); +            // NOTE: SORT ascending by package name, this is REQUIRED for CursorJoiner! +            // Drawables taken from projects res/drawables-xxhdpi/ic_launcher.png +            availableAppsCursor.addRow(new Object[]{1, "com.fsck.k9", "K-9 Mail", 0, 0, R.drawable.apps_k9}); +            availableAppsCursor.addRow(new Object[]{1, "com.zeapo.pwdstore", "Password Store", 0, 0, R.drawable.apps_password_store}); +            availableAppsCursor.addRow(new Object[]{1, "eu.siacs.conversations", "Conversations (Instant Messaging)", 0, 0, R.drawable.apps_conversations}); + +            MatrixCursor mergedCursor = new MatrixCursor(new String[]{ +                    ApiApps._ID, +                    ApiApps.PACKAGE_NAME, +                    TEMP_COLUMN_NAME, +                    TEMP_COLUMN_INSTALLED, +                    TEMP_COLUMN_REGISTERED, +                    TEMP_COLUMN_ICON_RES_ID +            }); + +            CursorJoiner joiner = new CursorJoiner( +                    availableAppsCursor, +                    new String[]{ApiApps.PACKAGE_NAME}, +                    data, +                    new String[]{ApiApps.PACKAGE_NAME}); +            for (CursorJoiner.Result joinerResult : joiner) { +                switch (joinerResult) { +                    case LEFT: { +                        // handle case where a row in availableAppsCursor is unique +                        String packageName = availableAppsCursor.getString(INDEX_PACKAGE_NAME); + +                        mergedCursor.addRow(new Object[]{ +                                1, // no need for unique _ID +                                packageName, +                                availableAppsCursor.getString(INDEX_NAME), +                                isInstalled(packageName), +                                0, +                                availableAppsCursor.getInt(INDEX_ICON_RES_ID) +                        }); +                        break; +                    } +                    case RIGHT: { +                        // handle case where a row in data is unique +                        String packageName = data.getString(INDEX_PACKAGE_NAME); + +                        mergedCursor.addRow(new Object[]{ +                                1, // no need for unique _ID +                                packageName, +                                null, +                                isInstalled(packageName), +                                1, // registered! +                                R.drawable.ic_launcher // icon is retrieved later +                        }); +                        break; +                    } +                    case BOTH: { +                        // handle case where a row with the same key is in both cursors +                        String packageName = data.getString(INDEX_PACKAGE_NAME); + +                        String name; +                        if (isInstalled(packageName) == 1) { +                            name = data.getString(INDEX_NAME); +                        } else { +                            // if not installed take name from available apps list +                            name = availableAppsCursor.getString(INDEX_NAME); +                        } + +                        mergedCursor.addRow(new Object[]{ +                                1, // no need for unique _ID +                                packageName, +                                name, +                                isInstalled(packageName), +                                1, // registered! +                                R.drawable.ic_launcher // icon is retrieved later +                        }); +                        break; +                    } +                } +            } + +            return mergedCursor; +        } + +        private int isInstalled(String packageName) { +            try { +                getContext().getPackageManager().getApplicationInfo(packageName, 0); +                return 1; +            } catch (final PackageManager.NameNotFoundException e) { +                return 0; +            } +        } +    } + +    private class AppsAdapter extends CursorAdapter {          private LayoutInflater mInflater;          private PackageManager mPM; -        public RegisteredAppsAdapter(Context context, Cursor c, int flags) { +        public AppsAdapter(Context context, Cursor c, int flags) {              super(context, c, flags);              mInflater = LayoutInflater.from(context); @@ -273,44 +300,23 @@ public class AppsListFragment extends ListFragment implements          /**           * Similar to CursorAdapter.getItemId().           * Required to build Uris for api apps, which are not based on row ids -         * -         * @param position -         * @return           */          public String getItemPackageName(int position) { -            if (mDataValid && mCursor != null) { -                if (mCursor.moveToPosition(position)) { -                    return mCursor.getString(INDEX_PACKAGE_NAME); -                } else { -                    return null; -                } +            if (mDataValid && mCursor != null && mCursor.moveToPosition(position)) { +                return mCursor.getString(INDEX_PACKAGE_NAME);              } else {                  return null;              }          }          public boolean getItemIsInstalled(int position) { -            if (mDataValid && mCursor != null) { -                if (mCursor.moveToPosition(position)) { -                    return (mCursor.getInt(INDEX_INSTALLED) == 1); -                } else { -                    return false; -                } -            } else { -                return false; -            } +            return mDataValid && mCursor != null +                    && mCursor.moveToPosition(position) && (mCursor.getInt(INDEX_INSTALLED) == 1);          }          public boolean getItemIsRegistered(int position) { -            if (mDataValid && mCursor != null) { -                if (mCursor.moveToPosition(position)) { -                    return (mCursor.getInt(INDEX_REGISTERED) == 1); -                } else { -                    return false; -                } -            } else { -                return false; -            } +            return mDataValid && mCursor != null +                    && mCursor.moveToPosition(position) && (mCursor.getInt(INDEX_REGISTERED) == 1);          }          @Override | 
