├── .gitignore
├── .idea
├── .gitignore
├── .name
├── compiler.xml
└── misc.xml
├── LICENSE
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── trianguloy
│ │ └── clipboardeditor
│ │ ├── Editor.java
│ │ ├── Preferences.java
│ │ ├── Process.java
│ │ ├── Shortcuts.java
│ │ └── SimpleTextWatcher.java
│ ├── play
│ ├── contact-email.txt
│ ├── contact-website.txt
│ ├── default-language.txt
│ ├── listings
│ │ ├── en-US
│ │ │ ├── full-description.txt
│ │ │ ├── graphics
│ │ │ │ ├── feature-graphic
│ │ │ │ │ └── featured.png
│ │ │ │ ├── icon
│ │ │ │ │ └── ic_launcher-playstore.png
│ │ │ │ └── phone-screenshots
│ │ │ │ │ ├── 1-main.png
│ │ │ │ │ ├── 2-info.png
│ │ │ │ │ ├── 3-settings.png
│ │ │ │ │ └── 4-other.png
│ │ │ ├── short-description.txt
│ │ │ └── title.txt
│ │ └── fr-FR
│ │ │ ├── full-description.txt
│ │ │ ├── short-description.txt
│ │ │ └── title.txt
│ └── release-notes
│ │ ├── en-US
│ │ └── default.txt
│ │ └── fr-FR
│ │ └── default.txt
│ └── res
│ ├── drawable-hdpi
│ └── ic_notification.png
│ ├── drawable-mdpi
│ └── ic_notification.png
│ ├── drawable-xhdpi
│ └── ic_notification.png
│ ├── drawable-xxhdpi
│ └── ic_notification.png
│ ├── drawable
│ ├── ic_launcher_foreground.xml
│ ├── sync_from.xml
│ └── sync_to.xml
│ ├── layout
│ ├── about.xml
│ ├── activity_editor.xml
│ └── configuration.xml
│ ├── mipmap-anydpi-v26
│ └── ic_launcher.xml
│ ├── mipmap-hdpi
│ └── ic_launcher.png
│ ├── mipmap-mdpi
│ └── ic_launcher.png
│ ├── mipmap-xhdpi
│ └── ic_launcher.png
│ ├── mipmap-xxhdpi
│ └── ic_launcher.png
│ ├── values-es
│ └── strings.xml
│ ├── values-fr-rFR
│ └── strings.xml
│ ├── values-pt-rBR
│ └── strings.xml
│ ├── values-v14
│ └── styles.xml
│ ├── values
│ ├── ic_launcher_background.xml
│ ├── strings.xml
│ └── styles.xml
│ └── xml
│ └── shortcuts.xml
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | # Built application files
2 | *.apk
3 | *.aar
4 | *.ap_
5 | *.aab
6 |
7 | # Files for the ART/Dalvik VM
8 | *.dex
9 |
10 | # Java class files
11 | *.class
12 |
13 | # Generated files
14 | bin/
15 | gen/
16 | out/
17 | # Uncomment the following line in case you need and you don't have the release build type files in your app
18 | # release/
19 |
20 | # Gradle files
21 | .gradle/
22 | build/
23 |
24 | # Local configuration file (sdk path, etc)
25 | local.properties
26 |
27 | # Proguard folder generated by Eclipse
28 | proguard/
29 |
30 | # Log Files
31 | *.log
32 |
33 | # Android Studio Navigation editor temp files
34 | .navigation/
35 |
36 | # Android Studio captures folder
37 | captures/
38 |
39 | # IntelliJ
40 | *.iml
41 | .idea/workspace.xml
42 | .idea/tasks.xml
43 | .idea/gradle.xml
44 | .idea/assetWizardSettings.xml
45 | .idea/dictionaries
46 | .idea/libraries
47 | .idea/jarRepositories.xml
48 | # Android Studio 3 in .gitignore file.
49 | .idea/caches
50 | .idea/modules.xml
51 | # Comment next line if keeping position of elements in Navigation Editor is relevant for you
52 | .idea/navEditor.xml
53 |
54 | # Keystore files
55 | # Uncomment the following lines if you do not want to check your keystore files in.
56 | #*.jks
57 | #*.keystore
58 |
59 | # External native build folder generated in Android Studio 2.2 and later
60 | .externalNativeBuild
61 | .cxx/
62 |
63 | # Google Services (e.g. APIs or Firebase)
64 | # google-services.json
65 |
66 | # Freeline
67 | freeline.py
68 | freeline/
69 | freeline_project_description.json
70 |
71 | # fastlane
72 | fastlane/report.xml
73 | fastlane/Preview.html
74 | fastlane/screenshots
75 | fastlane/test_output
76 | fastlane/readme.md
77 |
78 | # Version control
79 | vcs.xml
80 |
81 | # lint
82 | lint/intermediates/
83 | lint/generated/
84 | lint/outputs/
85 | lint/tmp/
86 | # lint/reports/
87 |
88 | # Android Profiling
89 | *.hprof
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/.idea/.name:
--------------------------------------------------------------------------------
1 | Simple Clipboard Editor
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | This work is licensed under the Creative Commons Attribution 4.0 International License. To view a copy of this license, visit http://creativecommons.org/licenses/by/4.0/ or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Simple Clipboard Editor
2 |
3 | Android app made by TrianguloY
4 |
5 | Get it on Google Play:\
6 | https://play.google.com/store/apps/details?id=com.trianguloy.clipboardeditor \
7 | [
](https://play.google.com/store/apps/details?id=com.trianguloy.clipboardeditor)
10 |
11 | Get it on F-Droid:\
12 | https://f-droid.org/packages/com.trianguloy.clipboardeditor/ \
13 | [
](https://f-droid.org/packages/com.trianguloy.clipboardeditor/)
16 |
17 | You can use parts of this project in your own ones, create pull request, or upload modified versions of it AS LONG AS you credit me.
18 |
19 | How to credit:
20 | - You must add my nick (TrianguloY) in an 'about' or 'acknowledgments' section visible to the user.
21 | - You must add a link to this GitHub main page (https://github.com/TrianguloY/SimpleClipboardEditor) or subpage (if you used a part of the code or an asset) in an 'about' or 'acknowledgments' section visible to the user.
22 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.android.application'
3 | id 'com.github.triplet.play' version '3.7.0'
4 | }
5 |
6 | android {
7 | namespace 'com.trianguloy.clipboardeditor'
8 | compileSdk 32
9 |
10 | defaultConfig {
11 | applicationId "com.trianguloy.clipboardeditor"
12 | minSdk 11
13 | targetSdk 32
14 | versionCode 6
15 | versionName "1.5"
16 | }
17 |
18 | buildTypes {
19 | release {
20 | minifyEnabled true
21 | shrinkResources true
22 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
23 | }
24 | }
25 | compileOptions {
26 | sourceCompatibility JavaVersion.VERSION_11
27 | targetCompatibility JavaVersion.VERSION_11
28 | }
29 |
30 | lint {
31 | // users are free to update translations whenever
32 | // this mean that they are not usually up to date
33 | // and that there are usually lots of missing translations
34 | // so we ignore missing strings
35 | disable 'MissingTranslation'
36 | }
37 | }
38 |
39 | dependencies {
40 |
41 | }
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
28 |
29 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/app/src/main/java/com/trianguloy/clipboardeditor/Editor.java:
--------------------------------------------------------------------------------
1 | package com.trianguloy.clipboardeditor;
2 |
3 | import android.app.Activity;
4 | import android.app.AlertDialog;
5 | import android.app.Notification;
6 | import android.app.NotificationChannel;
7 | import android.app.NotificationManager;
8 | import android.app.PendingIntent;
9 | import android.content.ClipData;
10 | import android.content.ClipboardManager;
11 | import android.content.Context;
12 | import android.content.Intent;
13 | import android.net.Uri;
14 | import android.os.Build;
15 | import android.os.Bundle;
16 | import android.text.Editable;
17 | import android.text.InputType;
18 | import android.util.Log;
19 | import android.view.View;
20 | import android.view.Window;
21 | import android.view.inputmethod.InputMethodManager;
22 | import android.widget.CheckBox;
23 | import android.widget.EditText;
24 | import android.widget.TextView;
25 | import android.widget.Toast;
26 |
27 | /**
28 | * The main activity, a clipboard editor
29 | */
30 | public class Editor extends Activity {
31 | private static final String CHANNEL_ID = "text"; // id for the channel for notifications
32 |
33 | // ------------------- data -------------------
34 |
35 | // classes
36 | private ClipboardManager clipboard; // system clipboard
37 | private NotificationManager notification; // system notifications
38 | private Preferences prefs; // preferences wrapper
39 |
40 | // views
41 | private EditText v_content; // content input
42 | private EditText v_label; // label input
43 | private TextView v_extra; // extra text
44 |
45 | // internal data
46 | private boolean noListener = false; // to avoid firing clipboardToInput and inputToClipboard recursively
47 |
48 | private final SimpleTextWatcher watcher = new SimpleTextWatcher() {
49 | @Override
50 | public void afterTextChanged(Editable s) {
51 | inputToClipboard();
52 | }
53 | };
54 |
55 | // ------------------- init -------------------
56 |
57 | @Override
58 | protected void onCreate(Bundle savedInstanceState) {
59 | super.onCreate(savedInstanceState);
60 |
61 | // activity content
62 | this.requestWindowFeature(Window.FEATURE_NO_TITLE);
63 | setContentView(R.layout.activity_editor);
64 |
65 | // views
66 | v_content = findViewById(R.id.content);
67 | v_label = findViewById(R.id.label);
68 | v_extra = findViewById(R.id.description);
69 |
70 | // descriptions
71 | for (var viewId : new int[]{R.id.notify, R.id.share, R.id.clear, R.id.configure, R.id.info, R.id.sync_to, R.id.sync_from}) {
72 | findViewById(viewId).setOnLongClickListener(view -> {
73 | Toast.makeText(Editor.this, view.getContentDescription().toString(), Toast.LENGTH_SHORT).show();
74 | return true;
75 | });
76 | }
77 |
78 | // preferences
79 | prefs = new Preferences(getPreferences(MODE_PRIVATE));
80 |
81 | // clipboard
82 | clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
83 | notification = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
84 |
85 | // sync if enabled in settings
86 | updateSyncState();
87 |
88 | // auto-update result
89 | v_content.addTextChangedListener(new SimpleTextWatcher() {
90 | @Override
91 | public void afterTextChanged(Editable s) {
92 | var intent = new Intent();
93 | intent.putExtra(getPackageName(), inputAsPrimaryClip());
94 | setResult(RESULT_OK, intent);
95 | }
96 | });
97 |
98 | // show keyboard if enabled in settings
99 | if (prefs.isShowKeyboard()) {
100 | if (v_content.requestFocus()) {
101 | var imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
102 | imm.showSoftInput(v_content, InputMethodManager.SHOW_IMPLICIT);
103 | }
104 | }
105 |
106 | // capitalize input state if enabled in settings
107 | updateCapitalizeState();
108 |
109 | // start intent
110 | parseIntent(getIntent());
111 | setIntent(null);
112 | }
113 |
114 | @Override
115 | public void onWindowFocusChanged(boolean hasFocus) {
116 | super.onWindowFocusChanged(hasFocus);
117 | // when windows is focused, update clipboard
118 | if (hasFocus && prefs.isSync()) {
119 | clipboardToInput();
120 | }
121 | }
122 |
123 | @Override
124 | protected void onNewIntent(Intent intent) {
125 | super.onNewIntent(intent);
126 | // on new intent (probably from a notification or from a sent text) load it
127 | parseIntent(intent);
128 | }
129 |
130 | /**
131 | * @param intent intent to parse for clipboard data
132 | */
133 | private void parseIntent(Intent intent) {
134 | if (intent == null) return;
135 | ClipData data = null;
136 |
137 | // set by ourselves
138 | if (intent.hasExtra(getPackageName()))
139 | data = intent.getParcelableExtra(getPackageName());
140 | // sent
141 | if (data == null && intent.hasExtra(Intent.EXTRA_TEXT))
142 | data = ClipData.newPlainText(getString(R.string.clip_sent), intent.getStringExtra(Intent.EXTRA_TEXT));
143 |
144 | // set
145 | if (data != null) {
146 | if (prefs.isSync()) {
147 | // set directly, it will autosync
148 | clipboard.setPrimaryClip(data);
149 | } else {
150 | // set manually
151 | clipToInput(data);
152 | }
153 | }
154 | }
155 |
156 | /**
157 | * Update
158 | */
159 | private void updateCapitalizeState() {
160 | if (prefs.isCapitalize()) {
161 | // set flag
162 | v_content.setInputType(v_content.getInputType() | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES);
163 | v_label.setInputType(v_label.getInputType() | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES);
164 | } else {
165 | // remove flag
166 | v_content.setInputType(v_content.getInputType() & ~InputType.TYPE_TEXT_FLAG_CAP_SENTENCES);
167 | v_label.setInputType(v_label.getInputType() & ~InputType.TYPE_TEXT_FLAG_CAP_SENTENCES);
168 | }
169 | }
170 |
171 | /**
172 | * Updates the sync state
173 | */
174 | private void updateSyncState() {
175 | if (prefs.isSync()) {
176 | // enable clipboard to input
177 | clipboard.addPrimaryClipChangedListener(this::clipboardToInput);
178 |
179 | // enable input to clipboard
180 | v_content.addTextChangedListener(watcher);
181 | v_label.addTextChangedListener(watcher);
182 |
183 | // hide buttons
184 | findViewById(R.id.sync_parent).setVisibility(View.GONE);
185 | } else {
186 | // disable clipboard to input
187 | clipboard.removePrimaryClipChangedListener(this::clipboardToInput);
188 |
189 | // disable input to clipboard
190 | v_content.removeTextChangedListener(watcher);
191 | v_label.removeTextChangedListener(watcher);
192 |
193 | // show buttons
194 | findViewById(R.id.sync_parent).setVisibility(View.VISIBLE);
195 | }
196 |
197 | }
198 |
199 | // ------------------- buttons -------------------
200 |
201 | /**
202 | * Shows a notification with the clipboard content
203 | */
204 | public void onNotification(View view) {
205 | Notification.Builder builder;
206 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
207 | // setup a notification channel in Oreo+
208 | var channel = new NotificationChannel(CHANNEL_ID, getString(R.string.channel_name), NotificationManager.IMPORTANCE_DEFAULT);
209 | channel.setDescription(getString(R.string.channel_description));
210 | notification.createNotificationChannel(channel);
211 |
212 | builder = new Notification.Builder(this, CHANNEL_ID);
213 | } else {
214 | // no notification channel before Oreo
215 | builder = new Notification.Builder(this);
216 | }
217 |
218 | // sets the label as notification title (if any), the content and icon
219 | if (v_label.getText().length() > 0) builder.setContentTitle(v_label.getText());
220 | builder.setContentText(v_content.getText());
221 | builder.setSmallIcon(R.drawable.ic_notification);
222 |
223 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
224 | // when allowed, set the content as big text (improved display)
225 | builder.setStyle(new Notification.BigTextStyle()
226 | .bigText(v_content.getText()));
227 | }
228 |
229 | // sets the intent for when you click the notification. It will open the app with the current clipboard content
230 | var intent = new Intent(this, Editor.class);
231 | intent.putExtra(getPackageName(), inputAsPrimaryClip());
232 | builder.setContentIntent(PendingIntent.getActivity(this, getUniqueId(), intent, PendingIntent.FLAG_UPDATE_CURRENT | (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? PendingIntent.FLAG_IMMUTABLE : 0))); // change the requestCode with an unique id for multiple independent pendingIntents
233 |
234 |
235 | // publish the notification
236 | var notification = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
237 | var id = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? notification.getActiveNotifications().length : getUniqueId(); // ensure unique id
238 | notification.notify(id,
239 | Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN ? builder.build() : builder.getNotification()
240 | );
241 | }
242 |
243 | /**
244 | * Share the clipboard content
245 | */
246 | public void onShare(View view) {
247 | // create a SEND text intent with the clipboard content
248 | var sendIntent = new Intent();
249 | sendIntent.setAction(Intent.ACTION_SEND);
250 | sendIntent.putExtra(Intent.EXTRA_TEXT, v_content.getText().toString());
251 | sendIntent.setType("text/plain");
252 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
253 | // not sure what it does, but maybe it allows to share images (even if the app can't display them)
254 | sendIntent.setClipData(inputAsPrimaryClip());
255 | }
256 |
257 | // start a chooser, use the label as title
258 | startActivity(Intent.createChooser(sendIntent, v_label.getText()));
259 | }
260 |
261 | /**
262 | * Clears the clipboard content
263 | */
264 | public void onClear(View view) {
265 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
266 | if (prefs.isSync()) {
267 | // the easy way, just call 'clear'
268 | clipboard.clearPrimaryClip();
269 | } else {
270 | // clear input only
271 | v_content.setText("");
272 | v_label.setText("");
273 | }
274 | } else {
275 | // the not-so-easy way, manually set as empty
276 | noListener = true;
277 | v_content.setText("");
278 | v_label.setText("");
279 | noListener = false;
280 | if (prefs.isSync()) {
281 | // and sync
282 | inputToClipboard();
283 | }
284 | }
285 | }
286 |
287 | /**
288 | * Open the configure screen
289 | */
290 | public void onConfigure(View view) {
291 | // setup
292 | var content = getLayoutInflater().inflate(R.layout.configuration, null);
293 |
294 | // auto keyboard
295 | CheckBox autokeyboard = content.findViewById(R.id.autokeyboard);
296 | autokeyboard.setChecked(prefs.isShowKeyboard());
297 | autokeyboard.setOnCheckedChangeListener((checkbox, checked) -> prefs.setShowKeyboard(checked));
298 |
299 | // capitalize
300 | CheckBox capitalize = content.findViewById(R.id.capitalize);
301 | capitalize.setChecked(prefs.isCapitalize());
302 | capitalize.setOnCheckedChangeListener((checkbox, checked) -> {
303 | prefs.setCapitalize(checked);
304 | updateCapitalizeState();
305 | });
306 |
307 | // autosync
308 | CheckBox sync = content.findViewById(R.id.sync);
309 | sync.setChecked(prefs.isSync());
310 | sync.setOnCheckedChangeListener((checkbox, checked) -> {
311 | prefs.setSync(checked);
312 | updateSyncState();
313 | });
314 |
315 | // show
316 | new AlertDialog.Builder(this)
317 | .setIcon(R.mipmap.ic_launcher)
318 | .setTitle(R.string.descr_configure)
319 | .setView(content)
320 | .show();
321 | }
322 |
323 | /**
324 | * Show the about screen
325 | */
326 | public void onInfo(View view) {
327 | // before-setup
328 | var content = getLayoutInflater().inflate(R.layout.about, null);
329 |
330 | // show
331 | var dialog = new AlertDialog.Builder(this)
332 | .setIcon(R.mipmap.ic_launcher)
333 | .setTitle(getString(R.string.descr_info))
334 | .setView(content)
335 | .show();
336 |
337 | // after-setup
338 | for (var id : new int[]{R.id.blog, R.id.github, R.id.playstore}) {
339 | // setup all three buttons (its tag is the url)
340 | var button = content.findViewById(id);
341 | button.setOnClickListener(btn -> {
342 | // click to open in browser
343 | var url = btn.getTag().toString();
344 | try {
345 | startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
346 | } catch (Exception e) {
347 | // on error, like no browser, invoke long click (set the url in the clipboard)
348 | btn.performLongClick();
349 | }
350 | dialog.dismiss();
351 | });
352 | button.setOnLongClickListener(btn -> {
353 | // long click to set in clipboard
354 | clipboard.setPrimaryClip(ClipData.newPlainText("TrianguloY", btn.getTag().toString()));
355 | dialog.dismiss();
356 | return true;
357 | });
358 | }
359 | }
360 |
361 | /**
362 | * @see this#clipboardToInput
363 | */
364 | public void inputFromClipboard(View view) {
365 | clipboardToInput();
366 | }
367 |
368 | /**
369 | * @see this#inputToClipboard()
370 | */
371 | public void inputToClipboard(View view) {
372 | inputToClipboard();
373 | }
374 |
375 |
376 | // ------------------- transfer -------------------
377 |
378 | /**
379 | * Sets the input values to the clipboard ones
380 | * Ensures it doesn't fire inputToClipboard
381 | */
382 | private void clipboardToInput() {
383 | if (noListener) return;
384 | noListener = true;
385 |
386 | // get
387 | clipToInput(clipboard.getPrimaryClip());
388 | }
389 |
390 | /**
391 | * Sets the inputs to the values of the clipdata
392 | */
393 | private void clipToInput(ClipData clip) {
394 | // set
395 | if (clip == null) {
396 | // no content
397 | v_extra.setText(String.format("[%s]", getString(R.string.txt_empty)));
398 | v_label.setText("");
399 | v_content.setText("");
400 |
401 | Log.d("CLIPBOARD", "--> null");
402 | } else {
403 | // content
404 | var description = clip.getDescription();
405 |
406 | // mimetype
407 | v_extra.setText(R.string.label_mimetype);
408 | var empty = true;
409 | for (var i = 0; i < description.getMimeTypeCount(); i++) {
410 | if (!empty) v_extra.append(" -");
411 | empty = false;
412 | v_extra.append(" " + description.getMimeType(i));
413 | }
414 | if (empty) v_extra.append(getString(R.string.txt_empty));
415 |
416 | // item count
417 | var itemCount = clip.getItemCount();
418 | if (itemCount > 1) v_extra.append(getString(R.string.txt_itemcount) + itemCount);
419 |
420 | // label
421 | var label = toStringNonNull(description.getLabel());
422 | if (!toStringNonNull(v_label.getText()).equals(label)) {
423 | v_label.setText(label);
424 | if (v_label.hasFocus()) v_label.setSelection(v_label.getText().length());
425 | }
426 |
427 | // text
428 | var content = toStringNonNull(clip.getItemAt(0).coerceToText(this));
429 | if (!toStringNonNull(v_content.getText()).equals(content)) {
430 | v_content.setText(content);
431 | if (v_content.hasFocus()) v_content.setSelection(v_content.getText().length());
432 | }
433 |
434 |
435 | Log.d("CLIPBOARD", "--> [" + label + "] " + content);
436 | }
437 |
438 |
439 | noListener = false;
440 | }
441 |
442 | /**
443 | * Sets the clipboard value to the input ones
444 | * Ensures it doesn't fire clipboardToInput
445 | */
446 | private void inputToClipboard() {
447 | if (noListener) return;
448 | noListener = true;
449 |
450 | // get
451 | CharSequence content = v_content.getText();
452 | CharSequence label = v_label.getText();
453 |
454 | // set
455 | clipboard.setPrimaryClip(ClipData.newPlainText(label, content));
456 |
457 | Log.d("CLIPBOARD", "<-- [" + label + "] " + content);
458 |
459 | noListener = false;
460 | }
461 |
462 | /**
463 | * Returns the input as primary clip
464 | * in sync mode, the clipboard one is returned (may contain more data)
465 | */
466 | private ClipData inputAsPrimaryClip() {
467 | return prefs.isSync()
468 | ? clipboard.getPrimaryClip()
469 | : ClipData.newPlainText(v_label.getText().toString(), v_content.getText().toString());
470 | }
471 |
472 | // ------------------- utils -------------------
473 |
474 | /**
475 | * return object?.toString() ?: "";
476 | *
477 | * @param object any object, including null
478 | * @return non null string
479 | */
480 | static private String toStringNonNull(Object object) {
481 | return object == null ? "" : object.toString();
482 | }
483 |
484 | /**
485 | * @return a 'unique' id (should be unique unless called at the same millisecond or after a very VERY long time)
486 | */
487 | private static int getUniqueId() {
488 | return Long.valueOf(System.currentTimeMillis()).intValue();
489 | }
490 |
491 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/trianguloy/clipboardeditor/Preferences.java:
--------------------------------------------------------------------------------
1 | package com.trianguloy.clipboardeditor;
2 |
3 | import android.content.SharedPreferences;
4 |
5 | /**
6 | * Simple Preferences wrapper
7 | */
8 | public class Preferences {
9 | private final SharedPreferences prefs; // the prefs
10 |
11 | /**
12 | * @param prefs preferences to wrap
13 | */
14 | public Preferences(SharedPreferences prefs) {
15 | this.prefs = prefs;
16 | }
17 |
18 | // ------------------- autoshowkeyboard -------------------
19 | private final String SHOWKEYBOARD_KEY = "showKeyboard";
20 | private final boolean SHOWKEYBOARD_DEFAULT = true;
21 |
22 | /**
23 | * @return if SHOWKEYBOARD preference is set
24 | */
25 | public boolean isShowKeyboard() {
26 | return prefs.getBoolean(SHOWKEYBOARD_KEY, SHOWKEYBOARD_DEFAULT);
27 | }
28 |
29 |
30 | /**
31 | * @param showKeyboard new SHOWKEYBOARD preference to set
32 | */
33 | public void setShowKeyboard(boolean showKeyboard) {
34 | prefs.edit().putBoolean(SHOWKEYBOARD_KEY, showKeyboard).apply();
35 | }
36 |
37 | // ------------------- capitalize sentences -------------------
38 |
39 | private final String CAPITALIZE_KEY = "capitalize";
40 | private final boolean CAPITALIZE_DEFAULT = false;
41 |
42 | /**
43 | * @return if CAPITALIZE preference is set
44 | */
45 | public boolean isCapitalize() {
46 | return prefs.getBoolean(CAPITALIZE_KEY, CAPITALIZE_DEFAULT);
47 | }
48 |
49 |
50 | /**
51 | * @param capitalize new CAPITALIZE preference to set
52 | */
53 | public void setCapitalize(boolean capitalize) {
54 | prefs.edit().putBoolean(CAPITALIZE_KEY, capitalize).apply();
55 | }
56 |
57 | // ------------------- auto sync -------------------
58 |
59 | private final String SYNC_KEY = "sync";
60 | private final boolean SYNC_DEFAULT = true;
61 |
62 | /**
63 | * @return if SYNC preference is set
64 | */
65 | public boolean isSync() {
66 | return prefs.getBoolean(SYNC_KEY, SYNC_DEFAULT);
67 | }
68 |
69 |
70 | /**
71 | * @param sync new SYNC preference to set
72 | */
73 | public void setSync(boolean sync) {
74 | prefs.edit().putBoolean(SYNC_KEY, sync).apply();
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/app/src/main/java/com/trianguloy/clipboardeditor/Process.java:
--------------------------------------------------------------------------------
1 | package com.trianguloy.clipboardeditor;
2 |
3 | import android.annotation.TargetApi;
4 | import android.app.Activity;
5 | import android.content.ClipData;
6 | import android.content.Intent;
7 | import android.os.Build;
8 | import android.os.Bundle;
9 |
10 | /**
11 | * This activity receives the PROCESS_TEXT intent and calls the main activity with it.
12 | * Separated to allow having a different label, and also because this feature is for Android 6.0+ only
13 | */
14 | @TargetApi(Build.VERSION_CODES.M)
15 | public class Process extends Activity {
16 |
17 | @Override
18 | protected void onCreate(Bundle savedInstanceState) {
19 | super.onCreate(savedInstanceState);
20 |
21 | // get the text
22 | var clipData = ClipData.newPlainText(
23 | getString(R.string.clip_selection),
24 | getIntent().getCharSequenceExtra(Intent.EXTRA_PROCESS_TEXT)
25 | );
26 |
27 | // process the text
28 | var intent = new Intent(this, Editor.class);
29 | intent.putExtra(getPackageName(), clipData);
30 | startActivityForResult(intent, 0);
31 | }
32 |
33 | @Override
34 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
35 | super.onActivityResult(requestCode, resultCode, data);
36 |
37 | // get the result
38 | var clipData = data == null ? null : data.getParcelableExtra(getPackageName());
39 | var result = clipData == null ? "" : clipData.getItemAt(0).coerceToText(this);
40 |
41 | // return it (we ignore the readonly attribute, it's unnecessary)
42 | var intent = new Intent();
43 | intent.putExtra(Intent.EXTRA_PROCESS_TEXT, result);
44 | setResult(RESULT_OK, intent);
45 | finish();
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/app/src/main/java/com/trianguloy/clipboardeditor/Shortcuts.java:
--------------------------------------------------------------------------------
1 | package com.trianguloy.clipboardeditor;
2 |
3 | import android.app.Activity;
4 | import android.content.ClipData;
5 | import android.content.ClipboardManager;
6 | import android.os.Build;
7 | import android.os.Bundle;
8 | import android.widget.Toast;
9 |
10 | /**
11 | * Activity that will clear the clipboard when launched, then exit
12 | */
13 | public class Shortcuts extends Activity {
14 | @Override
15 | protected void onCreate(Bundle savedInstanceState) {
16 | super.onCreate(savedInstanceState);
17 |
18 | // get
19 | var clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
20 |
21 | // clear
22 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
23 | // the easy way, just call 'clear'
24 | clipboard.clearPrimaryClip();
25 | } else {
26 | // the not-so-easy way, manually set as empty
27 | clipboard.setPrimaryClip(ClipData.newPlainText("", ""));
28 | }
29 |
30 | Toast.makeText(this, R.string.toast_cleared, Toast.LENGTH_SHORT).show();
31 | finish();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/java/com/trianguloy/clipboardeditor/SimpleTextWatcher.java:
--------------------------------------------------------------------------------
1 | package com.trianguloy.clipboardeditor;
2 |
3 | import android.text.Editable;
4 | import android.text.TextWatcher;
5 |
6 | /**
7 | * {@link TextWatcher} is an interface, with 3 methods, and you usually don't need all of them. This class overrides them all so you don't need to
8 | */
9 | public class SimpleTextWatcher implements TextWatcher {
10 | @Override
11 | public void beforeTextChanged(CharSequence s, int start, int count, int after) {
12 | }
13 |
14 | @Override
15 | public void onTextChanged(CharSequence s, int start, int before, int count) {
16 | }
17 |
18 | @Override
19 | public void afterTextChanged(Editable s) {
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/app/src/main/play/contact-email.txt:
--------------------------------------------------------------------------------
1 | correo--correo+sce@hotmail.com
2 |
--------------------------------------------------------------------------------
/app/src/main/play/contact-website.txt:
--------------------------------------------------------------------------------
1 | https://triangularapps.blogspot.com/
2 |
--------------------------------------------------------------------------------
/app/src/main/play/default-language.txt:
--------------------------------------------------------------------------------
1 | en-US
2 |
--------------------------------------------------------------------------------
/app/src/main/play/listings/en-US/full-description.txt:
--------------------------------------------------------------------------------
1 | This app displays the current content of your phone's clipboard.
2 | When that content is text, you can edit, replace, delete or perform any other text modification, live.
3 | Additionally, you can also share the content directly and create a notification with it for later use.
4 |
5 | Note: Due to Google's restrictions the app can't interact with the clipboard while it's closed. It will be automatically updated as soon as you reopen it though. The app doesn't contains any history functionality (not yet at least).
6 |
7 |
8 | Made by TrianguloY. Extremely small, efficient, without any permissions, free and without ads.
9 |
10 | GitHub: https://github.com/TrianguloY/SimpleClipboardEditor
11 | Blog: https://triangularapps.blogspot.com/
12 |
--------------------------------------------------------------------------------
/app/src/main/play/listings/en-US/graphics/feature-graphic/featured.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TrianguloY/SimpleClipboardEditor/fe38d45d492348c3c4b1602967f4a046a4a6be60/app/src/main/play/listings/en-US/graphics/feature-graphic/featured.png
--------------------------------------------------------------------------------
/app/src/main/play/listings/en-US/graphics/icon/ic_launcher-playstore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TrianguloY/SimpleClipboardEditor/fe38d45d492348c3c4b1602967f4a046a4a6be60/app/src/main/play/listings/en-US/graphics/icon/ic_launcher-playstore.png
--------------------------------------------------------------------------------
/app/src/main/play/listings/en-US/graphics/phone-screenshots/1-main.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TrianguloY/SimpleClipboardEditor/fe38d45d492348c3c4b1602967f4a046a4a6be60/app/src/main/play/listings/en-US/graphics/phone-screenshots/1-main.png
--------------------------------------------------------------------------------
/app/src/main/play/listings/en-US/graphics/phone-screenshots/2-info.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TrianguloY/SimpleClipboardEditor/fe38d45d492348c3c4b1602967f4a046a4a6be60/app/src/main/play/listings/en-US/graphics/phone-screenshots/2-info.png
--------------------------------------------------------------------------------
/app/src/main/play/listings/en-US/graphics/phone-screenshots/3-settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TrianguloY/SimpleClipboardEditor/fe38d45d492348c3c4b1602967f4a046a4a6be60/app/src/main/play/listings/en-US/graphics/phone-screenshots/3-settings.png
--------------------------------------------------------------------------------
/app/src/main/play/listings/en-US/graphics/phone-screenshots/4-other.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TrianguloY/SimpleClipboardEditor/fe38d45d492348c3c4b1602967f4a046a4a6be60/app/src/main/play/listings/en-US/graphics/phone-screenshots/4-other.png
--------------------------------------------------------------------------------
/app/src/main/play/listings/en-US/short-description.txt:
--------------------------------------------------------------------------------
1 | View, edit or delete the phone clipboard's text with a simple and fast editor.
2 |
--------------------------------------------------------------------------------
/app/src/main/play/listings/en-US/title.txt:
--------------------------------------------------------------------------------
1 | Simple Clipboard Editor
2 |
--------------------------------------------------------------------------------
/app/src/main/play/listings/fr-FR/full-description.txt:
--------------------------------------------------------------------------------
1 | Cette application affiche le contenu actuel du presse-papiers de votre téléphone.
2 | Lorsque ce contenu est du texte, vous pouvez le modifier, remplacer, supprimer ou effectuer toute autre modification, en direct.
3 | De plus, vous pouvez également partager se contenu directement et créer une notification avec lui pour une utilisation ultérieure.
4 |
5 | Remarque: En raison des restrictions de Google, l'application ne peut pas interagir avec le presse-papiers lorsqu'il est fermé. Cependant, il sera automatiquement mis à jour dès que vous le rouvrirez. L'application ne contient aucune fonctionnalité d'historique (du moins pas encore).
6 |
7 |
8 | Réalisé par TrianguloY. Léger, efficace, sans aucune autorisation, gratuit et sans publicité.
9 |
--------------------------------------------------------------------------------
/app/src/main/play/listings/fr-FR/short-description.txt:
--------------------------------------------------------------------------------
1 | intéragissez avec le presse-papiers de votre smartphone via un éditeur efficace.
2 |
--------------------------------------------------------------------------------
/app/src/main/play/listings/fr-FR/title.txt:
--------------------------------------------------------------------------------
1 | Simple Clipboard Editor
2 |
--------------------------------------------------------------------------------
/app/src/main/play/release-notes/en-US/default.txt:
--------------------------------------------------------------------------------
1 | V 1.5
2 | - Sent text to the app
3 | - Edit selected text (Android 6.0+)
4 |
5 | V 1.4
6 | - New shortcut to clear the clipboard directly without opening the app
7 | - Setting to disable automatic sync
8 | - New translation to Portuguese (Brazil) thanks to mezysinc!
9 | - New translation to Spanish
10 | - Fix launcher icon not shown in older android versions
11 |
12 | V 1.3
13 | - New setting: Capitalize sentences on input
14 | - Tweaks to texts and visuals of dialogs
15 |
16 | V 1.2
17 | - Style update
18 |
19 | V 1.1
20 | - Added Github and Blog links to about screen
21 | - Fixed sharing
22 |
23 | V 1.0
24 | - Initial release on Play Store
--------------------------------------------------------------------------------
/app/src/main/play/release-notes/fr-FR/default.txt:
--------------------------------------------------------------------------------
1 | V1.5
2 | - Envoyé du texte à l'application
3 | - Éditer le texte sélectionné (Android 6.0+)
4 |
5 | V1.4
6 | - Nouveau raccourci pour effacer le presse-papiers directement sans ouvrir l'application
7 | - Nouveau paramètre: désactiver la synchronisation automatique
8 | - Nouvelle traduction en portugais (Brésil) grâce à mezysinc !
9 | - Nouvelle traduction en espagnol
10 | - Correction de l'icône non affichée dans les anciennes versions d'Android
11 |
12 | v1.3
13 | - Nouveau paramètre: capitaliser les phrases lors de la saisie
14 | - Ajustements des textes et des visuels des boîtes de dialogue
15 |
16 | V1.2
17 | - Mise à jour des styles
18 |
19 | V1.1
20 | - Ajout de liens vers Github et Blog dans l'écran "À Propos"
21 | - Partage fixe
22 |
23 | V1.0
24 | - Première version sur Play Store
25 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_notification.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TrianguloY/SimpleClipboardEditor/fe38d45d492348c3c4b1602967f4a046a4a6be60/app/src/main/res/drawable-hdpi/ic_notification.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_notification.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TrianguloY/SimpleClipboardEditor/fe38d45d492348c3c4b1602967f4a046a4a6be60/app/src/main/res/drawable-mdpi/ic_notification.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_notification.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TrianguloY/SimpleClipboardEditor/fe38d45d492348c3c4b1602967f4a046a4a6be60/app/src/main/res/drawable-xhdpi/ic_notification.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_notification.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TrianguloY/SimpleClipboardEditor/fe38d45d492348c3c4b1602967f4a046a4a6be60/app/src/main/res/drawable-xxhdpi/ic_notification.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/sync_from.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/sync_to.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/about.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
14 |
15 |
20 |
21 |
29 |
30 |
38 |
39 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_editor.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
14 |
15 |
19 |
20 |
25 |
26 |
36 |
37 |
42 |
43 |
55 |
56 |
60 |
61 |
62 |
63 |
64 |
70 |
71 |
79 |
80 |
84 |
85 |
94 |
95 |
104 |
105 |
106 |
107 |
112 |
113 |
117 |
118 |
127 |
128 |
137 |
138 |
147 |
148 |
157 |
158 |
166 |
167 |
168 |
169 |
170 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/configuration.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
15 |
21 |
22 |
28 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TrianguloY/SimpleClipboardEditor/fe38d45d492348c3c4b1602967f4a046a4a6be60/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TrianguloY/SimpleClipboardEditor/fe38d45d492348c3c4b1602967f4a046a4a6be60/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TrianguloY/SimpleClipboardEditor/fe38d45d492348c3c4b1602967f4a046a4a6be60/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TrianguloY/SimpleClipboardEditor/fe38d45d492348c3c4b1602967f4a046a4a6be60/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/values-es/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Simple editor del portapapeles
4 | "Esta aplicación muestra el contenido del portapapeles de tu dispositivo.
5 | Cuando el contenido es texto puedes editarlo, reemplazarlo, borrarlo o realizar cualquier modificación sobre él en vivo.
6 | Además, puedes compartir el contenido directamente o crear una notificación con él para usar mas tarde.
7 |
8 | Nota: Debido a las restricciones de Google la aplicación no puede interactuar con el portapapeles mientras está cerrada pero se sincronizará automáticamente al abrirse. La aplicación no contiene ninguna funcionalidad de historial (al menos no de momento).
9 |
10 |
11 | Hecha por TrianguloY. Extremadamente pequeña, eficiente, sin permisos, gratuita y sin anuncios."
12 | Blog
13 | Código fuente
14 | Play Store
15 | Categoría
16 | Contenido
17 | Tipo (mimetype)
18 | Poner como notificación
19 | Compartir
20 | Borrar
21 | Ajustes
22 | Información
23 | vacío
24 | \nnúmero de elementos =
25 | Texto
26 | Texto del portapapeles
27 | Mostrar teclado al abrir la aplicación
28 | Poner en mayúsculas la primera letra de cada frase (algunos teclados puede que lo ignoren)
29 | Reemplaza el valor del portapapeles con el texto introducido
30 | Reemplaza el texto introducido con el valor del portapapeles
31 | Sincronizar automáticamente el contenido del portapapeles con los textos introducidos
32 | Borrar portapapeles
33 | Portapapeles borrado
34 | Editor del portapapelsseleccióncompartido
35 |
36 |
--------------------------------------------------------------------------------
/app/src/main/res/values-fr-rFR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Simple Clipboard Editor
4 | "Cette application affiche le contenu actuel du presse-papiers de votre téléphone.
5 | Lorsque ce contenu est du texte, vous pouvez modifier, remplacer, supprimer ou effectuer toute autre modification de texte, en direct.
6 | En outre, vous pouvez également partager le contenu directement ou créer une notification avec celui-ci pour une utilisation ultérieure.
7 |
8 | Remarque : En raison des restrictions de Google, l'application ne peut pas interagir avec le presse-papiers lorsqu'il est fermé. Cependant, il sera automatiquement mis à jour dès que vous le rouvrirez. L'application ne contient aucune fonctionnalité d'historique (du moins pas encore).
9 |
10 |
11 | Réalisé par TrianguloY. Extrêmement léger, efficace, sans aucune autorisation, gratuit et sans publicité."
12 | Blog
13 | Code source
14 | Play Store
15 |
16 |
17 | Label:
18 | Contenu:
19 | Mimetype:
20 | Définir en tant que notification
21 | Partager
22 | Effacer
23 | Paramètres
24 | Info
25 | Remplacer les données du presse-papiers par la valeur d\'entrée
26 | Remplacer la valeur d\'entrée par les données du presse-papiers
27 | Vierge
28 | \nNombre d\'éléments =
29 | envoyer
30 |
31 |
32 | Texte
33 | Texte du presse-papiers
34 |
35 |
36 | "Faire apparaître le clavier à l'ouverture de l'application"
37 | Capitaliser la première lettre des phrases saisies (certains claviers peuvent ignorer cela)
38 | Synchronisation automatique entre presse-papiers et entrées
39 |
40 |
41 | Effacer le presse-papier
42 | Presse-papiers effacé
43 |
44 |
45 | Éditeur de presse-papiers
46 | Sélection
47 |
48 |
49 |
--------------------------------------------------------------------------------
/app/src/main/res/values-pt-rBR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Simple Clipboard Editor
5 | "Este app mostra o conteúdo atual do clipboard de seu telefone.
6 | Se o conteúdo for um texto, você pode editar, substituir, excluir ou realizar qualquer outra modificação em texto, em tempo real.
7 | Além disso, também pode imediatamente compartilhar o conteúdo e colocar ele como notificação para usar mais tarde.
8 |
9 | Aviso: Devido às restrições do Google, o app não pode interagir com o clipboard enquanto estiver fechado. No entanto, será automaticamente atualizado assim que for reaberto. O app não possui a funcionalidade de histórico de entradas (pelo menos por enquanto).
10 |
11 |
12 | Feito por TrianguloY, traduzido por mezysinc. Extremamente pequeno, eficiente, sem nenhuma permissão, gratuito e sem anúncios."
13 | Blog
14 | Código-fonte
15 | Play Store
16 |
17 |
18 | Categoria:
19 | Conteúdo:
20 | Mimetype:
21 | Colocar como notificação
22 | Compartilhar
23 | Limpar
24 | Configurações
25 | Detalhes
26 | Substitui conteúdo do clipboard por texto digitado
27 | Substitui o texto digitado por conteúdo do clipboard
28 | inexistente
29 | \nnúmero de itens =
30 |
31 |
32 | Texto
33 | Texto do clipboard
34 |
35 |
36 | Mostrar teclado quando o app for aberto
37 | Colocar a primeira letra em maiúscula em frases de entrada (alguns teclados podem ignorar isso)
38 | Sincronização automática entre o clipboard e as entradas
39 |
40 |
41 | Limpar clipboard
42 | O conteúdo do clipboard foi removido
43 |
44 |
--------------------------------------------------------------------------------
/app/src/main/res/values-v14/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFFFFF
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Simple Clipboard Editor
4 | "This app displays the current content of your phone's clipboard.
5 | When that content is text you can edit, replace, delete or perform any other text modification, live.
6 | Additionally, you can also share the content directly or create a notification with it for later use.
7 |
8 | Note: Due to Google's restrictions the app can't interact with the clipboard while it's closed. It will be automatically updated as soon as you reopen it though. The app doesn't contains any history functionality (not yet at least).
9 |
10 |
11 | Made by TrianguloY. Extremely small, efficient, without any permissions, free and without ads."
12 | Blog
13 | Source code
14 | Play Store
15 |
16 |
17 | Label:
18 | Content:
19 | Mimetype:
20 | Set as notification
21 | Share
22 | Clear
23 | Settings
24 | Info
25 | Replace the clipboard data with the inputs value
26 | Replace the inputs value with the clipboard data
27 | empty
28 | \nItem count =
29 | sent
30 |
31 |
32 | Text
33 | Clipboard text
34 |
35 |
36 | Show keyboard when app opens
37 | Capitalize first letter of input sentences (some keyboards may ignore this)
38 | Automatic sync between clipboard and inputs
39 |
40 |
41 | Clear clipboard
42 | Clipboard cleared
43 |
44 |
45 | Clipboard editor
46 | selection
47 |
48 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/shortcuts.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
13 |
14 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | buildscript {
3 | repositories {
4 | google()
5 | mavenCentral()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:7.3.0'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | task clean(type: Delete) {
16 | delete rootProject.buildDir
17 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app"s APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Automatically convert third-party libraries to use AndroidX
19 | android.enableJetifier=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TrianguloY/SimpleClipboardEditor/fe38d45d492348c3c4b1602967f4a046a4a6be60/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Sat Sep 25 12:57:19 CEST 2021
2 | distributionBase=GRADLE_USER_HOME
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
4 | distributionPath=wrapper/dists
5 | zipStorePath=wrapper/dists
6 | zipStoreBase=GRADLE_USER_HOME
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | #
4 | # Copyright 2015 the original author or authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | ##
21 | ## Gradle start up script for UN*X
22 | ##
23 | ##############################################################################
24 |
25 | # Attempt to set APP_HOME
26 | # Resolve links: $0 may be a link
27 | PRG="$0"
28 | # Need this for relative symlinks.
29 | while [ -h "$PRG" ] ; do
30 | ls=`ls -ld "$PRG"`
31 | link=`expr "$ls" : '.*-> \(.*\)$'`
32 | if expr "$link" : '/.*' > /dev/null; then
33 | PRG="$link"
34 | else
35 | PRG=`dirname "$PRG"`"/$link"
36 | fi
37 | done
38 | SAVED="`pwd`"
39 | cd "`dirname \"$PRG\"`/" >/dev/null
40 | APP_HOME="`pwd -P`"
41 | cd "$SAVED" >/dev/null
42 |
43 | APP_NAME="Gradle"
44 | APP_BASE_NAME=`basename "$0"`
45 |
46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
48 |
49 | # Use the maximum available, or set MAX_FD != -1 to use that value.
50 | MAX_FD="maximum"
51 |
52 | warn () {
53 | echo "$*"
54 | }
55 |
56 | die () {
57 | echo
58 | echo "$*"
59 | echo
60 | exit 1
61 | }
62 |
63 | # OS specific support (must be 'true' or 'false').
64 | cygwin=false
65 | msys=false
66 | darwin=false
67 | nonstop=false
68 | case "`uname`" in
69 | CYGWIN* )
70 | cygwin=true
71 | ;;
72 | Darwin* )
73 | darwin=true
74 | ;;
75 | MINGW* )
76 | msys=true
77 | ;;
78 | NONSTOP* )
79 | nonstop=true
80 | ;;
81 | esac
82 |
83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
84 |
85 |
86 | # Determine the Java command to use to start the JVM.
87 | if [ -n "$JAVA_HOME" ] ; then
88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
89 | # IBM's JDK on AIX uses strange locations for the executables
90 | JAVACMD="$JAVA_HOME/jre/sh/java"
91 | else
92 | JAVACMD="$JAVA_HOME/bin/java"
93 | fi
94 | if [ ! -x "$JAVACMD" ] ; then
95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
96 |
97 | Please set the JAVA_HOME variable in your environment to match the
98 | location of your Java installation."
99 | fi
100 | else
101 | JAVACMD="java"
102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
103 |
104 | Please set the JAVA_HOME variable in your environment to match the
105 | location of your Java installation."
106 | fi
107 |
108 | # Increase the maximum file descriptors if we can.
109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
110 | MAX_FD_LIMIT=`ulimit -H -n`
111 | if [ $? -eq 0 ] ; then
112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
113 | MAX_FD="$MAX_FD_LIMIT"
114 | fi
115 | ulimit -n $MAX_FD
116 | if [ $? -ne 0 ] ; then
117 | warn "Could not set maximum file descriptor limit: $MAX_FD"
118 | fi
119 | else
120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
121 | fi
122 | fi
123 |
124 | # For Darwin, add options to specify how the application appears in the dock
125 | if $darwin; then
126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
127 | fi
128 |
129 | # For Cygwin or MSYS, switch paths to Windows format before running java
130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
133 |
134 | JAVACMD=`cygpath --unix "$JAVACMD"`
135 |
136 | # We build the pattern for arguments to be converted via cygpath
137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
138 | SEP=""
139 | for dir in $ROOTDIRSRAW ; do
140 | ROOTDIRS="$ROOTDIRS$SEP$dir"
141 | SEP="|"
142 | done
143 | OURCYGPATTERN="(^($ROOTDIRS))"
144 | # Add a user-defined pattern to the cygpath arguments
145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
147 | fi
148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
149 | i=0
150 | for arg in "$@" ; do
151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
153 |
154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
156 | else
157 | eval `echo args$i`="\"$arg\""
158 | fi
159 | i=`expr $i + 1`
160 | done
161 | case $i in
162 | 0) set -- ;;
163 | 1) set -- "$args0" ;;
164 | 2) set -- "$args0" "$args1" ;;
165 | 3) set -- "$args0" "$args1" "$args2" ;;
166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
172 | esac
173 | fi
174 |
175 | # Escape application args
176 | save () {
177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
178 | echo " "
179 | }
180 | APP_ARGS=`save "$@"`
181 |
182 | # Collect all arguments for the java command, following the shell quoting and substitution rules
183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
184 |
185 | exec "$JAVACMD" "$@"
186 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if "%ERRORLEVEL%"=="0" goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84 | exit /b 1
85 |
86 | :mainEnd
87 | if "%OS%"=="Windows_NT" endlocal
88 |
89 | :omega
90 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | dependencyResolutionManagement {
2 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
3 | repositories {
4 | google()
5 | mavenCentral()
6 | }
7 | }
8 | rootProject.name = "Simple Clipboard Editor"
9 | include ':app'
10 |
--------------------------------------------------------------------------------