Add "save to file" option for screenshots (+ lots of XML formatting)

This commit is contained in:
fkloft 2014-03-01 22:43:26 +01:00
parent 83ead3a358
commit f43cfeb5aa
20 changed files with 113 additions and 67 deletions

View File

@ -80,8 +80,8 @@
<category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/> <category android:name="android.intent.category.BROWSABLE"/>
<data android:mimeType="application/x-javascript" /> <data android:mimeType="application/x-javascript"/>
<data android:mimeType="text/javascript" /> <data android:mimeType="text/javascript"/>
</intent-filter> </intent-filter>
<intent-filter> <intent-filter>
<action android:name="android.intent.action.VIEW"/> <action android:name="android.intent.action.VIEW"/>
@ -92,23 +92,20 @@
<data <data
android:host="*" android:host="*"
android:scheme="file" android:pathPattern=".*\\.user.js"
android:pathPattern=".*\\.user.js"/> android:scheme="file"/>
<data <data
android:host="*" android:host="*"
android:scheme="content" android:pathPattern=".*\\.user.js"
android:pathPattern=".*\\.user.js"/> android:scheme="content"/>
<data <data
android:host="*" android:host="*"
android:scheme="http" android:pathPattern=".*\\.user.js"
android:pathPattern=".*\\.user.js"/> android:scheme="http"/>
<data <data
android:host="*" android:host="*"
android:scheme="https" android:pathPattern=".*\\.user.js"
android:pathPattern=".*\\.user.js"/> android:scheme="https"/>
</intent-filter> </intent-filter>
<!-- Points to searchable meta data. --> <!-- Points to searchable meta data. -->
@ -149,6 +146,15 @@
<data android:mimeType="text/plain"/> <data android:mimeType="text/plain"/>
</intent-filter> </intent-filter>
</activity> </activity>
<activity
android:name="com.cradle.iitc_mobile.share.SaveToFile"
android:enabled="true"
android:excludeFromRecents="true"
android:exported="false"
android:icon="@drawable/ic_action_save"
android:label="@string/activity_save_to_file"
android:noHistory="false"
android:theme="@android:style/Theme.Holo.Dialog"/>
<!-- START Used for Samsung Multi-Window support --> <!-- START Used for Samsung Multi-Window support -->
<uses-library <uses-library

View File

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout" android:id="@+id/drawer_layout"

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android" <android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/pager" android:id="@+id/pager"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".ShareActivity"/> tools:context=".ShareActivity"/>

View File

@ -1,6 +1,11 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<ProgressBar xmlns:android="http://schemas.android.com/apk/res/android" <ProgressBar xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/progressBarLoading" android:id="@+id/progressBarLoading"
style="?android:attr/progressBarStyleLarge" style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content"/> android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"/>

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -7,7 +6,7 @@
android:baselineAligned="false" android:baselineAligned="false"
android:gravity="center_vertical" android:gravity="center_vertical"
android:minHeight="48dp" android:minHeight="48dp"
android:paddingRight="?android:attr/scrollbarSize" > android:paddingRight="?android:attr/scrollbarSize">
<RelativeLayout <RelativeLayout
android:layout_width="0dip" android:layout_width="0dip"
@ -16,7 +15,7 @@
android:layout_marginLeft="6dip" android:layout_marginLeft="6dip"
android:layout_marginRight="6dip" android:layout_marginRight="6dip"
android:layout_marginTop="6dip" android:layout_marginTop="6dip"
android:layout_weight="1" > android:layout_weight="1">
<TextView <TextView
android:id="@+id/plug_pref_title" android:id="@+id/plug_pref_title"
@ -25,7 +24,7 @@
android:ellipsize="marquee" android:ellipsize="marquee"
android:fadingEdge="horizontal" android:fadingEdge="horizontal"
android:singleLine="true" android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceMedium" /> android:textAppearance="?android:attr/textAppearanceMedium"/>
<TextView <TextView
android:id="@+id/plug_pref_summary" android:id="@+id/plug_pref_summary"
@ -34,7 +33,7 @@
android:layout_below="@android:id/title" android:layout_below="@android:id/title"
android:ellipsize="end" android:ellipsize="end"
android:maxLines="2" android:maxLines="2"
android:textAppearance="?android:attr/textAppearanceSmall" /> android:textAppearance="?android:attr/textAppearanceSmall"/>
</RelativeLayout> </RelativeLayout>
</LinearLayout> </LinearLayout>

View File

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <menu xmlns:android="http://schemas.android.com/apk/res/android">
<item <item

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <menu xmlns:android="http://schemas.android.com/apk/res/android">
<item <item

