mirror of
https://github.com/venera-app/venera.git
synced 2025-09-27 07:47:24 +00:00
[Android] Support opening search page with shared text. Close #261
This commit is contained in:
@@ -47,6 +47,11 @@
|
|||||||
<category android:name="android.intent.category.BROWSABLE" />
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
<data android:scheme="https" android:host="exhentai.org" android:pathPrefix="/g" />
|
<data android:scheme="https" android:host="exhentai.org" android:pathPrefix="/g" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
<intent-filter android:label="@string/share_text">
|
||||||
|
<action android:name="android.intent.action.SEND" />
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
<data android:mimeType="text/plain" />
|
||||||
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<!-- Don't delete the meta-data below.
|
<!-- Don't delete the meta-data below.
|
||||||
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
||||||
|
@@ -7,6 +7,7 @@ import android.content.Intent
|
|||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
import android.os.Bundle
|
||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
@@ -40,6 +41,41 @@ class MainActivity : FlutterFragmentActivity() {
|
|||||||
|
|
||||||
private val nextLocalRequestCode = AtomicInteger()
|
private val nextLocalRequestCode = AtomicInteger()
|
||||||
|
|
||||||
|
private val sharedTexts = ArrayList<String>()
|
||||||
|
|
||||||
|
private var textShareHandler: ((String) -> Unit)? = null
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
if (intent?.action == Intent.ACTION_SEND) {
|
||||||
|
if (intent.type == "text/plain") {
|
||||||
|
val text = intent.getStringExtra(Intent.EXTRA_TEXT)
|
||||||
|
if (text != null)
|
||||||
|
handleSharedText(text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onNewIntent(intent: Intent) {
|
||||||
|
super.onNewIntent(intent)
|
||||||
|
if (intent.action == Intent.ACTION_SEND) {
|
||||||
|
if (intent.type == "text/plain") {
|
||||||
|
val text = intent.getStringExtra(Intent.EXTRA_TEXT)
|
||||||
|
if (text != null)
|
||||||
|
handleSharedText(text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleSharedText(text: String) {
|
||||||
|
if (textShareHandler != null) {
|
||||||
|
textShareHandler?.invoke(text)
|
||||||
|
} else {
|
||||||
|
sharedTexts.add(text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun <I, O> startContractForResult(
|
private fun <I, O> startContractForResult(
|
||||||
contract: ActivityResultContract<I, O>,
|
contract: ActivityResultContract<I, O>,
|
||||||
input: I,
|
input: I,
|
||||||
@@ -134,6 +170,26 @@ class MainActivity : FlutterFragmentActivity() {
|
|||||||
val mimeType = req.arguments<String>()
|
val mimeType = req.arguments<String>()
|
||||||
openFile(res, mimeType!!)
|
openFile(res, mimeType!!)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val shareTextChannel = EventChannel(flutterEngine.dartExecutor.binaryMessenger, "venera/text_share")
|
||||||
|
shareTextChannel.setStreamHandler(
|
||||||
|
object : EventChannel.StreamHandler {
|
||||||
|
override fun onListen(arguments: Any?, events: EventChannel.EventSink) {
|
||||||
|
textShareHandler = {text ->
|
||||||
|
events.success(text)
|
||||||
|
}
|
||||||
|
if (sharedTexts.isNotEmpty()) {
|
||||||
|
for (text in sharedTexts) {
|
||||||
|
events.success(text)
|
||||||
|
}
|
||||||
|
sharedTexts.clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCancel(arguments: Any?) {
|
||||||
|
textShareHandler = null
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getProxy(): String {
|
private fun getProxy(): String {
|
||||||
|
4
android/app/src/main/res/values-zh-rCN/strings.xml
Normal file
4
android/app/src/main/res/values-zh-rCN/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="share_text">搜索</string>
|
||||||
|
</resources>
|
4
android/app/src/main/res/values-zh/strings.xml
Normal file
4
android/app/src/main/res/values-zh/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="share_text">搜尋</string>
|
||||||
|
</resources>
|
4
android/app/src/main/res/values/strings.xml
Normal file
4
android/app/src/main/res/values/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="share_text">Search</string>
|
||||||
|
</resources>
|
@@ -11,6 +11,7 @@ import 'package:venera/pages/comic_source_page.dart';
|
|||||||
import 'package:venera/pages/follow_updates_page.dart';
|
import 'package:venera/pages/follow_updates_page.dart';
|
||||||
import 'package:venera/pages/settings/settings_page.dart';
|
import 'package:venera/pages/settings/settings_page.dart';
|
||||||
import 'package:venera/utils/app_links.dart';
|
import 'package:venera/utils/app_links.dart';
|
||||||
|
import 'package:venera/utils/handle_text_share.dart';
|
||||||
import 'package:venera/utils/tags_translation.dart';
|
import 'package:venera/utils/tags_translation.dart';
|
||||||
import 'package:venera/utils/translations.dart';
|
import 'package:venera/utils/translations.dart';
|
||||||
import 'foundation/appdata.dart';
|
import 'foundation/appdata.dart';
|
||||||
@@ -45,6 +46,7 @@ Future<void> init() async {
|
|||||||
_checkOldConfigs();
|
_checkOldConfigs();
|
||||||
if (App.isAndroid) {
|
if (App.isAndroid) {
|
||||||
handleLinks();
|
handleLinks();
|
||||||
|
handleTextShare();
|
||||||
}
|
}
|
||||||
FlutterError.onError = (details) {
|
FlutterError.onError = (details) {
|
||||||
Log.error("Unhandled Exception", "${details.exception}\n${details.stack}");
|
Log.error("Unhandled Exception", "${details.exception}\n${details.stack}");
|
||||||
|
22
lib/utils/handle_text_share.dart
Normal file
22
lib/utils/handle_text_share.dart
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:venera/foundation/app.dart';
|
||||||
|
import 'package:venera/pages/aggregated_search_page.dart';
|
||||||
|
|
||||||
|
bool _isHandling = false;
|
||||||
|
|
||||||
|
/// Handle text share event.
|
||||||
|
/// App will navigate to [AggregatedSearchPage] with the shared text as keyword.
|
||||||
|
void handleTextShare() async {
|
||||||
|
if (_isHandling) return;
|
||||||
|
_isHandling = true;
|
||||||
|
|
||||||
|
var channel = EventChannel('venera/text_share');
|
||||||
|
await for (var event in channel.receiveBroadcastStream()) {
|
||||||
|
if (App.mainNavigatorKey == null) {
|
||||||
|
await Future.delayed(const Duration(milliseconds: 200));
|
||||||
|
}
|
||||||
|
if (event is String) {
|
||||||
|
App.rootContext.to(() => AggregatedSearchPage(keyword: event));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user