Merge pull request #9850 from Stypox/fix-api33-links-again3
[Android 11+] Correctly open URLs in browser and fix opening downloads and external players
This commit is contained in:
commit
4b050c0dd8
83 changed files with 135 additions and 264 deletions
|
|
@ -6,6 +6,7 @@ import android.view.MenuItem
|
|||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Button
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
|
|
@ -57,13 +58,9 @@ class AboutActivity : AppCompatActivity() {
|
|||
* A placeholder fragment containing a simple view.
|
||||
*/
|
||||
class AboutFragment : Fragment() {
|
||||
private fun Button.openLink(url: Int) {
|
||||
private fun Button.openLink(@StringRes url: Int) {
|
||||
setOnClickListener {
|
||||
ShareUtils.openUrlInBrowser(
|
||||
context,
|
||||
requireContext().getString(url),
|
||||
false
|
||||
)
|
||||
ShareUtils.openUrlInApp(context, requireContext().getString(url))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ fun showLicense(context: Context?, component: SoftwareComponent): Disposable {
|
|||
dialog.dismiss()
|
||||
}
|
||||
setNeutralButton(R.string.open_website_license) { _, _ ->
|
||||
ShareUtils.openUrlInBrowser(context!!, component.link)
|
||||
ShareUtils.openUrlInApp(context!!, component.link)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ public class ErrorActivity extends AppCompatActivity {
|
|||
.setMessage(R.string.start_accept_privacy_policy)
|
||||
.setCancelable(false)
|
||||
.setNeutralButton(R.string.read_privacy_policy, (dialog, which) ->
|
||||
ShareUtils.openUrlInBrowser(context,
|
||||
ShareUtils.openUrlInApp(context,
|
||||
context.getString(R.string.privacy_policy_url)))
|
||||
.setPositiveButton(R.string.accept, (dialog, which) -> {
|
||||
if (action.equals("EMAIL")) { // send on email
|
||||
|
|
@ -171,9 +171,9 @@ public class ErrorActivity extends AppCompatActivity {
|
|||
+ getString(R.string.app_name) + " "
|
||||
+ BuildConfig.VERSION_NAME)
|
||||
.putExtra(Intent.EXTRA_TEXT, buildJson());
|
||||
ShareUtils.openIntentInApp(context, i, true);
|
||||
ShareUtils.openIntentInApp(context, i);
|
||||
} else if (action.equals("GITHUB")) { // open the NewPipe issue page on GitHub
|
||||
ShareUtils.openUrlInBrowser(this, ERROR_GITHUB_ISSUE_URL, false);
|
||||
ShareUtils.openUrlInApp(this, ERROR_GITHUB_ISSUE_URL);
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.decline, (dialog, which) -> {
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ class ErrorPanelHelper(
|
|||
) {
|
||||
errorOpenInBrowserButton.isVisible = true
|
||||
errorOpenInBrowserButton.setOnClickListener {
|
||||
ShareUtils.openUrlInBrowser(context, errorInfo.request, true)
|
||||
ShareUtils.openUrlInBrowser(context, errorInfo.request)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import static org.schabi.newpipe.player.playqueue.PlayQueueItem.RECOVERY_UNSET;
|
|||
import static org.schabi.newpipe.util.ExtractorHelper.showMetaInfoInTextView;
|
||||
import static org.schabi.newpipe.util.ListHelper.getUrlAndNonTorrentStreams;
|
||||
import static org.schabi.newpipe.util.NavigationHelper.openPlayQueue;
|
||||
import static org.schabi.newpipe.util.NavigationHelper.playWithKore;
|
||||
|
||||
import android.animation.ValueAnimator;
|
||||
import android.annotation.SuppressLint;
|
||||
|
|
@ -485,16 +484,8 @@ public final class VideoDetailFragment
|
|||
info.getThumbnailUrl())));
|
||||
binding.detailControlsOpenInBrowser.setOnClickListener(makeOnClickListener(info ->
|
||||
ShareUtils.openUrlInBrowser(requireContext(), info.getUrl())));
|
||||
binding.detailControlsPlayWithKodi.setOnClickListener(makeOnClickListener(info -> {
|
||||
try {
|
||||
playWithKore(requireContext(), Uri.parse(info.getUrl()));
|
||||
} catch (final Exception e) {
|
||||
if (DEBUG) {
|
||||
Log.i(TAG, "Failed to start kore", e);
|
||||
}
|
||||
KoreUtils.showInstallKoreDialog(requireContext());
|
||||
}
|
||||
}));
|
||||
binding.detailControlsPlayWithKodi.setOnClickListener(makeOnClickListener(info ->
|
||||
KoreUtils.playWithKore(requireContext(), Uri.parse(info.getUrl()))));
|
||||
if (DEBUG) {
|
||||
binding.detailControlsCrashThePlayer.setOnClickListener(v ->
|
||||
VideoDetailPlayerCrasher.onCrashThePlayer(requireContext(), player));
|
||||
|
|
|
|||
|
|
@ -204,8 +204,7 @@ public class ChannelFragment extends BaseListInfoFragment<StreamInfoItem, Channe
|
|||
break;
|
||||
case R.id.menu_item_rss:
|
||||
if (currentInfo != null) {
|
||||
ShareUtils.openUrlInBrowser(
|
||||
requireContext(), currentInfo.getFeedUrl(), false);
|
||||
ShareUtils.openUrlInApp(requireContext(), currentInfo.getFeedUrl());
|
||||
}
|
||||
break;
|
||||
case R.id.menu_item_openInBrowser:
|
||||
|
|
|
|||
|
|
@ -99,14 +99,8 @@ public enum StreamDialogDefaultEntry {
|
|||
)
|
||||
),
|
||||
|
||||
PLAY_WITH_KODI(R.string.play_with_kodi_title, (fragment, item) -> {
|
||||
final Uri videoUrl = Uri.parse(item.getUrl());
|
||||
try {
|
||||
NavigationHelper.playWithKore(fragment.requireContext(), videoUrl);
|
||||
} catch (final Exception e) {
|
||||
KoreUtils.showInstallKoreDialog(fragment.requireActivity());
|
||||
}
|
||||
}),
|
||||
PLAY_WITH_KODI(R.string.play_with_kodi_title, (fragment, item) ->
|
||||
KoreUtils.playWithKore(fragment.requireContext(), Uri.parse(item.getUrl()))),
|
||||
|
||||
SHARE(R.string.share, (fragment, item) ->
|
||||
ShareUtils.shareText(fragment.requireContext(), item.getName(), item.getUrl(),
|
||||
|
|
|
|||
|
|
@ -1420,14 +1420,7 @@ public abstract class VideoPlayerUi extends PlayerUi implements SeekBar.OnSeekBa
|
|||
private void onPlayWithKodiClicked() {
|
||||
if (player.getCurrentMetadata() != null) {
|
||||
player.pause();
|
||||
try {
|
||||
NavigationHelper.playWithKore(context, Uri.parse(player.getVideoUrl()));
|
||||
} catch (final Exception e) {
|
||||
if (DEBUG) {
|
||||
Log.i(TAG, "Failed to start kore", e);
|
||||
}
|
||||
KoreUtils.showInstallKoreDialog(player.getContext());
|
||||
}
|
||||
KoreUtils.playWithKore(context, Uri.parse(player.getVideoUrl()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package org.schabi.newpipe.util;
|
||||
|
||||
import static org.schabi.newpipe.util.external_communication.ShareUtils.installApp;
|
||||
import static org.schabi.newpipe.util.ListHelper.getUrlAndNonTorrentStreams;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
|
|
@ -50,9 +50,9 @@ import org.schabi.newpipe.local.history.StatisticsPlaylistFragment;
|
|||
import org.schabi.newpipe.local.playlist.LocalPlaylistFragment;
|
||||
import org.schabi.newpipe.local.subscription.SubscriptionFragment;
|
||||
import org.schabi.newpipe.local.subscription.SubscriptionsImportFragment;
|
||||
import org.schabi.newpipe.player.PlayerService;
|
||||
import org.schabi.newpipe.player.PlayQueueActivity;
|
||||
import org.schabi.newpipe.player.Player;
|
||||
import org.schabi.newpipe.player.PlayerService;
|
||||
import org.schabi.newpipe.player.PlayerType;
|
||||
import org.schabi.newpipe.player.helper.PlayerHelper;
|
||||
import org.schabi.newpipe.player.helper.PlayerHolder;
|
||||
|
|
@ -63,8 +63,6 @@ import org.schabi.newpipe.util.external_communication.ShareUtils;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import static org.schabi.newpipe.util.ListHelper.getUrlAndNonTorrentStreams;
|
||||
|
||||
public final class NavigationHelper {
|
||||
public static final String MAIN_FRAGMENT_TAG = "main_fragment_tag";
|
||||
public static final String SEARCH_FRAGMENT_TAG = "search_fragment_tag";
|
||||
|
|
@ -323,15 +321,13 @@ public final class NavigationHelper {
|
|||
|
||||
public static void resolveActivityOrAskToInstall(@NonNull final Context context,
|
||||
@NonNull final Intent intent) {
|
||||
if (intent.resolveActivity(context.getPackageManager()) != null) {
|
||||
ShareUtils.openIntentInApp(context, intent, false);
|
||||
} else {
|
||||
if (!ShareUtils.tryOpenIntentInApp(context, intent)) {
|
||||
if (context instanceof Activity) {
|
||||
new AlertDialog.Builder(context)
|
||||
.setMessage(R.string.no_player_found)
|
||||
.setPositiveButton(R.string.install,
|
||||
(dialog, which) -> ShareUtils.openUrlInBrowser(context,
|
||||
context.getString(R.string.fdroid_vlc_url), false))
|
||||
(dialog, which) -> ShareUtils.installApp(context,
|
||||
context.getString(R.string.vlc_package)))
|
||||
.setNegativeButton(R.string.cancel, (dialog, which)
|
||||
-> Log.i("NavigationHelper", "You unlocked a secret unicorn."))
|
||||
.show();
|
||||
|
|
@ -684,34 +680,6 @@ public final class NavigationHelper {
|
|||
return getOpenIntent(context, url, serviceId, StreamingService.LinkType.CHANNEL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start an activity to install Kore.
|
||||
*
|
||||
* @param context the context
|
||||
*/
|
||||
public static void installKore(final Context context) {
|
||||
installApp(context, context.getString(R.string.kore_package));
|
||||
}
|
||||
|
||||
/**
|
||||
* Start Kore app to show a video on Kodi.
|
||||
* <p>
|
||||
* For a list of supported urls see the
|
||||
* <a href="https://github.com/xbmc/Kore/blob/master/app/src/main/AndroidManifest.xml">
|
||||
* Kore source code
|
||||
* </a>.
|
||||
*
|
||||
* @param context the context to use
|
||||
* @param videoURL the url to the video
|
||||
*/
|
||||
public static void playWithKore(final Context context, final Uri videoURL) {
|
||||
final Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setPackage(context.getString(R.string.kore_package));
|
||||
intent.setData(videoURL);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finish this <code>Activity</code> as well as all <code>Activities</code> running below it
|
||||
* and then start <code>MainActivity</code>.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,11 @@
|
|||
package org.schabi.newpipe.util.external_communication;
|
||||
|
||||
import static org.schabi.newpipe.util.external_communication.ShareUtils.installApp;
|
||||
import static org.schabi.newpipe.util.external_communication.ShareUtils.tryOpenIntentInApp;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
|
|
@ -8,7 +13,6 @@ import androidx.preference.PreferenceManager;
|
|||
|
||||
import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.extractor.ServiceList;
|
||||
import org.schabi.newpipe.util.NavigationHelper;
|
||||
|
||||
/**
|
||||
* Util class that provides methods which are related to the Kodi Media Center and its Kore app.
|
||||
|
|
@ -29,13 +33,39 @@ public final class KoreUtils {
|
|||
.getBoolean(context.getString(R.string.show_play_with_kodi_key), false);
|
||||
}
|
||||
|
||||
public static void showInstallKoreDialog(@NonNull final Context context) {
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setMessage(R.string.kore_not_found)
|
||||
.setPositiveButton(R.string.install, (dialog, which) ->
|
||||
NavigationHelper.installKore(context))
|
||||
.setNegativeButton(R.string.cancel, (dialog, which) -> {
|
||||
});
|
||||
builder.create().show();
|
||||
/**
|
||||
* Start an activity to install Kore.
|
||||
*
|
||||
* @param context the context to use
|
||||
*/
|
||||
public static void installKore(final Context context) {
|
||||
installApp(context, context.getString(R.string.kore_package));
|
||||
}
|
||||
|
||||
/**
|
||||
* Start Kore app to show a video on Kodi, and if the app is not installed ask the user to
|
||||
* install it.
|
||||
* <p>
|
||||
* For a list of supported urls see the
|
||||
* <a href="https://github.com/xbmc/Kore/blob/master/app/src/main/AndroidManifest.xml">
|
||||
* Kore source code
|
||||
* </a>.
|
||||
*
|
||||
* @param context the context to use
|
||||
* @param streamUrl the url to the stream to play
|
||||
*/
|
||||
public static void playWithKore(final Context context, final Uri streamUrl) {
|
||||
final Intent intent = new Intent(Intent.ACTION_VIEW)
|
||||
.setPackage(context.getString(R.string.kore_package))
|
||||
.setData(streamUrl)
|
||||
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
|
||||
if (!tryOpenIntentInApp(context, intent)) {
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setMessage(R.string.kore_not_found)
|
||||
.setPositiveButton(R.string.install, (dialog, which) -> installKore(context))
|
||||
.setNegativeButton(R.string.cancel, (dialog, which) -> { });
|
||||
builder.create().show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,60 +41,67 @@ public final class ShareUtils {
|
|||
* 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.
|
||||
* <p>
|
||||
* It uses {@link #openIntentInApp(Context, Intent, boolean)} to open market scheme
|
||||
* and {@link #openUrlInBrowser(Context, String, boolean)} to open Google Play Store
|
||||
* web URL with false for the boolean param.
|
||||
* It uses {@link #openIntentInApp(Context, Intent)} to open market scheme and {@link
|
||||
* #openUrlInBrowser(Context, String)} to open Google Play Store web URL.
|
||||
*
|
||||
* @param context the context to use
|
||||
* @param packageId the package id of the app to be installed
|
||||
*/
|
||||
public static void installApp(@NonNull final Context context, final String packageId) {
|
||||
// Try market scheme
|
||||
final boolean marketSchemeResult = openIntentInApp(context, new Intent(Intent.ACTION_VIEW,
|
||||
final Intent marketSchemeIntent = new Intent(Intent.ACTION_VIEW,
|
||||
Uri.parse("market://details?id=" + packageId))
|
||||
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK), false);
|
||||
if (!marketSchemeResult) {
|
||||
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
if (!tryOpenIntentInApp(context, marketSchemeIntent)) {
|
||||
// Fall back to Google Play Store Web URL (F-Droid can handle it)
|
||||
openUrlInBrowser(context,
|
||||
"https://play.google.com/store/apps/details?id=" + packageId, false);
|
||||
openUrlInApp(context, "https://play.google.com/store/apps/details?id=" + packageId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the url with the system default browser.
|
||||
* Open the url with the system default browser. If no browser is set as default, falls back to
|
||||
* {@link #openAppChooser(Context, Intent, boolean)}.
|
||||
* <p>
|
||||
* If no browser is set as default, fallbacks to
|
||||
* {@link #openAppChooser(Context, Intent, boolean)}
|
||||
* This function selects the package to open based on which apps respond to the {@code http://}
|
||||
* schema alone, which should exclude special non-browser apps that are can handle the url (e.g.
|
||||
* the official YouTube app).
|
||||
* <p>
|
||||
* Therefore <b>please prefer {@link #openUrlInApp(Context, String)}</b>, that handles package
|
||||
* resolution in a standard way, unless this is the action of an explicit "Open in browser"
|
||||
* button.
|
||||
*
|
||||
* @param context the context to use
|
||||
* @param url the url to browse
|
||||
* @param httpDefaultBrowserTest the boolean to set if the test for the default browser will be
|
||||
* for HTTP protocol or for the created intent
|
||||
* @return true if the URL can be opened or false if it cannot
|
||||
*/
|
||||
public static boolean openUrlInBrowser(@NonNull final Context context,
|
||||
final String url,
|
||||
final boolean httpDefaultBrowserTest) {
|
||||
final String defaultPackageName;
|
||||
* @param context the context to use
|
||||
* @param url the url to browse
|
||||
**/
|
||||
public static void openUrlInBrowser(@NonNull final Context context, final String url) {
|
||||
// Resolve using a generic http://, so we are sure to get a browser and not e.g. the yt app.
|
||||
// Note that this requires the `http` schema to be added to `<queries>` in the manifest.
|
||||
final ResolveInfo defaultBrowserInfo;
|
||||
final Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://"));
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
defaultBrowserInfo = context.getPackageManager().resolveActivity(browserIntent,
|
||||
PackageManager.ResolveInfoFlags.of(PackageManager.MATCH_DEFAULT_ONLY));
|
||||
} else {
|
||||
defaultBrowserInfo = context.getPackageManager().resolveActivity(browserIntent,
|
||||
PackageManager.MATCH_DEFAULT_ONLY);
|
||||
}
|
||||
|
||||
if (defaultBrowserInfo == null) {
|
||||
// No app installed to open a web url
|
||||
Toast.makeText(context, R.string.no_app_to_open_intent, Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
final String defaultBrowserPackage = defaultBrowserInfo.activityInfo.packageName;
|
||||
final Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url))
|
||||
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
|
||||
if (httpDefaultBrowserTest) {
|
||||
defaultPackageName = getDefaultAppPackageName(context, new Intent(Intent.ACTION_VIEW,
|
||||
Uri.parse("http://")).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
|
||||
} else {
|
||||
defaultPackageName = getDefaultAppPackageName(context, intent);
|
||||
}
|
||||
|
||||
if (defaultPackageName.equals("android")) {
|
||||
if (defaultBrowserPackage.equals("android")) {
|
||||
// No browser set as default (doesn't work on some devices)
|
||||
openAppChooser(context, intent, true);
|
||||
} else {
|
||||
try {
|
||||
// will be empty on Android 12+
|
||||
if (!defaultPackageName.isEmpty()) {
|
||||
intent.setPackage(defaultPackageName);
|
||||
}
|
||||
intent.setPackage(defaultBrowserPackage);
|
||||
context.startActivity(intent);
|
||||
} catch (final ActivityNotFoundException e) {
|
||||
// Not a browser but an app chooser because of OEMs changes
|
||||
|
|
@ -102,61 +109,56 @@ public final class ShareUtils {
|
|||
openAppChooser(context, intent, true);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the url with the system default browser.
|
||||
* <p>
|
||||
* If no browser is set as default, fallbacks to
|
||||
* {@link #openAppChooser(Context, Intent, boolean)}
|
||||
* <p>
|
||||
* This calls {@link #openUrlInBrowser(Context, String, boolean)} with true
|
||||
* for the boolean parameter
|
||||
* Open a url with the system default app using {@link Intent#ACTION_VIEW}, showing a toast in
|
||||
* case of failure.
|
||||
*
|
||||
* @param context the context to use
|
||||
* @param url the url to browse
|
||||
* @return true if the URL can be opened or false if it cannot be
|
||||
**/
|
||||
public static boolean openUrlInBrowser(@NonNull final Context context, final String url) {
|
||||
return openUrlInBrowser(context, url, true);
|
||||
* @param url the url to open
|
||||
*/
|
||||
public static void openUrlInApp(@NonNull final Context context, final String url) {
|
||||
openIntentInApp(context, new Intent(Intent.ACTION_VIEW, Uri.parse(url))
|
||||
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
|
||||
}
|
||||
|
||||
/**
|
||||
* Open an intent with the system default app.
|
||||
* <p>
|
||||
* The intent can be of every type, excepted a web intent for which
|
||||
* {@link #openUrlInBrowser(Context, String, boolean)} should be used.
|
||||
* <p>
|
||||
* If no app can open the intent, a toast with the message {@code No app on your device can
|
||||
* open this} is shown.
|
||||
* Use {@link #openIntentInApp(Context, Intent)} to show a toast in case of failure.
|
||||
*
|
||||
* @param context the context to use
|
||||
* @param intent the intent to open
|
||||
* @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)
|
||||
* @return true if the intent can be opened or false if it cannot be
|
||||
* @param context the context to use
|
||||
* @param intent the intent to open
|
||||
* @return true if the intent could be opened successfully, false otherwise
|
||||
*/
|
||||
public static boolean openIntentInApp(@NonNull final Context context,
|
||||
@NonNull final Intent intent,
|
||||
final boolean showToast) {
|
||||
final String defaultPackageName = getDefaultAppPackageName(context, intent);
|
||||
|
||||
if (defaultPackageName.isEmpty()) {
|
||||
// No app installed to open the intent
|
||||
if (showToast) {
|
||||
Toast.makeText(context, R.string.no_app_to_open_intent, Toast.LENGTH_LONG)
|
||||
.show();
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
public static boolean tryOpenIntentInApp(@NonNull final Context context,
|
||||
@NonNull final Intent intent) {
|
||||
try {
|
||||
context.startActivity(intent);
|
||||
} catch (final ActivityNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open an intent with the system default app, showing a toast in case of failure.
|
||||
* <p>
|
||||
* Use {@link #tryOpenIntentInApp(Context, Intent)} if you don't want the toast. Use {@link
|
||||
* #openUrlInApp(Context, String)} as a shorthand for {@link Intent#ACTION_VIEW} with urls.
|
||||
*
|
||||
* @param context the context to use
|
||||
* @param intent the intent to
|
||||
*/
|
||||
public static void openIntentInApp(@NonNull final Context context,
|
||||
@NonNull final Intent intent) {
|
||||
if (!tryOpenIntentInApp(context, intent)) {
|
||||
Toast.makeText(context, R.string.no_app_to_open_intent, Toast.LENGTH_LONG)
|
||||
.show();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the system chooser to launch an intent.
|
||||
* <p>
|
||||
|
|
@ -206,31 +208,6 @@ public final class ShareUtils {
|
|||
context.startActivity(chooserIntent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default app package name.
|
||||
* <p>
|
||||
* If no app is set as default, it will return "android" (not on some devices because some
|
||||
* OEMs changed the app chooser).
|
||||
* <p>
|
||||
* If no app is installed on user's device to handle the intent, it will return an empty string.
|
||||
*
|
||||
* @param context the context to use
|
||||
* @param intent the intent to get default app
|
||||
* @return the package name of the default app, an empty string if there's no app installed to
|
||||
* handle the intent or the app chooser if there's no default
|
||||
*/
|
||||
private static String getDefaultAppPackageName(@NonNull final Context context,
|
||||
@NonNull final Intent intent) {
|
||||
final ResolveInfo resolveInfo = context.getPackageManager().resolveActivity(intent,
|
||||
PackageManager.MATCH_DEFAULT_ONLY);
|
||||
|
||||
if (resolveInfo == null) {
|
||||
return "";
|
||||
} else {
|
||||
return resolveInfo.activityInfo.packageName;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the android share sheet to share a content.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ final class UrlLongPressClickableSpan extends LongPressClickableSpan {
|
|||
public void onClick(@NonNull final View view) {
|
||||
if (!InternalUrlsHandler.handleUrlDescriptionTimestamp(
|
||||
disposables, context, url)) {
|
||||
ShareUtils.openUrlInBrowser(context, url, false);
|
||||
ShareUtils.openUrlInApp(context, url);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package us.shandian.giga.ui.adapter;
|
||||
|
||||
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
|
||||
import static android.content.Intent.FLAG_GRANT_PREFIX_URI_PERMISSION;
|
||||
import static android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION;
|
||||
import static us.shandian.giga.get.DownloadMission.ERROR_CONNECT_HOST;
|
||||
|
|
@ -345,16 +344,7 @@ public class MissionAdapter extends Adapter<ViewHolder> implements Handler.Callb
|
|||
intent.setDataAndType(resolveShareableUri(mission), mimeType);
|
||||
intent.addFlags(FLAG_GRANT_READ_URI_PERMISSION);
|
||||
intent.addFlags(FLAG_GRANT_PREFIX_URI_PERMISSION);
|
||||
|
||||
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) {
|
||||
intent.addFlags(FLAG_ACTIVITY_NEW_TASK);
|
||||
}
|
||||
|
||||
if (intent.resolveActivity(mContext.getPackageManager()) != null) {
|
||||
ShareUtils.openIntentInApp(mContext, intent, false);
|
||||
} else {
|
||||
Toast.makeText(mContext, R.string.toast_no_player, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
ShareUtils.openIntentInApp(mContext, intent);
|
||||
}
|
||||
|
||||
private void shareFile(Mission mission) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue