Share feature
This commit is contained in:
parent
1a37063295
commit
499f10ea39
|
@ -26,13 +26,30 @@
|
|||
<activity
|
||||
android:name=".activities.MainActivity"
|
||||
android:configChanges="orientation|screenSize"
|
||||
android:exported="true"
|
||||
>
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:mimeType="text/plain" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
|
||||
<data android:mimeType="image/*" />
|
||||
<data android:mimeType="video/*" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND_MULTIPLE" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
|
||||
<data android:mimeType="image/*" />
|
||||
<data android:mimeType="video/*" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
|
|
|
@ -28,11 +28,15 @@ import android.content.SharedPreferences;
|
|||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.text.Editable;
|
||||
import android.text.Html;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Patterns;
|
||||
import android.view.ContextThemeWrapper;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
|
@ -72,8 +76,12 @@ import com.google.android.material.snackbar.Snackbar;
|
|||
import com.jaredrummler.cyanea.Cyanea;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import app.fedilab.android.activities.AboutActivity;
|
||||
|
@ -115,6 +123,7 @@ import app.fedilab.android.client.entities.app.PinnedTimeline;
|
|||
import app.fedilab.android.databinding.ActivityMainBinding;
|
||||
import app.fedilab.android.databinding.NavHeaderMainBinding;
|
||||
import app.fedilab.android.exception.DBException;
|
||||
import app.fedilab.android.helper.CrossActionHelper;
|
||||
import app.fedilab.android.helper.Helper;
|
||||
import app.fedilab.android.helper.MastodonHelper;
|
||||
import app.fedilab.android.helper.PinnedTimelineHelper;
|
||||
|
@ -128,6 +137,11 @@ import app.fedilab.android.viewmodel.mastodon.InstancesVM;
|
|||
import app.fedilab.android.viewmodel.mastodon.TimelinesVM;
|
||||
import app.fedilab.android.viewmodel.mastodon.TopBarVM;
|
||||
import es.dmoral.toasty.Toasty;
|
||||
import okhttp3.Call;
|
||||
import okhttp3.Callback;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
|
||||
public abstract class BaseMainActivity extends BaseActivity implements NetworkStateReceiver.NetworkStateReceiverListener {
|
||||
|
||||
|
@ -234,6 +248,8 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
|
|||
private void mamageNewIntent(Intent intent) {
|
||||
if (intent == null)
|
||||
return;
|
||||
String action = intent.getAction();
|
||||
String type = intent.getType();
|
||||
Bundle extras = intent.getExtras();
|
||||
String userIdIntent, instanceIntent;
|
||||
if (extras != null && extras.containsKey(Helper.INTENT_ACTION)) {
|
||||
|
@ -270,6 +286,142 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
|
|||
intent.removeExtra(Helper.INTENT_ACTION);
|
||||
|
||||
}
|
||||
} else if (Intent.ACTION_SEND.equals(action) && type != null) {
|
||||
if ("text/plain".equals(type)) {
|
||||
final String[] url = {null};
|
||||
String sharedSubject = intent.getStringExtra(Intent.EXTRA_SUBJECT);
|
||||
String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
|
||||
//SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(BaseMainActivity.this);
|
||||
//boolean shouldRetrieveMetaData = sharedpreferences.getBoolean(getString(R.string.SET_RETRIEVE_METADATA_IF_URL_FROM_EXTERAL), true);
|
||||
if (sharedText != null) {
|
||||
/* Some apps don't send the URL as the first part of the EXTRA_TEXT,
|
||||
the BBC News app being one such, in this case find where the URL
|
||||
is and strip that out into sharedText.
|
||||
*/
|
||||
Matcher matcher;
|
||||
matcher = Patterns.WEB_URL.matcher(sharedText);
|
||||
while (matcher.find()) {
|
||||
int matchStart = matcher.start(1);
|
||||
int matchEnd = matcher.end();
|
||||
if (matchStart < matchEnd && sharedText.length() >= matchEnd)
|
||||
url[0] = sharedText.substring(matchStart, matchEnd);
|
||||
}
|
||||
new Thread(() -> {
|
||||
if (url[0].startsWith("www."))
|
||||
url[0] = "http://" + url[0];
|
||||
Matcher matcherPattern = Patterns.WEB_URL.matcher(url[0]);
|
||||
String potentialUrl = null;
|
||||
while (matcherPattern.find()) {
|
||||
int matchStart = matcherPattern.start(1);
|
||||
int matchEnd = matcherPattern.end();
|
||||
if (matchStart < matchEnd && url[0].length() >= matchEnd)
|
||||
potentialUrl = url[0].substring(matchStart, matchEnd);
|
||||
}
|
||||
// If we actually have a URL then make use of it.
|
||||
if (potentialUrl != null && potentialUrl.length() > 0) {
|
||||
Pattern titlePattern = Pattern.compile("meta[ a-zA-Z=\"'-]+property=[\"']og:title[\"']\\s+content=[\"']([^>]*)[\"']");
|
||||
Pattern descriptionPattern = Pattern.compile("meta[ a-zA-Z=\"'-]+property=[\"']og:description[\"']\\s+content=[\"']([^>]*)[\"']");
|
||||
Pattern imagePattern = Pattern.compile("meta[ a-zA-Z=\"'-]+property=[\"']og:image[\"']\\s+content=[\"']([^>]*)[\"']");
|
||||
try {
|
||||
OkHttpClient client = new OkHttpClient.Builder()
|
||||
.connectTimeout(10, TimeUnit.SECONDS)
|
||||
.writeTimeout(10, TimeUnit.SECONDS)
|
||||
.proxy(Helper.getProxy(getApplication().getApplicationContext()))
|
||||
.readTimeout(10, TimeUnit.SECONDS).build();
|
||||
Request request = new Request.Builder()
|
||||
.url(potentialUrl)
|
||||
.build();
|
||||
client.newCall(request).enqueue(new Callback() {
|
||||
@Override
|
||||
public void onFailure(@NonNull Call call, @NonNull IOException e) {
|
||||
e.printStackTrace();
|
||||
runOnUiThread(() -> Toasty.warning(BaseMainActivity.this, getString(R.string.toast_error), Toast.LENGTH_LONG).show());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call call, @NonNull final Response response) {
|
||||
if (response.isSuccessful()) {
|
||||
try {
|
||||
String data = response.body().string();
|
||||
Matcher matcherTitle;
|
||||
matcherTitle = titlePattern.matcher(data);
|
||||
Matcher matcherDescription = descriptionPattern.matcher(data);
|
||||
Matcher matcherImage = imagePattern.matcher(data);
|
||||
String titleEncoded = null;
|
||||
String descriptionEncoded = null;
|
||||
while (matcherTitle.find())
|
||||
titleEncoded = matcherTitle.group(1);
|
||||
while (matcherDescription.find())
|
||||
descriptionEncoded = matcherDescription.group(1);
|
||||
String image = null;
|
||||
while (matcherImage.find())
|
||||
image = matcherImage.group(1);
|
||||
String title = null;
|
||||
String description = null;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
if (titleEncoded != null)
|
||||
title = Html.fromHtml(titleEncoded, Html.FROM_HTML_MODE_LEGACY).toString();
|
||||
if (descriptionEncoded != null)
|
||||
description = Html.fromHtml(descriptionEncoded, Html.FROM_HTML_MODE_LEGACY).toString();
|
||||
} else {
|
||||
if (titleEncoded != null)
|
||||
title = Html.fromHtml(titleEncoded).toString();
|
||||
if (descriptionEncoded != null)
|
||||
description = Html.fromHtml(descriptionEncoded).toString();
|
||||
}
|
||||
String finalImage = image;
|
||||
String finalTitle = title;
|
||||
String finalDescription = description;
|
||||
runOnUiThread(() -> {
|
||||
|
||||
|
||||
Bundle b = new Bundle();
|
||||
b.putString(Helper.ARG_SHARE_URL, url[0]);
|
||||
b.putString(Helper.ARG_SHARE_URL_MEDIA, finalImage);
|
||||
b.putString(Helper.ARG_SHARE_TITLE, finalTitle);
|
||||
b.putString(Helper.ARG_SHARE_DESCRIPTION, finalDescription);
|
||||
b.putString(Helper.ARG_SHARE_SUBJECT, sharedSubject);
|
||||
b.putString(Helper.ARG_SHARE_CONTENT, sharedText);
|
||||
CrossActionHelper.doCrossShare(BaseMainActivity.this, b);
|
||||
});
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
runOnUiThread(() -> Toasty.warning(BaseMainActivity.this, getString(R.string.toast_error), Toast.LENGTH_LONG).show());
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
Toasty.warning(BaseMainActivity.this, getString(R.string.toast_error), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
}
|
||||
}).start();
|
||||
|
||||
}
|
||||
} else if (type.startsWith("image/") || type.startsWith("video/")) {
|
||||
Uri imageUri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
|
||||
if (imageUri != null) {
|
||||
intent = new Intent(BaseMainActivity.this, ComposeActivity.class);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
||||
intent.putExtra(Helper.ARG_SHARE_URI, imageUri.toString());
|
||||
startActivity(intent);
|
||||
} else {
|
||||
Toasty.warning(BaseMainActivity.this, getString(R.string.toast_error), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
} else if (Intent.ACTION_SEND_MULTIPLE.equals(action) && type != null) {
|
||||
if (type.startsWith("image/") || type.startsWith("video/")) {
|
||||
ArrayList<Uri> imageList = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
|
||||
if (imageList != null) {
|
||||
Bundle b = new Bundle();
|
||||
b.putParcelableArrayList(Helper.ARG_SHARE_URI_LIST, imageList);
|
||||
CrossActionHelper.doCrossShare(BaseMainActivity.this, b);
|
||||
} else {
|
||||
Toasty.warning(BaseMainActivity.this, getString(R.string.toast_error), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -72,7 +72,6 @@ import app.fedilab.android.client.entities.api.EmojiInstance;
|
|||
import app.fedilab.android.client.entities.api.Mention;
|
||||
import app.fedilab.android.client.entities.api.ScheduledStatus;
|
||||
import app.fedilab.android.client.entities.api.Status;
|
||||
import app.fedilab.android.client.entities.app.Account;
|
||||
import app.fedilab.android.client.entities.app.BaseAccount;
|
||||
import app.fedilab.android.client.entities.app.StatusDraft;
|
||||
import app.fedilab.android.databinding.ActivityPaginationBinding;
|
||||
|
@ -84,6 +83,7 @@ import app.fedilab.android.helper.MastodonHelper;
|
|||
import app.fedilab.android.helper.MediaHelper;
|
||||
import app.fedilab.android.helper.SpannableHelper;
|
||||
import app.fedilab.android.helper.ThemeHelper;
|
||||
import app.fedilab.android.interfaces.OnDownloadInterface;
|
||||
import app.fedilab.android.jobs.ScheduleThreadWorker;
|
||||
import app.fedilab.android.services.PostMessageService;
|
||||
import app.fedilab.android.services.ThreadMessageService;
|
||||
|
@ -134,6 +134,9 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana
|
|||
private app.fedilab.android.client.entities.api.Account accountMention;
|
||||
private String statusReplyId;
|
||||
private app.fedilab.android.client.entities.api.Account mentionBooster;
|
||||
private ArrayList<Uri> sharedUriList = new ArrayList<>();
|
||||
private Uri sharedUri;
|
||||
private String sharedSubject, sharedContent, sharedTitle, sharedDescription, shareURL, sharedUrlMedia;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
@ -160,13 +163,24 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana
|
|||
scheduledStatus = (ScheduledStatus) b.getSerializable(Helper.ARG_STATUS_SCHEDULED);
|
||||
statusReplyId = b.getString(Helper.ARG_STATUS_REPLY_ID);
|
||||
statusMention = (Status) b.getSerializable(Helper.ARG_STATUS_MENTION);
|
||||
account = (Account) b.getSerializable(Helper.ARG_ACCOUNT);
|
||||
account = (BaseAccount) b.getSerializable(Helper.ARG_ACCOUNT);
|
||||
instance = b.getString(Helper.ARG_INSTANCE, null);
|
||||
token = b.getString(Helper.ARG_TOKEN, null);
|
||||
visibility = b.getString(Helper.ARG_VISIBILITY, null);
|
||||
mentionBooster = (app.fedilab.android.client.entities.api.Account) b.getSerializable(Helper.ARG_MENTION_BOOSTER);
|
||||
accountMention = (app.fedilab.android.client.entities.api.Account) b.getSerializable(Helper.ARG_ACCOUNT_MENTION);
|
||||
//Shared elements
|
||||
sharedUriList = b.getParcelableArrayList(Helper.ARG_SHARE_URI_LIST);
|
||||
sharedUri = b.getParcelable(Helper.ARG_SHARE_URI);
|
||||
sharedUrlMedia = b.getString(Helper.ARG_SHARE_URL_MEDIA);
|
||||
sharedSubject = b.getString(Helper.ARG_SHARE_SUBJECT, null);
|
||||
sharedContent = b.getString(Helper.ARG_SHARE_CONTENT, null);
|
||||
sharedTitle = b.getString(Helper.ARG_SHARE_TITLE, null);
|
||||
sharedDescription = b.getString(Helper.ARG_SHARE_DESCRIPTION, null);
|
||||
shareURL = b.getString(Helper.ARG_SHARE_URL, null);
|
||||
}
|
||||
|
||||
|
||||
binding.toolbar.setPopupTheme(Helper.popupStyle());
|
||||
//Edit a scheduled status from server
|
||||
if (scheduledStatus != null) {
|
||||
|
@ -342,6 +356,28 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana
|
|||
storeDraft(false);
|
||||
}
|
||||
}, 0, 10000);
|
||||
|
||||
if (sharedUriList != null && sharedUriList.size() > 0) {
|
||||
List<Uri> uris = new ArrayList<>(sharedUriList);
|
||||
composeAdapter.addAttachment(-1, uris);
|
||||
} else if (sharedUri != null && !sharedUri.toString().startsWith("http")) {
|
||||
List<Uri> uris = new ArrayList<>();
|
||||
uris.add(sharedUri);
|
||||
composeAdapter.addAttachment(-1, uris);
|
||||
} else if (shareURL != null) {
|
||||
Helper.download(ComposeActivity.this, sharedUrlMedia, new OnDownloadInterface() {
|
||||
@Override
|
||||
public void onDownloaded(String saveFilePath, String downloadUrl, Error error) {
|
||||
composeAdapter.addSharing(shareURL, sharedTitle, sharedDescription, sharedSubject, sharedContent, saveFilePath);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateProgress(int progress) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -17,6 +17,7 @@ package app.fedilab.android.helper;
|
|||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
||||
|
@ -34,6 +35,7 @@ import java.util.concurrent.TimeUnit;
|
|||
|
||||
import app.fedilab.android.BaseMainActivity;
|
||||
import app.fedilab.android.R;
|
||||
import app.fedilab.android.activities.BaseActivity;
|
||||
import app.fedilab.android.activities.ComposeActivity;
|
||||
import app.fedilab.android.client.endpoints.MastodonSearchService;
|
||||
import app.fedilab.android.client.entities.api.Results;
|
||||
|
@ -399,6 +401,49 @@ public class CrossActionHelper {
|
|||
}).start();
|
||||
}
|
||||
|
||||
public static void doCrossShare(final Context context, final Bundle bundle) {
|
||||
List<BaseAccount> accounts;
|
||||
try {
|
||||
accounts = new Account(context).getAll();
|
||||
List<app.fedilab.android.client.entities.api.Account> accountList = new ArrayList<>();
|
||||
for (BaseAccount account : accounts) {
|
||||
accountList.add(account.mastodon_account);
|
||||
}
|
||||
if (accounts.size() == 1) {
|
||||
Intent intentToot = new Intent(context, ComposeActivity.class);
|
||||
intentToot.putExtras(bundle);
|
||||
context.startActivity(intentToot);
|
||||
((BaseActivity) context).finish();
|
||||
} else {
|
||||
AlertDialog.Builder builderSingle = new AlertDialog.Builder(context, Helper.dialogStyle());
|
||||
builderSingle.setTitle(context.getString(R.string.choose_accounts));
|
||||
final AccountsSearchAdapter accountsSearchAdapter = new AccountsSearchAdapter(context, accountList);
|
||||
final BaseAccount[] accountArray = new BaseAccount[accounts.size()];
|
||||
int i = 0;
|
||||
for (BaseAccount account : accounts) {
|
||||
accountArray[i] = account;
|
||||
i++;
|
||||
}
|
||||
builderSingle.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
|
||||
builderSingle.setAdapter(accountsSearchAdapter, (dialog, which) -> {
|
||||
final BaseAccount account = accountArray[which];
|
||||
Intent intentToot = new Intent(context, ComposeActivity.class);
|
||||
bundle.putSerializable(Helper.ARG_ACCOUNT, account);
|
||||
intentToot.putExtras(bundle);
|
||||
context.startActivity(intentToot);
|
||||
((BaseActivity) context).finish();
|
||||
dialog.dismiss();
|
||||
});
|
||||
builderSingle.show();
|
||||
}
|
||||
|
||||
} catch (DBException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public enum TypeOfCrossAction {
|
||||
FOLLOW_ACTION,
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
package app.fedilab.android.helper;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Work from https://stackoverflow.com/a/26420820
|
||||
*/
|
||||
|
||||
public class FileNameCleaner {
|
||||
private final static int[] illegalChars = {34, 60, 62, 124, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 58, 42, 63, 92, 47};
|
||||
|
||||
static {
|
||||
Arrays.sort(illegalChars);
|
||||
}
|
||||
|
||||
public static String cleanFileName(String badFileName) {
|
||||
StringBuilder cleanName = new StringBuilder();
|
||||
if (badFileName.contains("?")) {
|
||||
badFileName = badFileName.split("\\?")[0];
|
||||
}
|
||||
int len = badFileName.codePointCount(0, badFileName.length());
|
||||
for (int i = 0; i < len; i++) {
|
||||
int c = badFileName.codePointAt(i);
|
||||
if (Arrays.binarySearch(illegalChars, c) < 0) {
|
||||
cleanName.appendCodePoint(c);
|
||||
}
|
||||
}
|
||||
return cleanName.toString();
|
||||
}
|
||||
}
|
|
@ -107,10 +107,12 @@ import java.io.IOException;
|
|||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.Authenticator;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.PasswordAuthentication;
|
||||
import java.net.Proxy;
|
||||
import java.net.URL;
|
||||
import java.security.Security;
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
|
@ -131,6 +133,7 @@ import java.util.regex.Pattern;
|
|||
import app.fedilab.android.BaseMainActivity;
|
||||
import app.fedilab.android.MainApplication;
|
||||
import app.fedilab.android.R;
|
||||
import app.fedilab.android.activities.ComposeActivity;
|
||||
import app.fedilab.android.activities.LoginActivity;
|
||||
import app.fedilab.android.activities.MainActivity;
|
||||
import app.fedilab.android.activities.WebviewActivity;
|
||||
|
@ -139,6 +142,7 @@ import app.fedilab.android.client.entities.api.Attachment;
|
|||
import app.fedilab.android.client.entities.app.Account;
|
||||
import app.fedilab.android.client.entities.app.BaseAccount;
|
||||
import app.fedilab.android.exception.DBException;
|
||||
import app.fedilab.android.interfaces.OnDownloadInterface;
|
||||
import app.fedilab.android.sqlite.Sqlite;
|
||||
import app.fedilab.android.viewmodel.mastodon.OauthVM;
|
||||
import app.fedilab.android.watermark.androidwm.WatermarkBuilder;
|
||||
|
@ -206,6 +210,14 @@ public class Helper {
|
|||
public static final String ARG_MINIFIED = "ARG_MINIFIED";
|
||||
public static final String ARG_STATUS_REPORT = "ARG_STATUS_REPORT";
|
||||
public static final String ARG_STATUS_MENTION = "ARG_STATUS_MENTION";
|
||||
public static final String ARG_SHARE_URI = "ARG_SHARE_URI";
|
||||
public static final String ARG_SHARE_URL_MEDIA = "ARG_SHARE_URL_MEDIA";
|
||||
public static final String ARG_SHARE_URL = "ARG_SHARE_URL";
|
||||
public static final String ARG_SHARE_URI_LIST = "ARG_SHARE_URI_LIST";
|
||||
public static final String ARG_SHARE_TITLE = "ARG_SHARE_TITLE";
|
||||
public static final String ARG_SHARE_SUBJECT = "ARG_SHARE_SUBJECT";
|
||||
public static final String ARG_SHARE_DESCRIPTION = "ARG_SHARE_DESCRIPTION";
|
||||
public static final String ARG_SHARE_CONTENT = "ARG_SHARE_CONTENT";
|
||||
public static final String ARG_FOLLOW_TYPE = "ARG_FOLLOW_TYPE";
|
||||
public static final String ARG_TYPE_OF_INFO = "ARG_TYPE_OF_INFO";
|
||||
public static final String ARG_TOKEN = "ARG_TOKEN";
|
||||
|
@ -1244,6 +1256,21 @@ public class Helper {
|
|||
}).start();
|
||||
}
|
||||
|
||||
public static void createAttachmentFromPAth(String path, OnAttachmentCopied callBack) {
|
||||
new Thread(() -> {
|
||||
Attachment attachment = new Attachment();
|
||||
attachment.mimeType = "image/*";
|
||||
String extension = "jpg";
|
||||
SimpleDateFormat formatter = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_" + counter, Locale.getDefault());
|
||||
attachment.local_path = path;
|
||||
Date now = new Date();
|
||||
attachment.filename = formatter.format(now) + "." + extension;
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
Runnable myRunnable = () -> callBack.onAttachmentCopied(attachment);
|
||||
mainHandler.post(myRunnable);
|
||||
}).start();
|
||||
}
|
||||
|
||||
/**
|
||||
* change color of a drawable
|
||||
*
|
||||
|
@ -1623,4 +1650,74 @@ public class Helper {
|
|||
})
|
||||
.create();
|
||||
}
|
||||
|
||||
|
||||
/***
|
||||
* Download method which works for http and https connections
|
||||
* @param downloadUrl String download url
|
||||
* @param listener OnDownloadInterface, listener which manages progress
|
||||
*/
|
||||
public static void download(Context context, final String downloadUrl, final OnDownloadInterface listener) {
|
||||
new Thread(() -> {
|
||||
URL url;
|
||||
int CHUNK_SIZE = 4096;
|
||||
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
boolean enable_proxy = sharedpreferences.getBoolean(context.getString(R.string.SET_PROXY_ENABLED), false);
|
||||
Proxy proxy = null;
|
||||
if (enable_proxy) {
|
||||
proxy = getProxy(context);
|
||||
}
|
||||
try {
|
||||
url = new URL(downloadUrl);
|
||||
HttpURLConnection httpURLConnection;
|
||||
if (proxy != null)
|
||||
httpURLConnection = (HttpURLConnection) url.openConnection(proxy);
|
||||
else
|
||||
httpURLConnection = (HttpURLConnection) url.openConnection();
|
||||
httpURLConnection.setRequestProperty("User-Agent", USER_AGENT);
|
||||
int responseCode = httpURLConnection.getResponseCode();
|
||||
|
||||
// always check HTTP response code first
|
||||
if (responseCode == HttpURLConnection.HTTP_OK) {
|
||||
String fileName = "";
|
||||
String disposition = httpURLConnection.getHeaderField("Content-Disposition");
|
||||
|
||||
if (disposition != null) {
|
||||
// extracts file name from header field
|
||||
int index = disposition.indexOf("filename=");
|
||||
if (index > 0) {
|
||||
fileName = disposition.substring(index + 10,
|
||||
disposition.length() - 1);
|
||||
}
|
||||
} else {
|
||||
// extracts file name from URL
|
||||
fileName = downloadUrl.substring(downloadUrl.lastIndexOf("/") + 1);
|
||||
}
|
||||
fileName = FileNameCleaner.cleanFileName(fileName);
|
||||
// opens input stream from the HTTP connection
|
||||
InputStream inputStream = httpURLConnection.getInputStream();
|
||||
File saveDir = context.getCacheDir();
|
||||
final String saveFilePath = saveDir + File.separator + fileName;
|
||||
// opens an output stream to save into file
|
||||
FileOutputStream outputStream = new FileOutputStream(saveFilePath);
|
||||
|
||||
int bytesRead;
|
||||
byte[] buffer = new byte[CHUNK_SIZE];
|
||||
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
||||
outputStream.write(buffer, 0, bytesRead);
|
||||
}
|
||||
outputStream.close();
|
||||
inputStream.close();
|
||||
((ComposeActivity) context).runOnUiThread(() -> listener.onDownloaded(saveFilePath, downloadUrl, null));
|
||||
} else {
|
||||
((ComposeActivity) context).runOnUiThread(() -> listener.onDownloaded(null, downloadUrl, new Error()));
|
||||
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
((ComposeActivity) context).runOnUiThread(() -> listener.onDownloaded(null, downloadUrl, new Error()));
|
||||
}
|
||||
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,9 +74,12 @@ import com.bumptech.glide.request.transition.Transition;
|
|||
|
||||
import java.io.File;
|
||||
import java.text.Normalizer;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
@ -390,6 +393,37 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a shared element
|
||||
* If title and description are empty, it will use subject and content coming from the intent
|
||||
*
|
||||
* @param url - String url that is shared
|
||||
* @param title - String title gather from the URL
|
||||
* @param description - String description gathered from the URL
|
||||
* @param subject - String subject (title) comming from the shared elements
|
||||
* @param content - String content (description) coming from the shared elements
|
||||
*/
|
||||
public void addSharing(String url, String title, String description, String subject, String content, String saveFilePath) {
|
||||
int position = statusList.size() - 1;
|
||||
statusList.get(position).text = title != null ? title : subject;
|
||||
statusList.get(position).text += "\n\n";
|
||||
statusList.get(position).text += description != null ? description : content;
|
||||
statusList.get(position).text += "\n\n";
|
||||
statusList.get(position).text += url;
|
||||
Attachment attachment = new Attachment();
|
||||
attachment.mimeType = "image/*";
|
||||
String extension = "jpg";
|
||||
SimpleDateFormat formatter = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_", Locale.getDefault());
|
||||
attachment.local_path = saveFilePath;
|
||||
Date now = new Date();
|
||||
attachment.filename = formatter.format(now) + "." + extension;
|
||||
if (statusList.get(position).media_attachments == null) {
|
||||
statusList.get(position).media_attachments = new ArrayList<>();
|
||||
}
|
||||
statusList.get(position).media_attachments.add(attachment);
|
||||
notifyItemChanged(position);
|
||||
}
|
||||
|
||||
//<------ Manage contact from compose activity
|
||||
//It only targets last message in a thread
|
||||
//Return content of last compose message
|
||||
|
|
Loading…
Reference in New Issue