Skip to content

Commit 4bf02f5

Browse files
committed
getIntent
1 parent 15d02c7 commit 4bf02f5

File tree

2 files changed

+84
-16
lines changed

2 files changed

+84
-16
lines changed

src/intent.rs

Lines changed: 57 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,71 @@
11
use jni::{
2-
errors::Error,
2+
errors::Result,
33
objects::{JObject, JString, JValue},
44
JNIEnv,
55
};
66

7-
struct Inner<'env> {
8-
env: JNIEnv<'env>,
9-
object: JObject<'env>,
7+
#[must_use]
8+
pub struct Intent<'env> {
9+
pub(crate) env: JNIEnv<'env>,
10+
pub(crate) object: JObject<'env>,
11+
}
12+
13+
impl Intent<'_> {
14+
// TODO: Could also return a borrowed JavaStr so that the caller decides if they just want to read or also allocate
15+
pub fn action(&mut self) -> Result<String> {
16+
let action = self
17+
.env
18+
.call_method(&self.object, "getAction", "()Ljava/lang/String;", &[])?
19+
.l()?
20+
.into();
21+
22+
let action = self.env.get_string(&action)?;
23+
Ok(action.into())
24+
}
25+
26+
pub fn data_string(&mut self) -> Result<String> {
27+
let data_string = self
28+
.env
29+
.call_method(&self.object, "getDataString", "()Ljava/lang/String;", &[])?
30+
.l()?
31+
.into();
32+
let data_string = self.env.get_string(&data_string)?;
33+
Ok(data_string.into())
34+
}
35+
36+
/// <https://developer.android.com/reference/android/content/Intent#getStringExtra(java.lang.String)>
37+
pub fn string_extra(&mut self, name: &str) -> Result<String> {
38+
let name = self.env.new_string(name)?;
39+
40+
let extra = self
41+
.env
42+
.call_method(
43+
&self.object,
44+
"getStringExtra",
45+
"(Ljava/lang/String;)Ljava/lang/String;",
46+
&[JValue::Object(&name.into())],
47+
)?
48+
.l()?
49+
.into();
50+
let extra = self.env.get_string(&extra)?;
51+
Ok(extra.into())
52+
}
1053
}
1154

12-
/// A messaging object you can use to request an action from another android app component.
55+
/// A messaging object you can use to request an action from another Android app component.
1356
#[must_use]
14-
pub struct Intent<'env> {
15-
inner: Result<Inner<'env>, Error>,
57+
pub struct IntentBuilder<'env> {
58+
inner: Result<Intent<'env>>,
1659
}
1760

18-
impl<'env> Intent<'env> {
61+
impl<'env> IntentBuilder<'env> {
1962
pub fn from_object(env: JNIEnv<'env>, object: JObject<'env>) -> Self {
2063
Self {
21-
inner: Ok(Inner { env, object }),
64+
inner: Ok(Intent { env, object }),
2265
}
2366
}
2467

25-
fn from_fn(f: impl FnOnce() -> Result<Inner<'env>, Error>) -> Self {
68+
fn from_fn(f: impl FnOnce() -> Result<Intent<'env>>) -> Self {
2669
let inner = f();
2770
Self { inner }
2871
}
@@ -39,7 +82,7 @@ impl<'env> Intent<'env> {
3982
&[action_view.borrow()],
4083
)?;
4184

42-
Ok(Inner {
85+
Ok(Intent {
4386
env,
4487
object: intent,
4588
})
@@ -72,7 +115,7 @@ impl<'env> Intent<'env> {
72115
&[JValue::Object(&action_view), uri.borrow()],
73116
)?;
74117

75-
Ok(Inner {
118+
Ok(Intent {
76119
env,
77120
object: intent,
78121
})
@@ -190,7 +233,7 @@ impl<'env> Intent<'env> {
190233
})
191234
}
192235

193-
pub fn start_activity(self) -> Result<(), Error> {
236+
pub fn start_activity(self) -> Result<()> {
194237
let cx = ndk_context::android_context();
195238
let activity = unsafe { JObject::from_raw(cx.context() as jni::sys::jobject) };
196239

@@ -206,7 +249,7 @@ impl<'env> Intent<'env> {
206249
})
207250
}
208251

209-
fn and_then(mut self, f: impl FnOnce(Inner) -> Result<Inner, Error>) -> Self {
252+
fn and_then(mut self, f: impl FnOnce(Intent<'_>) -> Result<Intent<'_>>) -> Self {
210253
self.inner = self.inner.and_then(f);
211254
self
212255
}

src/lib.rs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,39 @@ mod extra;
55
pub use extra::Extra;
66

77
mod intent;
8-
pub use intent::Intent;
9-
use jni::{JNIEnv, JavaVM};
8+
pub use intent::{Intent, IntentBuilder};
9+
use jni::{objects::JObject, JNIEnv, JavaVM};
1010

1111
/// Run 'f' with the current [`JNIEnv`] from [`ndk_context`].
1212
pub fn with_current_env(f: impl FnOnce(&JNIEnv<'_>)) {
13+
// XXX: Pass AndroidActivity?
1314
let cx = ndk_context::android_context();
1415
let vm = unsafe { JavaVM::from_raw(cx.vm().cast()) }.unwrap();
1516
let env = vm.attach_current_thread().unwrap();
1617

18+
// TODO: Pass current activity?
1719
f(&env);
1820
}
21+
22+
/// Provides the intent from [`Activity#getIntent()`].
23+
///
24+
/// [`Activity#getIntent()`]: https://developer.android.com/reference/android/app/Activity#getIntent()
25+
pub fn with_current_intent<T>(f: impl FnOnce(Intent<'_>) -> T) -> std::io::Result<T> {
26+
let cx = ndk_context::android_context();
27+
let vm = unsafe { JavaVM::from_raw(cx.vm().cast()) }.unwrap();
28+
// let env = vm.attach_current_thread().unwrap();
29+
// TODO: Only so that our *temporary* Intent can own the `JNIEnv`, we need to change this!
30+
let mut env = vm.attach_current_thread_permanently().unwrap();
31+
let activity = unsafe { JObject::from_raw(cx.context() as jni::sys::jobject) };
32+
33+
let object = env
34+
.call_method(activity, "getIntent", "()Landroid/content/Intent;", &[])
35+
.unwrap()
36+
.l()
37+
.unwrap();
38+
39+
// TODO: Should borrow AttachGuard!
40+
let intent = Intent { env, object };
41+
42+
Ok(f(intent))
43+
}

0 commit comments

Comments
 (0)