├── .gitignore ├── libs └── android-support-v13.jar ├── src └── main │ ├── res │ ├── drawable-hdpi │ │ ├── logo.png │ │ └── ic_launcher.png │ ├── drawable-mdpi │ │ ├── logo.png │ │ └── ic_launcher.png │ ├── drawable │ │ ├── sd_card.png │ │ ├── settings.png │ │ └── settings_open.png │ ├── drawable-xhdpi │ │ ├── logo.png │ │ └── ic_launcher.png │ ├── drawable-xxhdpi │ │ ├── logo.png │ │ └── ic_launcher.png │ ├── drawable-sw600dp │ │ ├── sd_card.png │ │ ├── settings.png │ │ └── settings_open.png │ ├── values-land │ │ └── dimens.xml │ ├── values │ │ ├── dimens.xml │ │ ├── styles.xml │ │ └── strings.xml │ ├── values-v11 │ │ └── styles.xml │ ├── layout │ │ ├── activity_help.xml │ │ └── fragment_help.xml │ ├── values-w820dp │ │ └── dimens.xml │ └── values-v14 │ │ └── styles.xml │ ├── AndroidManifest.xml │ └── java │ └── de │ └── nsvb │ └── catchemall │ ├── HelpActivity.java │ └── CatchActivity.java ├── README.md └── app.iml /.gitignore: -------------------------------------------------------------------------------- 1 | build -------------------------------------------------------------------------------- /libs/android-support-v13.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ns130291/Catch-EmAll/master/libs/android-support-v13.jar -------------------------------------------------------------------------------- /src/main/res/drawable-hdpi/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ns130291/Catch-EmAll/master/src/main/res/drawable-hdpi/logo.png -------------------------------------------------------------------------------- /src/main/res/drawable-mdpi/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ns130291/Catch-EmAll/master/src/main/res/drawable-mdpi/logo.png -------------------------------------------------------------------------------- /src/main/res/drawable/sd_card.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ns130291/Catch-EmAll/master/src/main/res/drawable/sd_card.png -------------------------------------------------------------------------------- /src/main/res/drawable/settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ns130291/Catch-EmAll/master/src/main/res/drawable/settings.png -------------------------------------------------------------------------------- /src/main/res/drawable-xhdpi/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ns130291/Catch-EmAll/master/src/main/res/drawable-xhdpi/logo.png -------------------------------------------------------------------------------- /src/main/res/drawable-xxhdpi/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ns130291/Catch-EmAll/master/src/main/res/drawable-xxhdpi/logo.png -------------------------------------------------------------------------------- /src/main/res/drawable/settings_open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ns130291/Catch-EmAll/master/src/main/res/drawable/settings_open.png -------------------------------------------------------------------------------- /src/main/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ns130291/Catch-EmAll/master/src/main/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /src/main/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ns130291/Catch-EmAll/master/src/main/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /src/main/res/drawable-sw600dp/sd_card.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ns130291/Catch-EmAll/master/src/main/res/drawable-sw600dp/sd_card.png -------------------------------------------------------------------------------- /src/main/res/drawable-sw600dp/settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ns130291/Catch-EmAll/master/src/main/res/drawable-sw600dp/settings.png -------------------------------------------------------------------------------- /src/main/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ns130291/Catch-EmAll/master/src/main/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /src/main/res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ns130291/Catch-EmAll/master/src/main/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /src/main/res/drawable-sw600dp/settings_open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ns130291/Catch-EmAll/master/src/main/res/drawable-sw600dp/settings_open.png -------------------------------------------------------------------------------- /src/main/res/values-land/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16dp 5 | 16dp 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16dp 5 | 16dp 6 | 7 | 350dp 8 | 9 | 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Catch 'Em All 2 | ============= 3 | Catch 'Em All is an Android app that allows you to save files to your SD card which are shared via the share menu. 4 | 5 | [![Get it on Google Play](http://developer.android.com/images/brand/en_generic_rgb_wo_45.png)](https://play.google.com/store/apps/details?id=de.nsvb.catchemall) 6 | -------------------------------------------------------------------------------- /src/main/res/values-v11/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/main/res/layout/activity_help.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | -------------------------------------------------------------------------------- /src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 64dp 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/main/res/values-v14/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 14 | 15 | 16 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Catch \'Em All 5 | Save with Catch \'Em All 6 | Saving failed 7 | Welcome to Catch \'Em All 8 | Catch \'Em All allows you to save files to your SD card which are shared via the share menu. 9 | To be able to save your files in any folder on your SD card you have to enable an option in the File Picker App. 10 | Open File Picker 11 | Open the settings screen via the overflow menu 12 | Enable the option \"Display advanced devices\" 13 | You\'re done! 14 | The next time you want to save a file to your SD card just choose the \"Save with Catch \'Em All\" entry in the share menu 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 12 | 13 | 18 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/main/java/de/nsvb/catchemall/HelpActivity.java: -------------------------------------------------------------------------------- 1 | package de.nsvb.catchemall; 2 | 3 | import android.app.Activity; 4 | import android.app.Fragment; 5 | import android.content.Intent; 6 | import android.os.Bundle; 7 | import android.view.LayoutInflater; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | import android.widget.Button; 11 | 12 | 13 | public class HelpActivity extends Activity { 14 | 15 | @Override 16 | protected void onCreate(Bundle savedInstanceState) { 17 | super.onCreate(savedInstanceState); 18 | getActionBar().setDisplayShowTitleEnabled(false); 19 | setContentView(R.layout.activity_help); 20 | if (savedInstanceState == null) { 21 | getFragmentManager().beginTransaction() 22 | .add(R.id.container, new HelpFragment()) 23 | .commit(); 24 | } 25 | } 26 | 27 | 28 | /*@Override 29 | public boolean onCreateOptionsMenu(Menu menu) { 30 | 31 | // Inflate the menu; this adds items to the action bar if it is present. 32 | getMenuInflater().inflate(R.menu.help, menu); 33 | return true; 34 | }*/ 35 | 36 | /* @Override 37 | public boolean onOptionsItemSelected(MenuItem item) { 38 | // Handle action bar item clicks here. The action bar will 39 | // automatically handle clicks on the Home/Up button, so long 40 | // as you specify a parent activity in AndroidManifest.xml. 41 | int id = item.getItemId(); 42 | if (id == R.id.action_settings) { 43 | return true; 44 | } 45 | return super.onOptionsItemSelected(item); 46 | }*/ 47 | 48 | /** 49 | * A placeholder fragment containing a simple view. 50 | */ 51 | public static class HelpFragment extends Fragment { 52 | 53 | public HelpFragment() { 54 | } 55 | 56 | @Override 57 | public View onCreateView(LayoutInflater inflater, ViewGroup container, 58 | Bundle savedInstanceState) { 59 | View rootView = inflater.inflate(R.layout.fragment_help, container, false); 60 | 61 | Button openFilePicker = (Button) rootView.findViewById(R.id.open_file_picker); 62 | openFilePicker.setOnClickListener(new View.OnClickListener() { 63 | @Override 64 | public void onClick(View v) { 65 | Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); 66 | intent.addCategory(Intent.CATEGORY_OPENABLE); 67 | intent.setType("*/*"); 68 | startActivityForResult(intent, 0); 69 | } 70 | }); 71 | 72 | return rootView; 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/de/nsvb/catchemall/CatchActivity.java: -------------------------------------------------------------------------------- 1 | package de.nsvb.catchemall; 2 | 3 | import java.io.FileOutputStream; 4 | import java.io.InputStream; 5 | import java.util.Set; 6 | 7 | import android.app.Activity; 8 | import android.content.Intent; 9 | import android.net.Uri; 10 | import android.os.Bundle; 11 | import android.os.ParcelFileDescriptor; 12 | import android.util.Log; 13 | import android.widget.Toast; 14 | 15 | public class CatchActivity extends Activity { 16 | 17 | private static final int WRITE_REQUEST_CODE = 42; 18 | 19 | private Intent file; 20 | private boolean txt = false; 21 | //private static final String fileIntent = "fileIntent"; 22 | 23 | @Override 24 | protected void onCreate(Bundle savedInstanceState) { 25 | super.onCreate(savedInstanceState); 26 | 27 | /*if (savedInstanceState != null) { 28 | file = (Intent) savedInstanceState.getParcelable(fileIntent); 29 | } else {*/ 30 | file = getIntent(); 31 | //} 32 | 33 | if (file != null) { 34 | // TODO: mimeType evtl. überprüfen/einschränken 35 | String type = file.getType(); 36 | // Toast.makeText(this, "Mime Type " + type, 37 | // Toast.LENGTH_LONG).show(); 38 | Log.d("", "Type " + type); 39 | Uri uri = (Uri) file.getExtras().get(Intent.EXTRA_STREAM); 40 | if (uri != null) { 41 | String data = uri.getLastPathSegment(); 42 | // Toast.makeText(this, "Data " + data, 43 | // Toast.LENGTH_LONG).show(); 44 | createFile(type, data); 45 | } else { 46 | 47 | if (type.equals("text/plain") && file.getExtras().get(Intent.EXTRA_TEXT) != null) { 48 | txt = true; 49 | String name = (String) file.getExtras().get(Intent.EXTRA_SUBJECT); 50 | if(name != null){ 51 | createFile(type, name + ".txt"); 52 | }else{ 53 | createFile(type, ""); 54 | } 55 | } else { 56 | Log.d("", "Kein Bekannter Intent-Typ"); 57 | Log.d("", file.toString()); 58 | 59 | Set keys = file.getExtras().keySet(); 60 | for (String key : keys) { 61 | Log.d("", key + " = " 62 | + file.getExtras().get(key).toString()); 63 | } 64 | 65 | saveFailed(); 66 | finish(); 67 | } 68 | } 69 | } else { 70 | Log.d("", "Intent null"); 71 | saveFailed(); 72 | finish(); 73 | } 74 | 75 | } 76 | 77 | private void createFile(String mimeType, String fileName) { 78 | Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT); 79 | 80 | // Filter to only show results that can be "opened", such as 81 | // a file (as opposed to a list of contacts or timezones). 82 | intent.addCategory(Intent.CATEGORY_OPENABLE); 83 | 84 | // Create a file with the requested MIME type. 85 | intent.setType(mimeType); 86 | intent.putExtra(Intent.EXTRA_TITLE, fileName); 87 | startActivityForResult(intent, WRITE_REQUEST_CODE); 88 | } 89 | 90 | @Override 91 | protected void onActivityResult(int requestCode, int resultCode, 92 | Intent resultData) { 93 | if (requestCode == WRITE_REQUEST_CODE) { 94 | if (resultCode == Activity.RESULT_OK) { 95 | if (resultData != null) { 96 | Uri out = resultData.getData(); 97 | 98 | Log.d("", out.toString()); 99 | if(txt){ 100 | Log.d("", "saving TXT"); 101 | 102 | save((String) file.getExtras().get(Intent.EXTRA_TEXT), out); 103 | }else{ 104 | Log.d("", ((Uri) file.getExtras().get(Intent.EXTRA_STREAM)) 105 | .toString()); 106 | 107 | save((Uri) file.getExtras().get(Intent.EXTRA_STREAM), out); 108 | } 109 | 110 | } else { 111 | saveFailed(); 112 | } 113 | } else { 114 | saveFailed(); 115 | } 116 | } 117 | finish(); 118 | } 119 | 120 | private void save(String text, Uri out) { 121 | // TODO: Async Task 122 | try { 123 | 124 | ParcelFileDescriptor pfd = getContentResolver().openFileDescriptor( 125 | out, "w"); 126 | FileOutputStream fileOutputStream = new FileOutputStream( 127 | pfd.getFileDescriptor()); 128 | 129 | 130 | fileOutputStream.write(text.getBytes()); 131 | 132 | // Let the document provider know you're done by closing the stream. 133 | fileOutputStream.close(); 134 | pfd.close(); 135 | 136 | } catch (Exception e) { 137 | e.printStackTrace(); 138 | saveFailed(); 139 | } 140 | } 141 | 142 | private void save(Uri in, Uri out) { 143 | // TODO: Async Task 144 | try { 145 | InputStream inputStream = getContentResolver().openInputStream(in); 146 | 147 | ParcelFileDescriptor pfd = getContentResolver().openFileDescriptor( 148 | out, "w"); 149 | FileOutputStream fileOutputStream = new FileOutputStream( 150 | pfd.getFileDescriptor()); 151 | 152 | byte buffer[] = new byte[1024]; 153 | int length = 0; 154 | 155 | while ((length = inputStream.read(buffer)) > 0) { 156 | fileOutputStream.write(buffer, 0, length); 157 | } 158 | 159 | // Let the document provider know you're done by closing the stream. 160 | fileOutputStream.close(); 161 | inputStream.close(); 162 | pfd.close(); 163 | 164 | } catch (Exception e) { 165 | e.printStackTrace(); 166 | saveFailed(); 167 | } 168 | } 169 | 170 | private void saveFailed() { 171 | Toast.makeText(this, R.string.save_failed, Toast.LENGTH_LONG).show(); 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /app.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /src/main/res/layout/fragment_help.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 17 | 20 | 21 | 30 | 31 | 40 | 41 | 46 | 47 | 56 | 57 |