termux-app

Форк
0
225 строк · 9.6 Кб
1
package com.termux.shared.interact;
2

3
import android.Manifest;
4
import android.app.Activity;
5
import android.content.ActivityNotFoundException;
6
import android.content.ClipData;
7
import android.content.ClipboardManager;
8
import android.content.Context;
9
import android.content.Intent;
10
import android.net.Uri;
11
import android.os.Build;
12
import android.os.Environment;
13

14
import androidx.appcompat.app.AppCompatActivity;
15

16
import com.termux.shared.R;
17
import com.termux.shared.data.DataUtils;
18
import com.termux.shared.data.IntentUtils;
19
import com.termux.shared.file.FileUtils;
20
import com.termux.shared.logger.Logger;
21
import com.termux.shared.errors.Error;
22
import com.termux.shared.android.PermissionUtils;
23

24
import java.nio.charset.Charset;
25

26
import javax.annotation.Nullable;
27

28
public class ShareUtils {
29

30
    private static final String LOG_TAG = "ShareUtils";
31

32
    /**
33
     * Open the system app chooser that allows the user to select which app to send the intent.
34
     *
35
     * @param context The context for operations.
36
     * @param intent The intent that describes the choices that should be shown.
37
     * @param title The title for choose menu.
38
     */
39
    public static void openSystemAppChooser(final Context context, final Intent intent, final String title) {
40
        if (context == null) return;
41

42
        final Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
43
        chooserIntent.putExtra(Intent.EXTRA_INTENT, intent);
44
        chooserIntent.putExtra(Intent.EXTRA_TITLE, title);
45
        chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
46
        try {
47
            context.startActivity(chooserIntent);
48
        } catch (Exception e) {
49
            Logger.logStackTraceWithMessage(LOG_TAG, "Failed to open system chooser for:\n" + IntentUtils.getIntentString(chooserIntent), e);
50
        }
51
    }
52

53
    /**
54
     * Share text.
55
     *
56
     * @param context The context for operations.
57
     * @param subject The subject for sharing.
58
     * @param text The text to share.
59
     */
60
    public static void shareText(final Context context, final String subject, final String text) {
61
        shareText(context, subject, text, null);
62
    }
63

64
    /**
65
     * Share text.
66
     *
67
     * @param context The context for operations.
68
     * @param subject The subject for sharing.
69
     * @param text The text to share.
70
     * @param title The title for share menu.
71
     */
72
    public static void shareText(final Context context, final String subject, final String text, @Nullable final String title) {
73
        if (context == null || text == null) return;
74

75
        final Intent shareTextIntent = new Intent(Intent.ACTION_SEND);
76
        shareTextIntent.setType("text/plain");
77
        shareTextIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
78
        shareTextIntent.putExtra(Intent.EXTRA_TEXT, DataUtils.getTruncatedCommandOutput(text, DataUtils.TRANSACTION_SIZE_LIMIT_IN_BYTES, true, false, false));
79

80
        openSystemAppChooser(context, shareTextIntent, DataUtils.isNullOrEmpty(title) ? context.getString(R.string.title_share_with) : title);
81
    }
82

83

84

85
    /** Wrapper for {@link #copyTextToClipboard(Context, String, String, String)} with `null` `clipDataLabel` and `toastString`. */
86
    public static void copyTextToClipboard(Context context, final String text) {
87
        copyTextToClipboard(context, null, text, null);
88
    }
89

90
    /** Wrapper for {@link #copyTextToClipboard(Context, String, String, String)} with `null` `clipDataLabel`. */
91
    public static void copyTextToClipboard(Context context, final String text, final String toastString) {
92
        copyTextToClipboard(context, null, text, toastString);
93
    }
94

95
    /**
96
     * Copy the text to primary clip of the clipboard.
97
     *
98
     * @param context The context for operations.
99
     * @param clipDataLabel The label to show to the user describing the copied text.
100
     * @param text The text to copy.
101
     * @param toastString If this is not {@code null} or empty, then a toast is shown if copying to
102
     *                    clipboard is successful.
103
     */
104
    public static void copyTextToClipboard(Context context, @Nullable final String clipDataLabel,
105
                                           final String text, final String toastString) {
106
        if (context == null || text == null) return;
107

108
        ClipboardManager clipboardManager = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
109
        if (clipboardManager == null) return;
110

111
        clipboardManager.setPrimaryClip(ClipData.newPlainText(clipDataLabel,
112
            DataUtils.getTruncatedCommandOutput(text, DataUtils.TRANSACTION_SIZE_LIMIT_IN_BYTES,
113
                true, false, false)));
114

115
        if (toastString != null && !toastString.isEmpty())
116
            Logger.showToast(context, toastString, true);
117
    }
118

119

120

121
    /**
122
     * Wrapper for {@link #getTextFromClipboard(Context, boolean)} that returns primary text {@link String}
123
     * if its set and not empty.
124
     */
125
    @Nullable
126
    public static String getTextStringFromClipboardIfSet(Context context, boolean coerceToText) {
127
        CharSequence textCharSequence = getTextFromClipboard(context, coerceToText);
128
        if (textCharSequence == null) return null;
129
        String textString = textCharSequence.toString();
130
        return !textString.isEmpty() ? textString : null;
131
    }
132

133
    /**
134
     * Get the text from primary clip of the clipboard.
135
     *
136
     * @param context The context for operations.
137
     * @param coerceToText Whether to call {@link ClipData.Item#coerceToText(Context)} to coerce
138
     *                     non-text data to text.
139
     * @return Returns the {@link CharSequence} of primary text. This will be `null` if failed to get it.
140
     */
141
    @Nullable
142
    public static CharSequence getTextFromClipboard(Context context, boolean coerceToText) {
143
        if (context == null) return null;
144

145
        ClipboardManager clipboardManager = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
146
        if (clipboardManager == null) return null;
147

148
        ClipData clipData = clipboardManager.getPrimaryClip();
149
        if (clipData == null) return null;
150

151
        ClipData.Item clipItem = clipData.getItemAt(0);
152
        if (clipItem == null) return null;
153

154
        return coerceToText ? clipItem.coerceToText(context) : clipItem.getText();
155
    }
156

157

158

159
    /**
160
     * Open a url.
161
     *
162
     * @param context The context for operations.
163
     * @param url The url to open.
164
     */
165
    public static void openUrl(final Context context, final String url) {
166
        if (context == null || url == null || url.isEmpty()) return;
167
        Uri uri = Uri.parse(url);
168
        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
169
        try {
170
            context.startActivity(intent);
171
        } catch (ActivityNotFoundException e) {
172
            // If no activity found to handle intent, show system chooser
173
            openSystemAppChooser(context, intent, context.getString(R.string.title_open_url_with));
174
        } catch (Exception e) {
175
            Logger.logStackTraceWithMessage(LOG_TAG, "Failed to open url \"" + url + "\"", e);
176
        }
177
    }
178

179
    /**
180
     * Save a file at the path.
181
     *
182
     * If if path is under {@link Environment#getExternalStorageDirectory()}
183
     * or `/sdcard` and storage permission is missing, it will be requested if {@code context} is an
184
     * instance of {@link Activity} or {@link AppCompatActivity} and {@code storagePermissionRequestCode}
185
     * is `>=0` and the function will automatically return. The caller should call this function again
186
     * if user granted the permission.
187
     *
188
     * @param context The context for operations.
189
     * @param label The label for file.
190
     * @param filePath The path to save the file.
191
     * @param text The text to write to file.
192
     * @param showToast If set to {@code true}, then a toast is shown if saving to file is successful.
193
     * @param storagePermissionRequestCode The request code to use while asking for permission.
194
     */
195
    public static void saveTextToFile(final Context context, final String label, final String filePath, final String text, final boolean showToast, final int storagePermissionRequestCode) {
196
        if (context == null || filePath == null || filePath.isEmpty() || text == null) return;
197

198
        // If path is under primary external storage directory, then check for missing permissions.
199
        if ((FileUtils.isPathInDirPath(filePath, Environment.getExternalStorageDirectory().getAbsolutePath(), true) ||
200
            FileUtils.isPathInDirPath(filePath, "/sdcard", true)) &&
201
            !PermissionUtils.checkPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
202
            Logger.logErrorAndShowToast(context, LOG_TAG, context.getString(R.string.msg_storage_permission_not_granted));
203

204
            if (storagePermissionRequestCode >= 0 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
205
                if (context instanceof AppCompatActivity)
206
                    PermissionUtils.requestPermission(((AppCompatActivity) context), Manifest.permission.WRITE_EXTERNAL_STORAGE, storagePermissionRequestCode);
207
                else if (context instanceof Activity)
208
                    PermissionUtils.requestPermission(((Activity) context), Manifest.permission.WRITE_EXTERNAL_STORAGE, storagePermissionRequestCode);
209
            }
210

211
            return;
212
        }
213

214
        Error error = FileUtils.writeTextToFile(label, filePath,
215
            Charset.defaultCharset(), text, false);
216
        if (error != null) {
217
            Logger.logErrorExtended(LOG_TAG, error.toString());
218
            Logger.showToast(context, Error.getMinimalErrorString(error), true);
219
        } else {
220
            if (showToast)
221
                Logger.showToast(context, context.getString(R.string.msg_file_saved_successfully, label, filePath), true);
222
        }
223
    }
224

225
}
226

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.