├── .gitignore
├── AndroidManifest.xml
├── LICENSE
├── README.md
├── libs
└── acra-4.5.0.jar
├── project.properties
├── res
├── drawable-hdpi
│ ├── checkbox_off.png
│ ├── checkbox_on.png
│ └── ic_launcher.png
├── drawable-ldpi
│ └── ic_launcher.png
├── drawable-mdpi
│ ├── checkbox_off.png
│ ├── checkbox_on.png
│ └── ic_launcher.png
├── drawable-xhdpi
│ ├── checkbox_off.png
│ ├── checkbox_on.png
│ └── ic_launcher.png
├── drawable
│ └── selector_checkbox.xml
├── layout
│ ├── activity_main.xml
│ ├── column_list_item.xml
│ ├── dialog_add_content_provider.xml
│ ├── dialog_query_with_filter.xml
│ ├── result_table.xml
│ └── simple_spinner_item.xml
├── menu
│ ├── main_activity.xml
│ └── result_activity.xml
├── values
│ ├── arrays.xml
│ ├── prefs.xml
│ └── strings.xml
└── xml
│ └── preferences.xml
├── src
└── com
│ └── jensdriller
│ └── contentproviderhelper
│ ├── app
│ └── ContentProviderHelper.java
│ ├── db
│ └── Database.java
│ ├── model
│ ├── Column.java
│ ├── ColumnData.java
│ ├── ColumnList.java
│ └── Result.java
│ ├── provider
│ └── FileProvider.java
│ ├── task
│ ├── DialogAsyncTask.java
│ ├── LoadColumnsTask.java
│ ├── LoadResultsTask.java
│ └── SearchProvidersTask.java
│ └── ui
│ ├── activity
│ ├── BaseActivity.java
│ ├── ColumnsAdapter.java
│ ├── MainActivity.java
│ ├── PreferenceActivity.java
│ └── ResultActivity.java
│ └── dialog
│ ├── AddProviderDialog.java
│ ├── ContractDialogFragment.java
│ ├── DeleteProviderDialog.java
│ ├── ProgressDialogFragment.java
│ ├── QueryWithFilterDialog.java
│ └── SearchProviderDialog.java
└── web_hi_res_512.png
/.gitignore:
--------------------------------------------------------------------------------
1 | #########################
2 | ### GITIGNORE ANDROID ###
3 | #########################
4 |
5 | # built application files
6 | *.apk
7 | *.ap_
8 |
9 | # files for the dex VM
10 | *.dex
11 |
12 | # Java class files
13 | *.class
14 |
15 | # generated files
16 | bin/
17 | gen/
18 |
19 | # Local configuration file (sdk path, etc)
20 | local.properties
21 |
22 | # Eclipse project files
23 | .classpath
24 | .project
25 |
26 | # Proguard folder generated by Eclipse
27 | proguard/
28 |
29 | # Intellij project files
30 | *.iml
31 | *.ipr
32 | *.iws
33 | .idea/
34 |
35 |
36 | #########################
37 | ### GITIGNORE ECLIPSE ###
38 | #########################
39 |
40 | *.pydevproject
41 | .project
42 | .metadata
43 | bin/**
44 | tmp/**
45 | tmp/**/*
46 | *.tmp
47 | *.bak
48 | *.swp
49 | *~.nib
50 | local.properties
51 | .classpath
52 | .settings/
53 | .loadpath
54 |
55 | # External tool builders
56 | .externalToolBuilders/
57 |
58 | # Locally stored "Eclipse launch configurations"
59 | *.launch
60 |
61 | # CDT-specific
62 | .cproject
63 |
64 | # PDT-specific
65 | .buildpath
66 |
--------------------------------------------------------------------------------
/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
34 |
35 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Jens Driller
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Content Provider Helper
2 | =======================
3 |
4 | Get it on Google Play: [com.jensdriller.contentproviderhelper](https://play.google.com/store/apps/details?id=com.jensdriller.contentproviderhelper)
5 |
6 | Requires [ActionBarSherlock](http://actionbarsherlock.com) and the latest [android-support-v4.jar](http://developer.android.com/tools/support-library/index.html) library.
7 |
8 | What's New
9 | ----------
10 |
11 | ### v1.1.0:
12 |
13 | - Choose your theme: Light / Dark / Light (Dark ActionBar)
14 |
15 | - Fixed OutOfMemory errors on lower spec devices
16 |
17 | - Query content providers with more complex SQL queries
18 |
19 | - Save & Share query results as HTML page
20 |
21 | ### v1.0.0:
22 |
23 | - Initial release
24 |
25 | Description
26 | -----------
27 |
28 | This app helps developers to discover and query content providers.
29 | You can add and delete your own URIs manually or search for all available content providers on the device.
30 |
31 | App permissions are set generously to provide maximum compatibility.
32 |
33 | The following content providers are provided by default:
34 |
35 | * content://browser/bookmarks
36 | * content://browser/searches
37 | * content://call_log/calls
38 | * content://com.android.calendar/attendees
39 | * content://com.android.calendar/calendar_alerts
40 | * content://com.android.calendar/calendars
41 | * content://com.android.calendar/event_entities
42 | * content://com.android.calendar/events
43 | * content://com.android.calendar/reminders
44 | * content://com.android.contacts/aggregation_exceptions
45 | * content://com.android.contacts/contacts
46 | * content://com.android.contacts/data
47 | * content://com.android.contacts/groups
48 | * content://com.android.contacts/raw_contact_entities
49 | * content://com.android.contacts/raw_contacts
50 | * content://com.android.contacts/settings
51 | * content://com.android.contacts/status_updates
52 | * content://com.android.contacts/syncstate
53 | * content://drm/audio
54 | * content://drm/images
55 | * content://icc/adn
56 | * content://icc/fdn
57 | * content://icc/sdn
58 | * content://media/external/audio/albums
59 | * content://media/external/audio/artists
60 | * content://media/external/audio/genres
61 | * content://media/external/audio/media
62 | * content://media/external/audio/playlists
63 | * content://media/external/images/media
64 | * content://media/external/images/thumbnails
65 | * content://media/external/video/media
66 | * content://media/external/video/thumbnails
67 | * content://media/internal/audio/albums
68 | * content://media/internal/audio/artists
69 | * content://media/internal/audio/genres
70 | * content://media/internal/audio/media
71 | * content://media/internal/audio/playlists
72 | * content://media/internal/images/media
73 | * content://media/internal/images/thumbnails
74 | * content://media/internal/video/media
75 | * content://media/internal/video/thumbnails
76 | * content://mms
77 | * content://mms/inbox
78 | * content://mms/outbox
79 | * content://mms/part
80 | * content://mms/sent
81 | * content://mms-sms/conversations
82 | * content://mms-sms/draft
83 | * content://mms-sms/locked
84 | * content://mms-sms/search
85 | * content://settings/secure
86 | * content://settings/system
87 | * content://sms/conversations
88 | * content://sms/draft
89 | * content://sms/inbox
90 | * content://sms/outbox
91 | * content://sms/sent
92 | * content://telephony/carriers
93 | * content://user_dictionary/words
94 |
95 | License
96 | -------
97 | This project is licensed under the [MIT License](https://raw.githubusercontent.com/jenzz/ContentProviderHelper/master/LICENSE).
98 |
--------------------------------------------------------------------------------
/libs/acra-4.5.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jenzz/ContentProviderHelper/2837512289e91b3ae918eca183c6e37a07db0600/libs/acra-4.5.0.jar
--------------------------------------------------------------------------------
/project.properties:
--------------------------------------------------------------------------------
1 | target=android-19
2 | android.library.reference.1=../ActionBarSherlock/actionbarsherlock
3 |
--------------------------------------------------------------------------------
/res/drawable-hdpi/checkbox_off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jenzz/ContentProviderHelper/2837512289e91b3ae918eca183c6e37a07db0600/res/drawable-hdpi/checkbox_off.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/checkbox_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jenzz/ContentProviderHelper/2837512289e91b3ae918eca183c6e37a07db0600/res/drawable-hdpi/checkbox_on.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jenzz/ContentProviderHelper/2837512289e91b3ae918eca183c6e37a07db0600/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-ldpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jenzz/ContentProviderHelper/2837512289e91b3ae918eca183c6e37a07db0600/res/drawable-ldpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-mdpi/checkbox_off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jenzz/ContentProviderHelper/2837512289e91b3ae918eca183c6e37a07db0600/res/drawable-mdpi/checkbox_off.png
--------------------------------------------------------------------------------
/res/drawable-mdpi/checkbox_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jenzz/ContentProviderHelper/2837512289e91b3ae918eca183c6e37a07db0600/res/drawable-mdpi/checkbox_on.png
--------------------------------------------------------------------------------
/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jenzz/ContentProviderHelper/2837512289e91b3ae918eca183c6e37a07db0600/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-xhdpi/checkbox_off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jenzz/ContentProviderHelper/2837512289e91b3ae918eca183c6e37a07db0600/res/drawable-xhdpi/checkbox_off.png
--------------------------------------------------------------------------------
/res/drawable-xhdpi/checkbox_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jenzz/ContentProviderHelper/2837512289e91b3ae918eca183c6e37a07db0600/res/drawable-xhdpi/checkbox_on.png
--------------------------------------------------------------------------------
/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jenzz/ContentProviderHelper/2837512289e91b3ae918eca183c6e37a07db0600/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable/selector_checkbox.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
14 |
15 |
20 |
21 |
27 |
28 |
35 |
36 |
43 |
44 |
45 |
55 |
56 |
64 |
65 |
71 |
72 |
80 |
81 |
85 |
86 |
92 |
93 |
99 |
100 |
101 |
105 |
106 |
112 |
113 |
118 |
119 |
120 |
121 |
--------------------------------------------------------------------------------
/res/layout/column_list_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
17 |
18 |
25 |
26 |
31 |
32 |
33 |
36 |
37 |
44 |
45 |
51 |
52 |
53 |
54 |
65 |
66 |
--------------------------------------------------------------------------------
/res/layout/dialog_add_content_provider.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
20 |
21 |
22 |
23 |
24 |
29 |
30 |
36 |
37 |
--------------------------------------------------------------------------------
/res/layout/dialog_query_with_filter.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
11 |
12 |
18 |
19 |
25 |
26 |
27 |
30 |
31 |
37 |
38 |
45 |
46 |
53 |
54 |
55 |
59 |
60 |
66 |
67 |
74 |
75 |
82 |
83 |
84 |
87 |
88 |
94 |
95 |
102 |
103 |
104 |
--------------------------------------------------------------------------------
/res/layout/result_table.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
14 |
15 |
22 |
23 |
29 |
30 |
38 |
39 |
46 |
47 |
55 |
56 |
63 |
64 |
65 |
69 |
70 |
--------------------------------------------------------------------------------
/res/layout/simple_spinner_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/res/menu/main_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/res/menu/result_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/res/values/arrays.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | - content://browser/bookmarks
6 | - content://browser/searches
7 | - content://call_log/calls
8 | - content://com.android.calendar/attendees
9 | - content://com.android.calendar/calendars
10 | - content://com.android.calendar/calendar_alerts
11 | - content://com.android.calendar/events
12 | - content://com.android.calendar/event_entities
13 | - content://com.android.calendar/reminders
14 | - content://com.android.contacts/contacts
15 | - content://com.android.contacts/raw_contacts
16 | - content://com.android.contacts/raw_contact_entities
17 | - content://com.android.contacts/data
18 | - content://com.android.contacts/status_updates
19 | - content://com.android.contacts/settings
20 | - content://com.android.contacts/aggregation_exceptions
21 | - content://com.android.contacts/groups
22 | - content://com.android.contacts/syncstate
23 | - content://drm/images
24 | - content://drm/audio
25 | - content://icc/adn
26 | - content://icc/fdn
27 | - content://icc/sdn
28 | - content://media/internal/audio/media
29 | - content://media/external/audio/media
30 | - content://media/internal/audio/albums
31 | - content://media/external/audio/albums
32 | - content://media/internal/audio/genres
33 | - content://media/external/audio/genres
34 | - content://media/internal/audio/artists
35 | - content://media/external/audio/artists
36 | - content://media/internal/audio/playlists
37 | - content://media/external/audio/playlists
38 | - content://media/internal/images/media
39 | - content://media/external/images/media
40 | - content://media/internal/images/thumbnails
41 | - content://media/external/images/thumbnails
42 | - content://media/internal/video/media
43 | - content://media/external/video/media
44 | - content://media/internal/video/thumbnails
45 | - content://media/external/video/thumbnails
46 | - content://mms
47 | - content://mms/inbox
48 | - content://mms/sent
49 | - content://mms/outbox
50 | - content://mms/part
51 | - content://sms/inbox
52 | - content://sms/sent
53 | - content://sms/draft
54 | - content://sms/outbox
55 | - content://sms/conversations
56 | - content://mms-sms/conversations
57 | - content://mms-sms/draft
58 | - content://mms-sms/locked
59 | - content://mms-sms/search
60 | - content://telephony/carriers
61 | - content://user_dictionary/words
62 | - content://settings/system
63 | - content://settings/secure
64 |
65 |
66 | - @string/preferences_theme_light
67 | - @string/preferences_theme_light_dark_action_bar
68 | - @string/preferences_theme_dark
69 |
70 |
71 | - =
72 | - !=
73 | - <
74 | - <=
75 | - >
76 | - >=
77 |
78 |
79 | - ASC
80 | - DESC
81 |
82 |
83 |
--------------------------------------------------------------------------------
/res/values/prefs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Theme
5 | Miscellaneous
6 | Source Code
7 | Build Version
8 | theme
9 | acra.enable
10 | build_version
11 | github
12 | Theme
13 | Current: %1$s
14 | Light
15 | Light (Dark ActionBar)
16 | Dark
17 | Send crash reports
18 | Yes, I support the developer! :-)
19 | No, I do NOT support the developer! :-(
20 | true
21 | @string/preferences_theme_light_dark_action_bar
22 | This app is now open source!
23 | https://github.com/jenzz/ContentProviderHelper
24 |
25 |
--------------------------------------------------------------------------------
/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Content Provider Helper
4 | Check All
5 | Uncheck All
6 | Query
7 | Query With Filter
8 | Show Column Types
9 | Hide Column Types
10 | Content Provider:
11 | Filter:
12 | Type:
13 | Columns:
14 | Rows:
15 | Info
16 | OK
17 | - BLOB -
18 | - ERROR -
19 | None
20 | Cancel
21 | Add
22 | Delete
23 | Share
24 | Unknown
25 | Add Content Provider
26 | Delete Content Providers
27 | - No custom content providers available -
28 | Settings
29 | Loading columns…
30 | Searching content providers…
31 | Loading data…
32 | Sorry, API Level 11 or higher is required to display column types. Your current API Level is %s.
33 | Data successfully loaded
34 | content://
35 | Insert content provider manually:
36 | Or search for available content providers:
37 | Content provider successfully added
38 |
39 |
40 | - 1 content provider successfully deleted
41 | - %d content providers successfully deleted
42 |
43 |
44 | Content provider already exists
45 | Note: Enclose Strings in single quotes!
46 | Invalid content provider
47 | Search
48 | Where:
49 | Sort by:
50 | Limit:
51 | -
52 |
53 |
--------------------------------------------------------------------------------
/res/xml/preferences.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
12 |
13 |
14 |
20 |
21 |
24 |
25 |
26 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/src/com/jensdriller/contentproviderhelper/app/ContentProviderHelper.java:
--------------------------------------------------------------------------------
1 | package com.jensdriller.contentproviderhelper.app;
2 |
3 | import org.acra.ACRA;
4 | import org.acra.ReportField;
5 | import org.acra.annotation.ReportsCrashes;
6 |
7 | import android.app.Application;
8 | import android.content.Context;
9 | import android.preference.PreferenceManager;
10 | import android.widget.Toast;
11 |
12 | import com.jensdriller.contentproviderhelper.R;
13 |
14 | @ReportsCrashes(formKey = "dFMxRVo1UzRvcHBDLVEtMTR2QnhUN2c6MQ", customReportContent = { ReportField.REPORT_ID, ReportField.INSTALLATION_ID, ReportField.APP_VERSION_CODE, ReportField.APP_VERSION_NAME,
15 | ReportField.PACKAGE_NAME, ReportField.FILE_PATH, ReportField.PHONE_MODEL, ReportField.BRAND, ReportField.PRODUCT, ReportField.ANDROID_VERSION, ReportField.BUILD, ReportField.STACK_TRACE,
16 | ReportField.INITIAL_CONFIGURATION, ReportField.CRASH_CONFIGURATION, ReportField.DISPLAY, ReportField.USER_APP_START_DATE, ReportField.USER_CRASH_DATE, ReportField.DEVICE_FEATURES,
17 | ReportField.ENVIRONMENT, ReportField.SHARED_PREFERENCES, ReportField.SETTINGS_SYSTEM, ReportField.SETTINGS_SECURE })
18 | public class ContentProviderHelper extends Application {
19 |
20 | @Override
21 | public void onCreate() {
22 | super.onCreate();
23 |
24 | ACRA.init(this);
25 | PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
26 | }
27 |
28 | public static int getUserTheme(Context context) {
29 | String themeKey = context.getString(R.string.preferences_key_theme);
30 | String themeDefault = context.getString(R.string.preferences_default_theme);
31 | String themeDark = context.getString(R.string.preferences_theme_dark);
32 | String themeLight = context.getString(R.string.preferences_theme_light);
33 |
34 | String theme = PreferenceManager.getDefaultSharedPreferences(context).getString(themeKey, themeDefault);
35 | if (theme.equals(themeDark)) {
36 | return R.style.Theme_Sherlock;
37 | } else if (theme.equals(themeLight)) {
38 | return R.style.Theme_Sherlock_Light;
39 | } else {
40 | return R.style.Theme_Sherlock_Light_DarkActionBar;
41 | }
42 | }
43 |
44 | public static void handleException(Context context, Exception e, boolean sendReport) {
45 | e.printStackTrace();
46 | Toast.makeText(context, e.toString(), Toast.LENGTH_LONG).show();
47 | if (sendReport) {
48 | ACRA.getErrorReporter().handleException(e);
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/com/jensdriller/contentproviderhelper/db/Database.java:
--------------------------------------------------------------------------------
1 | package com.jensdriller.contentproviderhelper.db;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import android.content.ContentValues;
7 | import android.content.Context;
8 | import android.database.Cursor;
9 | import android.database.SQLException;
10 | import android.database.sqlite.SQLiteDatabase;
11 | import android.database.sqlite.SQLiteException;
12 | import android.database.sqlite.SQLiteOpenHelper;
13 |
14 | import com.jensdriller.contentproviderhelper.app.ContentProviderHelper;
15 |
16 | public class Database extends SQLiteOpenHelper {
17 |
18 | public static final String COLUMN_ID = "_id";
19 | public static final String COLUMN_URI = "uri";
20 |
21 | private static final int DB_VERSION = 1;
22 | private static final String DB_NAME = Database.class.getPackage().getName();
23 | private static final String DB_CREATE = "CREATE TABLE uris (_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, uri TEXT) ";
24 | private static final String TABLE_NAME = "uris";
25 | private static final String DB_DROP = "DROP TABLE IF EXISTS " + TABLE_NAME;
26 |
27 | private Context mContext;
28 |
29 | public Database(Context context) {
30 | super(context, DB_NAME, null, DB_VERSION);
31 |
32 | mContext = context;
33 | }
34 |
35 | @Override
36 | public void onCreate(SQLiteDatabase db) {
37 | try {
38 | db.execSQL(DB_CREATE);
39 | } catch (SQLiteException e) {
40 | ContentProviderHelper.handleException(mContext, e, true);
41 | }
42 | }
43 |
44 | @Override
45 | public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
46 | try {
47 | db.execSQL(DB_DROP);
48 | onCreate(db);
49 | } catch (SQLException e) {
50 | ContentProviderHelper.handleException(mContext, e, true);
51 | }
52 | }
53 |
54 | public List getAllUris() {
55 | List uris = new ArrayList();
56 | SQLiteDatabase db = null;
57 | Cursor cursor = null;
58 |
59 | try {
60 | db = getReadableDatabase();
61 |
62 | cursor = db.rawQuery("SELECT * FROM " + TABLE_NAME, null);
63 | if (cursor.moveToFirst()) {
64 | do {
65 | uris.add(cursor.getString(cursor.getColumnIndex(COLUMN_URI)));
66 | } while (cursor.moveToNext());
67 | }
68 | } catch (SQLException e) {
69 | ContentProviderHelper.handleException(mContext, e, true);
70 | } finally {
71 | if (cursor != null) {
72 | cursor.close();
73 | }
74 | if (db != null) {
75 | db.close();
76 | }
77 | }
78 |
79 | return uris;
80 | }
81 |
82 | public long insert(String uri) {
83 | SQLiteDatabase db = null;
84 | long id = -1;
85 |
86 | try {
87 | db = getWritableDatabase();
88 |
89 | ContentValues values = new ContentValues();
90 | values.put(COLUMN_URI, uri);
91 | id = db.insert(TABLE_NAME, null, values);
92 | } catch (SQLException e) {
93 | ContentProviderHelper.handleException(mContext, e, true);
94 | } finally {
95 | if (db != null) {
96 | db.close();
97 | }
98 | }
99 |
100 | return id;
101 | }
102 |
103 | public int delete(String uri) {
104 | SQLiteDatabase db = null;
105 | int count = 0;
106 |
107 | try {
108 | db = getWritableDatabase();
109 |
110 | count = db.delete(TABLE_NAME, COLUMN_URI + " = ?", new String[] { uri });
111 | } catch (SQLiteException e) {
112 | ContentProviderHelper.handleException(mContext, e, true);
113 | } finally {
114 | if (db != null) {
115 | db.close();
116 | }
117 | }
118 |
119 | return count;
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/src/com/jensdriller/contentproviderhelper/model/Column.java:
--------------------------------------------------------------------------------
1 | package com.jensdriller.contentproviderhelper.model;
2 |
3 | import android.annotation.TargetApi;
4 | import android.database.Cursor;
5 | import android.os.Build;
6 | import android.os.Parcel;
7 | import android.os.Parcelable;
8 |
9 | public class Column implements Parcelable {
10 |
11 | private String mName;
12 | private boolean mIsChecked;
13 | private int mType;
14 |
15 | public Column(String name, boolean isChecked) {
16 | mName = name;
17 | mIsChecked = isChecked;
18 | }
19 |
20 | protected Column(Parcel in) {
21 | readFromParcel(in);
22 | }
23 |
24 | public String getName() {
25 | return mName;
26 | }
27 |
28 | public void setName(String name) {
29 | mName = name;
30 | }
31 |
32 | public int getType() {
33 | return mType;
34 | }
35 |
36 | public void setType(int type) {
37 | mType = type;
38 | }
39 |
40 | public boolean isChecked() {
41 | return mIsChecked;
42 | }
43 |
44 | public void setChecked(boolean isChecked) {
45 | mIsChecked = isChecked;
46 | }
47 |
48 | @TargetApi(Build.VERSION_CODES.HONEYCOMB)
49 | public String getDisplayType() {
50 | switch (mType) {
51 | case Cursor.FIELD_TYPE_BLOB:
52 | return "Cursor.FIELD_TYPE_BLOB (" + Cursor.FIELD_TYPE_BLOB + ")";
53 | case Cursor.FIELD_TYPE_FLOAT:
54 | return "Cursor.FIELD_TYPE_FLOAT (" + Cursor.FIELD_TYPE_FLOAT + ")";
55 | case Cursor.FIELD_TYPE_INTEGER:
56 | return "Cursor.FIELD_TYPE_INTEGER (" + Cursor.FIELD_TYPE_INTEGER + ")";
57 | case Cursor.FIELD_TYPE_NULL:
58 | return "Cursor.FIELD_TYPE_NULL (" + Cursor.FIELD_TYPE_NULL + ")";
59 | case Cursor.FIELD_TYPE_STRING:
60 | return "Cursor.FIELD_TYPE_STRING (" + Cursor.FIELD_TYPE_STRING + ")";
61 | default:
62 | return "Unknown";
63 | }
64 | }
65 |
66 | @Override
67 | public String toString() {
68 | return mName;
69 | }
70 |
71 | @Override
72 | public int describeContents() {
73 | return 0;
74 | }
75 |
76 | @Override
77 | public void writeToParcel(Parcel dest, int flags) {
78 | dest.writeString(mName);
79 | dest.writeInt(mType);
80 | dest.writeByte((byte) (mIsChecked ? 0x01 : 0x00));
81 | }
82 |
83 | private void readFromParcel(Parcel in) {
84 | mName = in.readString();
85 | mType = in.readInt();
86 | mIsChecked = in.readByte() != 0x00;
87 | }
88 |
89 | public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
90 |
91 | @Override
92 | public Column createFromParcel(Parcel source) {
93 | return new Column(source);
94 | }
95 |
96 | @Override
97 | public Column[] newArray(int size) {
98 | return new Column[size];
99 | }
100 | };
101 |
102 | }
103 |
--------------------------------------------------------------------------------
/src/com/jensdriller/contentproviderhelper/model/ColumnData.java:
--------------------------------------------------------------------------------
1 | package com.jensdriller.contentproviderhelper.model;
2 |
3 | import android.os.Parcel;
4 | import android.os.Parcelable;
5 |
6 | public class ColumnData implements Parcelable {
7 |
8 | private int mRowCount;
9 | private ColumnList mColumnList;
10 |
11 | public ColumnData() {
12 | mColumnList = new ColumnList();
13 | }
14 |
15 | protected ColumnData(Parcel in) {
16 | readFromParcel(in);
17 | }
18 |
19 | public void setRowCount(int rowCount) {
20 | mRowCount = rowCount;
21 | }
22 |
23 | public void setColumnList(ColumnList columnList) {
24 | mColumnList = columnList;
25 | }
26 |
27 | public int getRowCount() {
28 | return mRowCount;
29 | }
30 |
31 | public ColumnList getColumnList() {
32 | return mColumnList;
33 | }
34 |
35 | @Override
36 | public int describeContents() {
37 | return 0;
38 | }
39 |
40 | @Override
41 | public void writeToParcel(Parcel dest, int flags) {
42 | dest.writeInt(mRowCount);
43 | dest.writeParcelable(mColumnList, flags);
44 | }
45 |
46 | private void readFromParcel(Parcel in) {
47 | mRowCount = in.readInt();
48 | mColumnList = in.readParcelable(ColumnList.class.getClassLoader());
49 | }
50 |
51 | public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
52 |
53 | @Override
54 | public ColumnData createFromParcel(Parcel source) {
55 | return new ColumnData(source);
56 | }
57 |
58 | @Override
59 | public ColumnData[] newArray(int size) {
60 | return new ColumnData[size];
61 | }
62 | };
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/src/com/jensdriller/contentproviderhelper/model/ColumnList.java:
--------------------------------------------------------------------------------
1 | package com.jensdriller.contentproviderhelper.model;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import android.os.Parcel;
7 | import android.os.Parcelable;
8 |
9 | public class ColumnList implements Parcelable {
10 |
11 | private List mColumns;
12 |
13 | public ColumnList() {
14 | mColumns = new ArrayList();
15 | }
16 |
17 | protected ColumnList(Parcel in) {
18 | readFromParcel(in);
19 | }
20 |
21 | public List getColumns() {
22 | return mColumns;
23 | }
24 |
25 | public void setColumns(List columns) {
26 | mColumns = columns;
27 | }
28 |
29 | public void add(Column column) {
30 | mColumns.add(column);
31 | }
32 |
33 | public void setAllChecked(boolean isChecked) {
34 | for (Column column : mColumns) {
35 | column.setChecked(isChecked);
36 | }
37 | }
38 |
39 | public boolean isAnyColumnChecked() {
40 | for (Column column : mColumns) {
41 | if (column.isChecked()) {
42 | return true;
43 | }
44 | }
45 | return false;
46 | }
47 |
48 | public ColumnList getCheckedColumns() {
49 | ColumnList checkedColumns = new ColumnList();
50 | for (Column column : mColumns) {
51 | if (column.isChecked()) {
52 | checkedColumns.add(column);
53 | }
54 | }
55 | return checkedColumns;
56 | }
57 |
58 | public void clear() {
59 | mColumns.clear();
60 | }
61 |
62 | public void addAll(List columns) {
63 | mColumns.addAll(columns);
64 | }
65 |
66 | public Column get(int location) {
67 | return mColumns.get(location);
68 | }
69 |
70 | public int size() {
71 | return mColumns.size();
72 | }
73 |
74 | @Override
75 | public int describeContents() {
76 | return 0;
77 | }
78 |
79 | @Override
80 | public void writeToParcel(Parcel dest, int flags) {
81 | dest.writeList(mColumns);
82 | }
83 |
84 | private void readFromParcel(Parcel in) {
85 | mColumns = new ArrayList();
86 | in.readList(mColumns, Column.class.getClassLoader());
87 | }
88 |
89 | public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
90 |
91 | @Override
92 | public ColumnList createFromParcel(Parcel source) {
93 | return new ColumnList(source);
94 | }
95 |
96 | @Override
97 | public ColumnList[] newArray(int size) {
98 | return new ColumnList[size];
99 | }
100 | };
101 |
102 | }
103 |
--------------------------------------------------------------------------------
/src/com/jensdriller/contentproviderhelper/model/Result.java:
--------------------------------------------------------------------------------
1 | package com.jensdriller.contentproviderhelper.model;
2 |
3 | import java.io.File;
4 |
5 | import android.os.Parcel;
6 | import android.os.Parcelable;
7 |
8 | public class Result implements Parcelable {
9 |
10 | private int mRowCount;
11 | private File mFile;
12 |
13 | public Result() {
14 |
15 | }
16 |
17 | protected Result(Parcel in) {
18 | readFromParcel(in);
19 | }
20 |
21 | public int getRowCount() {
22 | return mRowCount;
23 | }
24 |
25 | public void setRowCount(int rowCount) {
26 | mRowCount = rowCount;
27 | }
28 |
29 | public File getFile() {
30 | return mFile;
31 | }
32 |
33 | public void setFile(File file) {
34 | mFile = file;
35 | }
36 |
37 | @Override
38 | public int describeContents() {
39 | return 0;
40 | }
41 |
42 | @Override
43 | public void writeToParcel(Parcel dest, int flags) {
44 | dest.writeInt(mRowCount);
45 | dest.writeSerializable(mFile);
46 | }
47 |
48 | private void readFromParcel(Parcel in) {
49 | mRowCount = in.readInt();
50 | mFile = (File) in.readSerializable();
51 | }
52 |
53 | public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
54 |
55 | @Override
56 | public Result createFromParcel(Parcel in) {
57 | return new Result(in);
58 | }
59 |
60 | @Override
61 | public Result[] newArray(int size) {
62 | return new Result[size];
63 | }
64 | };
65 | }
66 |
--------------------------------------------------------------------------------
/src/com/jensdriller/contentproviderhelper/provider/FileProvider.java:
--------------------------------------------------------------------------------
1 | package com.jensdriller.contentproviderhelper.provider;
2 |
3 | import java.io.File;
4 | import java.io.FileNotFoundException;
5 |
6 | import com.jensdriller.contentproviderhelper.ui.activity.ResultActivity;
7 |
8 | import android.content.ContentProvider;
9 | import android.content.ContentValues;
10 | import android.database.Cursor;
11 | import android.net.Uri;
12 | import android.os.ParcelFileDescriptor;
13 |
14 | public class FileProvider extends ContentProvider {
15 |
16 | @Override
17 | public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
18 | File fileDir = getContext().getFilesDir();
19 | File privateFile = new File(fileDir, ResultActivity.RESULTS_FILE_NAME);
20 |
21 | return ParcelFileDescriptor.open(privateFile, ParcelFileDescriptor.MODE_READ_ONLY);
22 | }
23 |
24 | @Override
25 | public boolean onCreate() {
26 | return true;
27 | }
28 |
29 | @Override
30 | public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
31 | return null;
32 | }
33 |
34 | @Override
35 | public String getType(Uri uri) {
36 | return null;
37 | }
38 |
39 | @Override
40 | public Uri insert(Uri uri, ContentValues values) {
41 | return null;
42 | }
43 |
44 | @Override
45 | public int delete(Uri uri, String selection, String[] selectionArgs) {
46 | return 0;
47 | }
48 |
49 | @Override
50 | public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
51 | return 0;
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/src/com/jensdriller/contentproviderhelper/task/DialogAsyncTask.java:
--------------------------------------------------------------------------------
1 | package com.jensdriller.contentproviderhelper.task;
2 |
3 | import android.annotation.TargetApi;
4 | import android.content.Context;
5 | import android.os.AsyncTask;
6 | import android.os.Build;
7 |
8 | import com.jensdriller.contentproviderhelper.app.ContentProviderHelper;
9 | import com.jensdriller.contentproviderhelper.ui.dialog.ProgressDialogFragment;
10 |
11 | public abstract class DialogAsyncTask extends AsyncTask {
12 |
13 | protected Context mContext;
14 | protected Exception mException;
15 | protected ExceptionListener mExceptionListener;
16 |
17 | private ProgressDialogFragment mDialogFragment;
18 |
19 | public interface ExceptionListener {
20 | void onException(Exception e);
21 | }
22 |
23 | public DialogAsyncTask(Context context) {
24 | mContext = context;
25 | }
26 |
27 | public void setExceptionListener(ExceptionListener exceptionListener) {
28 | mExceptionListener = exceptionListener;
29 | }
30 |
31 | public void setDialogFragment(ProgressDialogFragment dialogFragment) {
32 | mDialogFragment = dialogFragment;
33 | }
34 |
35 | @Override
36 | protected void onPreExecute() {
37 | super.onPreExecute();
38 |
39 | if (mDialogFragment != null) {
40 | mDialogFragment.notifyOnPreExecute();
41 | }
42 | }
43 |
44 | @Override
45 | protected void onProgressUpdate(Progress... values) {
46 | super.onProgressUpdate(values);
47 |
48 | if (mDialogFragment != null) {
49 | mDialogFragment.notifyOnProgressUpdate(values);
50 | }
51 | }
52 |
53 | @Override
54 | protected void onPostExecute(Result result) {
55 | super.onPostExecute(result);
56 |
57 | if (mException != null) {
58 | ContentProviderHelper.handleException(mContext, mException, false);
59 | if (mExceptionListener != null) {
60 | mExceptionListener.onException(mException);
61 | }
62 | }
63 |
64 | if (mDialogFragment != null) {
65 | mDialogFragment.notifyOnPostExecute(result);
66 | }
67 | }
68 |
69 | @Override
70 | protected void onCancelled() {
71 | super.onCancelled();
72 |
73 | if (mDialogFragment != null) {
74 | mDialogFragment.notifyOnCancelled();
75 | }
76 | }
77 |
78 | @TargetApi(Build.VERSION_CODES.HONEYCOMB)
79 | @Override
80 | protected void onCancelled(Result result) {
81 | super.onCancelled(result);
82 |
83 | if (mDialogFragment != null) {
84 | mDialogFragment.notifyOnCancelled(result);
85 | }
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/src/com/jensdriller/contentproviderhelper/task/LoadColumnsTask.java:
--------------------------------------------------------------------------------
1 | package com.jensdriller.contentproviderhelper.task;
2 |
3 | import android.annotation.TargetApi;
4 | import android.content.Context;
5 | import android.database.Cursor;
6 | import android.net.Uri;
7 | import android.os.Build;
8 |
9 | import com.jensdriller.contentproviderhelper.R;
10 | import com.jensdriller.contentproviderhelper.model.Column;
11 | import com.jensdriller.contentproviderhelper.model.ColumnData;
12 | import com.jensdriller.contentproviderhelper.model.ColumnList;
13 |
14 | public class LoadColumnsTask extends DialogAsyncTask {
15 |
16 | public LoadColumnsTask(Context context) {
17 | super(context);
18 | }
19 |
20 | @TargetApi(Build.VERSION_CODES.HONEYCOMB)
21 | @Override
22 | protected ColumnData doInBackground(Uri... params) {
23 | ColumnData columnData = new ColumnData();
24 | ColumnList columnList = new ColumnList();
25 | columnData.setColumnList(columnList);
26 | Cursor cursor = null;
27 |
28 | try {
29 | cursor = mContext.getContentResolver().query(params[0], null, null, null, null);
30 |
31 | if (cursor == null) {
32 | throw new IllegalArgumentException(mContext.getString(R.string.invalid_content_provider));
33 | }
34 |
35 | if (!cursor.moveToFirst()) { // Cursor is empty
36 | return columnData;
37 | }
38 |
39 | columnData.setRowCount(cursor.getCount());
40 | int count = cursor.getColumnCount();
41 | for (int i = 0; i < count; i++) {
42 | String name = cursor.getColumnName(i);
43 | Column column = new Column(name, true);
44 |
45 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
46 | int type = cursor.getType(i);
47 | column.setType(type);
48 | }
49 |
50 | columnList.add(column);
51 | }
52 |
53 | } catch (Exception e) {
54 | mException = e;
55 | } finally {
56 | if (cursor != null) {
57 | cursor.close();
58 | }
59 | }
60 |
61 | return columnData;
62 | }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/src/com/jensdriller/contentproviderhelper/task/LoadResultsTask.java:
--------------------------------------------------------------------------------
1 | package com.jensdriller.contentproviderhelper.task;
2 |
3 | import java.io.File;
4 | import java.io.FileWriter;
5 | import java.io.IOException;
6 |
7 | import android.content.Context;
8 | import android.database.Cursor;
9 | import android.net.Uri;
10 |
11 | import com.jensdriller.contentproviderhelper.R;
12 | import com.jensdriller.contentproviderhelper.model.ColumnList;
13 | import com.jensdriller.contentproviderhelper.model.Result;
14 | import com.jensdriller.contentproviderhelper.ui.activity.ResultActivity;
15 |
16 | public class LoadResultsTask extends DialogAsyncTask {
17 |
18 | private static final String HTML_HEADER = "Content Provider Helper";
19 | private static final String HTML_FOOTER = "