Skip to content

Commit

Permalink
Extended custom URL scheme to include service selection
Browse files Browse the repository at this point in the history
- Implemented the abilImplemented the ability for third-party apps to initiate a search in NewPipe on a specific service by using the custom URL scheme `newpipe://search?service=SERVICE_NAME&q=YOUR_QUERY`.
- Added intent-filter to RouterActivity to handle the custom URL scheme.
- Enhanced RouterActivity to parse the incoming service parameter, retrieve the corresponding service ID, and start MainActivity with the specified service and search query.
- Added error handling for invalid service names: displays an error message to the user if the service name is invalid.
- Tested the implementation using ADB commands to send an intent with the custom URI.
Fixes: Expose search API with url #3475

Add new tag to customize urls

add logic of handling custom search intents in onCreate method

add comments to helping review

add a new method to get the service by name

improve the RouterActivity to handle the service name

improve the RouterActivity
  • Loading branch information
jiahengguo123 committed Nov 3, 2024
1 parent 90404a2 commit c934c25
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 2 deletions.
8 changes: 8 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,14 @@
<data android:sspPattern="bandcamp.com/?show=*" />
</intent-filter>

<!-- customized search URL filter -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="newpipe" android:host="search" />
</intent-filter>

</activity>
<service
android:name=".RouterActivity$FetcherService"
Expand Down
50 changes: 50 additions & 0 deletions app/src/main/java/org/schabi/newpipe/RouterActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
Expand Down Expand Up @@ -87,6 +88,7 @@
import org.schabi.newpipe.util.Localization;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.PermissionHelper;
import org.schabi.newpipe.util.ServiceHelper;
import org.schabi.newpipe.util.ThemeHelper;
import org.schabi.newpipe.util.external_communication.ShareUtils;
import org.schabi.newpipe.util.urlfinder.UrlFinder;
Expand Down Expand Up @@ -127,6 +129,12 @@ public class RouterActivity extends AppCompatActivity {
private AlertDialog alertDialogChoice = null;
private FragmentManager.FragmentLifecycleCallbacks dismissListener = null;

/**
* Initializes the activity based on the incoming intent. This activity acts as a router
* to direct the user to different parts of the app based on the URL or action specified
* in the intent. It handles special URLs like 'newpipe://search?q=query' to trigger
* search directly or standard URLs to open specific videos, playlists, or channels.
*/
@Override
protected void onCreate(final Bundle savedInstanceState) {
ThemeHelper.setDayNightMode(this);
Expand All @@ -153,7 +161,49 @@ protected void onCreate(final Bundle savedInstanceState) {
getWindow().setAttributes(params);

super.onCreate(savedInstanceState);

Bridge.restoreInstanceState(this, savedInstanceState);
// Restoring state with Icepick for handling screen rotations more efficiently
Icepick.restoreInstanceState(this, savedInstanceState);

final Intent actionIntent = getIntent();
final Uri data = actionIntent.getData();
if (data != null) {
final String scheme = data.getScheme();
final String host = data.getHost();
if ("newpipe".equals(scheme) && "search".equals(host)) {
final String query = data.getQueryParameter("q");
final String serviceName = data.getQueryParameter("service");
// Default to use current service
int serviceId = ServiceHelper.getSelectedServiceId(this);

if (serviceName != null) {
// Base on the service name to get correspond Id
try {
serviceId = ServiceHelper.getServiceIdByName(serviceName);
} catch (final IllegalArgumentException e) {
// If service name is invalid, show the Error message
Toast.makeText(this, "Invalid service name", Toast.LENGTH_SHORT).show();
finish();
return;
}
}

if (query != null) {
// Enable the search function
final Intent searchIntent = new Intent(this, MainActivity.class);
searchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
searchIntent.putExtra(Constants.KEY_OPEN_SEARCH, true);
searchIntent.putExtra(Constants.KEY_SERVICE_ID, serviceId);
searchIntent.putExtra(Constants.KEY_SEARCH_STRING, query);
startActivity(searchIntent);
currentUrl = null;
finish();
return;
}
}
}

// FragmentManager will take care to recreate (Playlist|Download)Dialog when screen rotates
// We used to .setOnDismissListener(dialog -> finish()); when creating these DialogFragments
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,17 @@ private void generateDataFrom(final Frameset frameset, final UUID updateRequestI

// Get the bounds where the frame is found
final int[] bounds = frameset.getFrameBoundsAt(currentPosMs);
generatedDataForUrl.put(currentPosMs,
createBitmapSupplier(srcBitMap, bounds, frameset));
generatedDataForUrl.put(currentPosMs, () -> {
// It can happen, that the original bitmap could not be downloaded
// In such a case - we don't want a NullPointer - simply return null
if (srcBitMap == null) {
return null;
}

// Cut out the corresponding bitmap form the "srcBitMap"
return Bitmap.createBitmap(srcBitMap, bounds[1], bounds[2],
frameset.getFrameWidth(), frameset.getFrameHeight());
});

currentPosMs += frameset.getDurationPerFrame();
pos++;
Expand Down
10 changes: 10 additions & 0 deletions app/src/main/java/org/schabi/newpipe/util/ServiceHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,16 @@ public static int getSelectedServiceId(final Context context) {
.getServiceId();
}

public static int getServiceIdByName(final String serviceName) throws IllegalArgumentException {
for (final StreamingService s : NewPipe.getServices()) {
if (s.getServiceInfo().getName().equalsIgnoreCase(serviceName)) {
return s.getServiceId();
}
}
throw new IllegalArgumentException("Invalid service name");
}


@Nullable
public static StreamingService getSelectedService(final Context context) {
final String serviceName = PreferenceManager.getDefaultSharedPreferences(context)
Expand Down

0 comments on commit c934c25

Please sign in to comment.