View File

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<!-- <!--

View File

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<!-- <!--

View File

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<!-- <!--

View File

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<!-- <!--

View File

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<!-- Default screen margins, per the Android Design guidelines. --> <!-- Default screen margins, per the Android Design guidelines. -->
@ -8,7 +9,10 @@
<dimen name="app_minimumsize_w">400dip</dimen> <dimen name="app_minimumsize_w">400dip</dimen>
<dimen name="app_minimumsize_h">200dip</dimen> <dimen name="app_minimumsize_h">200dip</dimen>
<!-- margin around app icons in share activity -->
<dimen name="icon_margin">8dp</dimen> <dimen name="icon_margin">8dp</dimen>
<!-- button size for debug views -->
<dimen name="button_size">36dp</dimen>
</resources> </resources>

View File

@ -8,6 +8,7 @@
<string name="activity_plugins">IITC Plugins</string> <string name="activity_plugins">IITC Plugins</string>
<string name="activity_share">Share using…</string> <string name="activity_share">Share using…</string>
<string name="activity_share_to_clipboard">Copy to clipboard</string> <string name="activity_share_to_clipboard">Copy to clipboard</string>
<string name="activity_save_to_file">Save to file</string>
<string name="action_settings">Settings</string> <string name="action_settings">Settings</string>
<string name="drawer_open">Show navigation menu</string> <string name="drawer_open">Show navigation menu</string>
<string name="drawer_close">Hide navigation menu</string> <string name="drawer_close">Hide navigation menu</string>
@ -185,4 +186,4 @@
Are you sure you want to proceed?]]> Are you sure you want to proceed?]]>
</string> </string>
</resources> </resources>

View File

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<!-- <!--
@ -19,6 +20,4 @@
<color name="drawer_background">#99111111</color> <color name="drawer_background">#99111111</color>
<dimen name="button_size">36dp</dimen>
</resources> </resources>

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen> <PreferenceScreen>
<!-- empty...we will build the prefs in PluginsFragment -->
<!-- empty...we will build the prefs in PluginsFragment -->
</PreferenceScreen> </PreferenceScreen>

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory <PreferenceCategory
android:key="pref_ui_cat" android:key="pref_ui_cat"
android:title="@string/pref_ui_cat"> android:title="@string/pref_ui_cat">
@ -36,8 +37,8 @@
android:fragment="com.cradle.iitc_mobile.fragments.PluginsFragment" android:fragment="com.cradle.iitc_mobile.fragments.PluginsFragment"
android:key="pref_plugins" android:key="pref_plugins"
android:persistent="false" android:persistent="false"
android:title="@string/pref_plugins" android:summary="@string/pref_plugins_sum"
android:summary="@string/pref_plugins_sum"> android:title="@string/pref_plugins">
<intent <intent
android:targetClass="com.cradle.iitc_mobile.IITC_PluginPreferenceActivity" android:targetClass="com.cradle.iitc_mobile.IITC_PluginPreferenceActivity"
android:targetPackage="com.cradle.iitc_mobile"/> android:targetPackage="com.cradle.iitc_mobile"/>
@ -60,18 +61,19 @@
android:title="@string/pref_press_twice_to_exit"/> android:title="@string/pref_press_twice_to_exit"/>
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory <PreferenceCategory
android:key="pref_mics" android:key="pref_mics"
android:title="@string/pref_misc_cat"> android:title="@string/pref_misc_cat">
<PreferenceScreen <PreferenceScreen
android:key="pref_developer_screen" android:key="pref_developer_screen"
android:persistent="false" android:persistent="false"
android:title="@string/pref_advanced_options" android:summary="@string/pref_advanced_options_sum"
android:summary="@string/pref_advanced_options_sum"> android:title="@string/pref_advanced_options">
<CheckBoxPreference <CheckBoxPreference
android:defaultValue="false" android:defaultValue="false"
android:key="pref_dev_checkbox" android:key="pref_dev_checkbox"
android:summary="@string/pref_enable_dev_mode_sum" android:summary="@string/pref_enable_dev_mode_sum"
android:title="@string/pref_enable_dev_mode"/> android:title="@string/pref_enable_dev_mode"/>
<PreferenceCategory <PreferenceCategory
android:key="pref_advanced_ui_cat" android:key="pref_advanced_ui_cat"
android:title="@string/pref_ui_cat"> android:title="@string/pref_ui_cat">
@ -106,4 +108,4 @@
</PreferenceScreen> </PreferenceScreen>
</PreferenceCategory> </PreferenceCategory>
</PreferenceScreen> </PreferenceScreen>

View File

@ -1,8 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android" <searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/app_name" android:hint="@string/search_hint"
android:hint="@string/search_hint" android:label="@string/app_name"
android:voiceSearchMode="showVoiceSearchButton|launchRecognizer" android:voiceLanguageModel="web_search"
android:voiceLanguageModel="web_search" android:voiceMaxResults="1"
android:voiceMaxResults="1"> android:voiceSearchMode="showVoiceSearchButton|launchRecognizer"/>
</searchable>

View File

@ -63,8 +63,7 @@ public class IITC_FileManager {
* @throws IOException * @throws IOException
*/ */
public static void copyStream(final InputStream inStream, final OutputStream outStream, final boolean closeOutput) public static void copyStream(final InputStream inStream, final OutputStream outStream, final boolean closeOutput)
throws IOException throws IOException {
{
// in case Android includes Apache commons IO in the future, this function should be replaced by IOUtils.copy // in case Android includes Apache commons IO in the future, this function should be replaced by IOUtils.copy
final int bufferSize = 4096; final int bufferSize = 4096;
final byte[] buffer = new byte[bufferSize]; final byte[] buffer = new byte[bufferSize];
@ -94,20 +93,20 @@ public class IITC_FileManager {
map.put("name", "unknown"); map.put("name", "unknown");
map.put("description", ""); map.put("description", "");
map.put("category", "Misc"); map.put("category", "Misc");
BufferedReader reader = new BufferedReader(new StringReader(header)); final BufferedReader reader = new BufferedReader(new StringReader(header));
String headerLine; String headerLine;
try { try {
while ((headerLine = reader.readLine()) != null) { while ((headerLine = reader.readLine()) != null) {
if (headerLine.matches("//.*@.*")) { if (headerLine.matches("//.*@.*")) {
// get start of key name (first @ in line) // get start of key name (first @ in line)
String[] keyStart = headerLine.split("@", 2); final String[] keyStart = headerLine.split("@", 2);
// split key value // split key value
String[] keyValue = keyStart[1].split(" ", 2); final String[] keyValue = keyStart[1].split(" ", 2);
// remove whitespaces from string begin and end and push to map // remove whitespaces from string begin and end and push to map
map.put(keyValue[0].trim(), keyValue[1].trim()); map.put(keyValue[0].trim(), keyValue[1].trim());
} }
} }
} catch (IOException e) { } catch (final IOException e) {
Log.w(e); Log.w(e);
} }
return map; return map;
@ -279,7 +278,7 @@ public class IITC_FileManager {
InputStream is; InputStream is;
String fileName; String fileName;
if (uri.getScheme().contains("http")) { if (uri.getScheme().contains("http")) {
URLConnection conn = new URL(url).openConnection(); final URLConnection conn = new URL(url).openConnection();
is = conn.getInputStream(); is = conn.getInputStream();
fileName = uri.getLastPathSegment(); fileName = uri.getLastPathSegment();
} else { } else {

View File

@ -7,6 +7,7 @@ import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo; import android.content.pm.ResolveInfo;
import android.net.Uri; import android.net.Uri;
import android.os.Build;
import com.cradle.iitc_mobile.Log; import com.cradle.iitc_mobile.Log;
import com.cradle.iitc_mobile.R; import com.cradle.iitc_mobile.R;
@ -136,6 +137,14 @@ public class IntentGenerator {
return targets; return targets;
} }
/**
* get a list of intents capable of sharing a plain text string
*
* @param title
* description of the shared string
* @param text
* the string to be shared
*/
public ArrayList<Intent> getShareIntents(final String title, final String text) { public ArrayList<Intent> getShareIntents(final String title, final String text) {
final Intent intent = new Intent(Intent.ACTION_SEND) final Intent intent = new Intent(Intent.ACTION_SEND)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) .addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET)
@ -155,11 +164,29 @@ public class IntentGenerator {
return targets; return targets;
} }
public ArrayList<Intent> getShareIntents(final String title, final Uri uri, final String type) { /**
return resolveTargets(new Intent(Intent.ACTION_SEND) * get a list of intents capable of sharing the given content
*
* @param uri
* URI of a file to share
* @param type
* MIME type of the file
*/
public ArrayList<Intent> getShareIntents(final Uri uri, final String type) {
final Intent intent = new Intent(Intent.ACTION_SEND)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) .addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET)
.setType(type) .setType(type)
.putExtra(Intent.EXTRA_SUBJECT, title) .putExtra(Intent.EXTRA_SUBJECT, uri.getLastPathSegment())
.putExtra(Intent.EXTRA_STREAM, uri)); .putExtra(Intent.EXTRA_STREAM, uri);
final ArrayList<Intent> targets = resolveTargets(intent);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
targets.add(new Intent(intent)
.setComponent(new ComponentName(mContext, SaveToFile.class))
.putExtra(EXTRA_FLAG_TITLE, mContext.getString(R.string.activity_save_to_file)));
}
return targets;
} }
} }

