mirror of
https://github.com/TeamNewPipe/NewPipe.git
synced 2024-11-22 11:02:35 +01:00
Initial work to add the image of the content in the share sheet
Also do some fixes when sharing a file in downloads and some improvements in JavaDocs of ShareUtils class.
This commit is contained in:
parent
2fb86364ab
commit
d85afd6435
@ -234,7 +234,7 @@ public class RouterActivity extends AppCompatActivity {
|
|||||||
.setPositiveButton(R.string.open_in_browser,
|
.setPositiveButton(R.string.open_in_browser,
|
||||||
(dialog, which) -> ShareUtils.openUrlInBrowser(this, url))
|
(dialog, which) -> ShareUtils.openUrlInBrowser(this, url))
|
||||||
.setNegativeButton(R.string.share,
|
.setNegativeButton(R.string.share,
|
||||||
(dialog, which) -> ShareUtils.shareText(this, "", url, false)) //no subject
|
(dialog, which) -> ShareUtils.shareText(this, "", url, "")) //no subject
|
||||||
.setNeutralButton(R.string.cancel, null)
|
.setNeutralButton(R.string.cancel, null)
|
||||||
.setOnDismissListener(dialog -> finish())
|
.setOnDismissListener(dialog -> finish())
|
||||||
.show();
|
.show();
|
||||||
|
@ -454,8 +454,8 @@ public final class VideoDetailFragment
|
|||||||
break;
|
break;
|
||||||
case R.id.detail_controls_share:
|
case R.id.detail_controls_share:
|
||||||
if (currentInfo != null) {
|
if (currentInfo != null) {
|
||||||
ShareUtils.shareText(requireContext(),
|
ShareUtils.shareText(requireContext(), currentInfo.getName(),
|
||||||
currentInfo.getName(), currentInfo.getUrl());
|
currentInfo.getUrl(), currentInfo.getThumbnailUrl());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case R.id.detail_controls_open_in_browser:
|
case R.id.detail_controls_open_in_browser:
|
||||||
|
@ -203,7 +203,8 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo>
|
|||||||
break;
|
break;
|
||||||
case R.id.menu_item_share:
|
case R.id.menu_item_share:
|
||||||
if (currentInfo != null) {
|
if (currentInfo != null) {
|
||||||
ShareUtils.shareText(requireContext(), name, currentInfo.getOriginalUrl());
|
ShareUtils.shareText(requireContext(), name, currentInfo.getOriginalUrl(),
|
||||||
|
currentInfo.getAvatarUrl());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -251,7 +251,7 @@ public class PlaylistFragment extends BaseListInfoFragment<PlaylistInfo> {
|
|||||||
ShareUtils.openUrlInBrowser(requireContext(), url);
|
ShareUtils.openUrlInBrowser(requireContext(), url);
|
||||||
break;
|
break;
|
||||||
case R.id.menu_item_share:
|
case R.id.menu_item_share:
|
||||||
ShareUtils.shareText(requireContext(), name, url);
|
ShareUtils.shareText(requireContext(), name, url, currentInfo.getThumbnailUrl());
|
||||||
break;
|
break;
|
||||||
case R.id.menu_item_bookmark:
|
case R.id.menu_item_bookmark:
|
||||||
onBookmarkClicked();
|
onBookmarkClicked();
|
||||||
|
@ -293,7 +293,8 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
|
|||||||
|
|
||||||
val actions = DialogInterface.OnClickListener { _, i ->
|
val actions = DialogInterface.OnClickListener { _, i ->
|
||||||
when (i) {
|
when (i) {
|
||||||
0 -> ShareUtils.shareText(requireContext(), selectedItem.name, selectedItem.url)
|
0 -> ShareUtils.shareText(requireContext(), selectedItem.name, selectedItem.url,
|
||||||
|
selectedItem.thumbnailUrl)
|
||||||
1 -> ShareUtils.openUrlInBrowser(requireContext(), selectedItem.url)
|
1 -> ShareUtils.openUrlInBrowser(requireContext(), selectedItem.url)
|
||||||
2 -> deleteChannel(selectedItem)
|
2 -> deleteChannel(selectedItem)
|
||||||
}
|
}
|
||||||
|
@ -313,7 +313,8 @@ public final class PlayQueueActivity extends AppCompatActivity
|
|||||||
final MenuItem share = popupMenu.getMenu().add(RECYCLER_ITEM_POPUP_MENU_GROUP_ID, 3,
|
final MenuItem share = popupMenu.getMenu().add(RECYCLER_ITEM_POPUP_MENU_GROUP_ID, 3,
|
||||||
Menu.NONE, R.string.share);
|
Menu.NONE, R.string.share);
|
||||||
share.setOnMenuItemClickListener(menuItem -> {
|
share.setOnMenuItemClickListener(menuItem -> {
|
||||||
shareText(getApplicationContext(), item.getTitle(), item.getUrl());
|
shareText(getApplicationContext(), item.getTitle(), item.getUrl(),
|
||||||
|
item.getThumbnailUrl());
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -3593,7 +3593,8 @@ public final class Player implements
|
|||||||
} else if (v.getId() == binding.moreOptionsButton.getId()) {
|
} else if (v.getId() == binding.moreOptionsButton.getId()) {
|
||||||
onMoreOptionsClicked();
|
onMoreOptionsClicked();
|
||||||
} else if (v.getId() == binding.share.getId()) {
|
} else if (v.getId() == binding.share.getId()) {
|
||||||
ShareUtils.shareText(context, getVideoTitle(), getVideoUrlAtCurrentTime());
|
ShareUtils.shareText(context, getVideoTitle(), getVideoUrlAtCurrentTime(),
|
||||||
|
currentItem.getThumbnailUrl());
|
||||||
} else if (v.getId() == binding.playWithKodi.getId()) {
|
} else if (v.getId() == binding.playWithKodi.getId()) {
|
||||||
onPlayWithKodiClicked();
|
onPlayWithKodiClicked();
|
||||||
} else if (v.getId() == binding.openInBrowser.getId()) {
|
} else if (v.getId() == binding.openInBrowser.getId()) {
|
||||||
|
@ -8,6 +8,7 @@ import android.content.Intent;
|
|||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.ResolveInfo;
|
import android.content.pm.ResolveInfo;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
@ -25,15 +26,15 @@ public final class ShareUtils {
|
|||||||
* second param (a system chooser will be opened if there are multiple markets and no default)
|
* second param (a system chooser will be opened if there are multiple markets and no default)
|
||||||
* and falls back to Google Play Store web URL if no app to handle the market scheme was found.
|
* and falls back to Google Play Store web URL if no app to handle the market scheme was found.
|
||||||
* <p>
|
* <p>
|
||||||
* It uses {@link ShareUtils#openIntentInApp(Context, Intent, boolean)} to open market scheme
|
* It uses {@link #openIntentInApp(Context, Intent, boolean)} to open market scheme
|
||||||
* and {@link ShareUtils#openUrlInBrowser(Context, String, boolean)} to open Google Play Store
|
* and {@link #openUrlInBrowser(Context, String, boolean)} to open Google Play Store
|
||||||
* web URL with false for the boolean param.
|
* web URL with false for the boolean param.
|
||||||
*
|
*
|
||||||
* @param context the context to use
|
* @param context the context to use
|
||||||
* @param packageId the package id of the app to be installed
|
* @param packageId the package id of the app to be installed
|
||||||
*/
|
*/
|
||||||
public static void installApp(final Context context, final String packageId) {
|
public static void installApp(final Context context, final String packageId) {
|
||||||
// Try market:// scheme
|
// Try market scheme
|
||||||
final boolean marketSchemeResult = openIntentInApp(context, new Intent(Intent.ACTION_VIEW,
|
final boolean marketSchemeResult = openIntentInApp(context, new Intent(Intent.ACTION_VIEW,
|
||||||
Uri.parse("market://details?id=" + packageId))
|
Uri.parse("market://details?id=" + packageId))
|
||||||
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK), false);
|
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK), false);
|
||||||
@ -48,7 +49,7 @@ public final class ShareUtils {
|
|||||||
* Open the url with the system default browser.
|
* Open the url with the system default browser.
|
||||||
* <p>
|
* <p>
|
||||||
* If no browser is set as default, fallbacks to
|
* If no browser is set as default, fallbacks to
|
||||||
* {@link ShareUtils#openAppChooser(Context, Intent, boolean)}
|
* {@link #openAppChooser(Context, Intent, boolean)}
|
||||||
*
|
*
|
||||||
* @param context the context to use
|
* @param context the context to use
|
||||||
* @param url the url to browse
|
* @param url the url to browse
|
||||||
@ -56,7 +57,8 @@ public final class ShareUtils {
|
|||||||
* for HTTP protocol or for the created intent
|
* for HTTP protocol or for the created intent
|
||||||
* @return true if the URL can be opened or false if it cannot
|
* @return true if the URL can be opened or false if it cannot
|
||||||
*/
|
*/
|
||||||
public static boolean openUrlInBrowser(final Context context, final String url,
|
public static boolean openUrlInBrowser(final Context context,
|
||||||
|
final String url,
|
||||||
final boolean httpDefaultBrowserTest) {
|
final boolean httpDefaultBrowserTest) {
|
||||||
final String defaultPackageName;
|
final String defaultPackageName;
|
||||||
final Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url))
|
final Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url))
|
||||||
@ -96,9 +98,9 @@ public final class ShareUtils {
|
|||||||
* Open the url with the system default browser.
|
* Open the url with the system default browser.
|
||||||
* <p>
|
* <p>
|
||||||
* If no browser is set as default, fallbacks to
|
* If no browser is set as default, fallbacks to
|
||||||
* {@link ShareUtils#openAppChooser(Context, Intent, boolean)}
|
* {@link #openAppChooser(Context, Intent, boolean)}
|
||||||
* <p>
|
* <p>
|
||||||
* This calls {@link ShareUtils#openUrlInBrowser(Context, String, boolean)} with true
|
* This calls {@link #openUrlInBrowser(Context, String, boolean)} with true
|
||||||
* for the boolean parameter
|
* for the boolean parameter
|
||||||
*
|
*
|
||||||
* @param context the context to use
|
* @param context the context to use
|
||||||
@ -113,19 +115,20 @@ public final class ShareUtils {
|
|||||||
* Open an intent with the system default app.
|
* Open an intent with the system default app.
|
||||||
* <p>
|
* <p>
|
||||||
* The intent can be of every type, excepted a web intent for which
|
* The intent can be of every type, excepted a web intent for which
|
||||||
* {@link ShareUtils#openUrlInBrowser(Context, String, boolean)} should be used.
|
* {@link #openUrlInBrowser(Context, String, boolean)} should be used.
|
||||||
* <p>
|
* <p>
|
||||||
* If no app is set as default, fallbacks to
|
* If no app is set as default, fallbacks to
|
||||||
* {@link ShareUtils#openAppChooser(Context, Intent, boolean)}.
|
* {@link #openAppChooser(Context, Intent, boolean)}.
|
||||||
* <p>
|
* <p>
|
||||||
*
|
*
|
||||||
* @param context the context to use
|
* @param context the context to use
|
||||||
* @param intent the intent to open
|
* @param intent the intent to open
|
||||||
* @param showToast the boolean to set if a toast is displayed to user when no app is installed
|
* @param showToast a boolean to set if a toast is displayed to user when no app is installed
|
||||||
* to open the intent (true) or not (false)
|
* to open the intent (true) or not (false)
|
||||||
* @return true if the intent can be opened or false if it cannot be
|
* @return true if the intent can be opened or false if it cannot be
|
||||||
*/
|
*/
|
||||||
public static boolean openIntentInApp(final Context context, final Intent intent,
|
public static boolean openIntentInApp(final Context context,
|
||||||
|
final Intent intent,
|
||||||
final boolean showToast) {
|
final boolean showToast) {
|
||||||
final String defaultPackageName = getDefaultAppPackageName(context, intent);
|
final String defaultPackageName = getDefaultAppPackageName(context, intent);
|
||||||
|
|
||||||
@ -178,6 +181,36 @@ public final class ShareUtils {
|
|||||||
if (setTitleChooser) {
|
if (setTitleChooser) {
|
||||||
chooserIntent.putExtra(Intent.EXTRA_TITLE, context.getString(R.string.open_with));
|
chooserIntent.putExtra(Intent.EXTRA_TITLE, context.getString(R.string.open_with));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Migrate any clip data and flags from the original intent.
|
||||||
|
final int permFlags;
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
permFlags = intent.getFlags() & (Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||||
|
| Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
||||||
|
| Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
|
||||||
|
| Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
|
||||||
|
} else {
|
||||||
|
permFlags = intent.getFlags() & (Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||||
|
| Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
||||||
|
| Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
|
||||||
|
}
|
||||||
|
if (permFlags != 0) {
|
||||||
|
ClipData targetClipData = intent.getClipData();
|
||||||
|
if (targetClipData == null && intent.getData() != null) {
|
||||||
|
final ClipData.Item item = new ClipData.Item(intent.getData());
|
||||||
|
final String[] mimeTypes;
|
||||||
|
if (intent.getType() != null) {
|
||||||
|
mimeTypes = new String[] {intent.getType()};
|
||||||
|
} else {
|
||||||
|
mimeTypes = new String[] {};
|
||||||
|
}
|
||||||
|
targetClipData = new ClipData(null, mimeTypes, item);
|
||||||
|
}
|
||||||
|
if (targetClipData != null) {
|
||||||
|
chooserIntent.setClipData(targetClipData);
|
||||||
|
chooserIntent.addFlags(permFlags);
|
||||||
|
}
|
||||||
|
}
|
||||||
context.startActivity(chooserIntent);
|
context.startActivity(chooserIntent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,24 +241,45 @@ public final class ShareUtils {
|
|||||||
/**
|
/**
|
||||||
* Open the android share menu to share the current url.
|
* Open the android share menu to share the current url.
|
||||||
*
|
*
|
||||||
* @param context the context to use
|
* @param context the context to use
|
||||||
* @param subject the url subject, typically the title
|
* @param subject the url subject, typically the title
|
||||||
* @param url the url to share
|
* @param url the url to share
|
||||||
|
* @param imagePreviewUrl the image of the subject
|
||||||
*/
|
*/
|
||||||
public static void shareText(final Context context, final String subject, final String url) {
|
|
||||||
shareText(context, subject, url, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static void shareText(final Context context,
|
public static void shareText(final Context context,
|
||||||
final String subject,
|
final String subject,
|
||||||
final String url,
|
final String url,
|
||||||
|
final String imagePreviewUrl) {
|
||||||
|
shareText(context, subject, url, imagePreviewUrl, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open the android share sheet to share the current url.
|
||||||
|
*
|
||||||
|
* For Android 10+ users, a content preview is shown, which includes the title of the shared
|
||||||
|
* content.
|
||||||
|
* Support sharing the image of the content needs to done, if possible.
|
||||||
|
*
|
||||||
|
* @param context the context to use
|
||||||
|
* @param subject the url subject, typically the title
|
||||||
|
* @param url the url to share
|
||||||
|
* @param imagePreviewUrl the image of the subject
|
||||||
|
* @param showPreviewText show the subject as an extra title of the Android share sheet if true
|
||||||
|
*/
|
||||||
|
public static void shareText(final Context context,
|
||||||
|
final String subject,
|
||||||
|
final String url,
|
||||||
|
final String imagePreviewUrl,
|
||||||
final boolean showPreviewText) {
|
final boolean showPreviewText) {
|
||||||
final Intent shareIntent = new Intent(Intent.ACTION_SEND);
|
final Intent shareIntent = new Intent(Intent.ACTION_SEND);
|
||||||
shareIntent.setType("text/plain");
|
shareIntent.setType("text/plain");
|
||||||
if (!subject.isEmpty() && showPreviewText) {
|
if (!imagePreviewUrl.isEmpty() && !subject.isEmpty() && showPreviewText) {
|
||||||
shareIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
|
|
||||||
shareIntent.putExtra(Intent.EXTRA_TITLE, subject);
|
shareIntent.putExtra(Intent.EXTRA_TITLE, subject);
|
||||||
|
/* TODO: add the image of the content to Android share sheet with setClipData after
|
||||||
|
generating a content URI of this image, then use ClipData.newUri(the content
|
||||||
|
resolver, null, the content URI) and set the ClipData to the share intent with
|
||||||
|
shareIntent.setClipData(generated ClipData).*/
|
||||||
|
//shareIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||||
}
|
}
|
||||||
shareIntent.putExtra(Intent.EXTRA_TEXT, url);
|
shareIntent.putExtra(Intent.EXTRA_TEXT, url);
|
||||||
|
|
||||||
|
@ -88,7 +88,8 @@ public enum StreamDialogEntry {
|
|||||||
}),
|
}),
|
||||||
|
|
||||||
share(R.string.share, (fragment, item) ->
|
share(R.string.share, (fragment, item) ->
|
||||||
ShareUtils.shareText(fragment.getContext(), item.getName(), item.getUrl())),
|
ShareUtils.shareText(fragment.getContext(), item.getName(), item.getUrl(),
|
||||||
|
item.getThumbnailUrl())),
|
||||||
|
|
||||||
open_in_browser(R.string.open_in_browser, (fragment, item) ->
|
open_in_browser(R.string.open_in_browser, (fragment, item) ->
|
||||||
ShareUtils.openUrlInBrowser(fragment.getContext(), item.getUrl()));
|
ShareUtils.openUrlInBrowser(fragment.getContext(), item.getUrl()));
|
||||||
|
@ -376,8 +376,11 @@ public class MissionAdapter extends Adapter<ViewHolder> implements Handler.Callb
|
|||||||
|
|
||||||
final Intent intent = new Intent(Intent.ACTION_CHOOSER);
|
final Intent intent = new Intent(Intent.ACTION_CHOOSER);
|
||||||
intent.putExtra(Intent.EXTRA_INTENT, shareIntent);
|
intent.putExtra(Intent.EXTRA_INTENT, shareIntent);
|
||||||
intent.putExtra(Intent.EXTRA_TITLE, mContext.getString(R.string.share_dialog_title));
|
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.O_MR1) {
|
||||||
|
intent.putExtra(Intent.EXTRA_TITLE, mContext.getString(R.string.share_dialog_title));
|
||||||
|
}
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
|
intent.addFlags(FLAG_GRANT_READ_URI_PERMISSION);
|
||||||
|
|
||||||
mContext.startActivity(intent);
|
mContext.startActivity(intent);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user