View File

@ -55,7 +55,6 @@ public class ShareActivity extends FragmentActivity implements ActionBar.TabList
private FragmentAdapter mFragmentAdapter; private FragmentAdapter mFragmentAdapter;
private IntentGenerator mGenerator; private IntentGenerator mGenerator;
private SharedPreferences mSharedPrefs = null; private SharedPreferences mSharedPrefs = null;
private String mTitle;
private ViewPager mViewPager; private ViewPager mViewPager;
private void addTab(final ArrayList<Intent> intents, final int label, final int icon) { private void addTab(final ArrayList<Intent> intents, final int label, final int icon) {
@ -115,34 +114,33 @@ public class ShareActivity extends FragmentActivity implements ActionBar.TabList
final String type = intent.getStringExtra(EXTRA_TYPE); final String type = intent.getStringExtra(EXTRA_TYPE);
// from portallinks/permalinks we build 3 intents (share / geo / vanilla-intel-link) // from portallinks/permalinks we build 3 intents (share / geo / vanilla-intel-link)
if (TYPE_PERMALINK.equals(type) || TYPE_PORTAL_LINK.equals(type)) { if (TYPE_PERMALINK.equals(type) || TYPE_PORTAL_LINK.equals(type)) {
mTitle = intent.getStringExtra("title"); final String title = intent.getStringExtra("title");
final String ll = intent.getDoubleExtra("lat", 0) + "," + intent.getDoubleExtra("lng", 0); final String ll = intent.getDoubleExtra("lat", 0) + "," + intent.getDoubleExtra("lng", 0);
final int zoom = intent.getIntExtra("zoom", 0); final int zoom = intent.getIntExtra("zoom", 0);
final String url = getIntelUrl(ll, zoom, TYPE_PORTAL_LINK.equals(type)); final String url = getIntelUrl(ll, zoom, TYPE_PORTAL_LINK.equals(type));
actionBar.setTitle(mTitle); actionBar.setTitle(title);
addTab(mGenerator.getShareIntents(mTitle, url), addTab(mGenerator.getShareIntents(title, url),
R.string.tab_share, R.string.tab_share,
R.drawable.ic_action_share); R.drawable.ic_action_share);
addTab(mGenerator.getGeoIntents(mTitle, ll, zoom), addTab(mGenerator.getGeoIntents(title, ll, zoom),
R.string.tab_map, R.string.tab_map,
R.drawable.ic_action_place); R.drawable.ic_action_place);
addTab(mGenerator.getBrowserIntents(mTitle, url), addTab(mGenerator.getBrowserIntents(title, url),
R.string.tab_browser, R.string.tab_browser,
R.drawable.ic_action_web_site); R.drawable.ic_action_web_site);
} else if (TYPE_STRING.equals(type)) { } else if (TYPE_STRING.equals(type)) {
mTitle = getString(R.string.app_name); final String title = getString(R.string.app_name);
final String shareString = intent.getStringExtra("shareString"); final String shareString = intent.getStringExtra("shareString");
addTab(mGenerator.getShareIntents(mTitle, shareString), R.string.tab_share, R.drawable.ic_action_share); addTab(mGenerator.getShareIntents(title, shareString), R.string.tab_share, R.drawable.ic_action_share);
} else if (TYPE_FILE.equals(type)) { } else if (TYPE_FILE.equals(type)) {
mTitle = "Screenshot";
final Uri uri = intent.getParcelableExtra("uri"); final Uri uri = intent.getParcelableExtra("uri");
final String mime = intent.getStringExtra("type"); final String mime = intent.getStringExtra("type");
addTab(mGenerator.getShareIntents(mTitle, uri, mime), R.string.tab_share, R.drawable.ic_action_share); addTab(mGenerator.getShareIntents(uri, mime), R.string.tab_share, R.drawable.ic_action_share);
} else { } else {
Log.w("Unknown sharing type: " + type); Log.w("Unknown sharing type: " + type);
setResult(RESULT_CANCELED); setResult(RESULT_CANCELED);