Skip to content

Commit 8fbca64

Browse files
committed
getIntent
1 parent 4767c26 commit 8fbca64

File tree

2 files changed

+110
-26
lines changed

2 files changed

+110
-26
lines changed

src/intent.rs

Lines changed: 77 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,79 @@
1-
use jni::{
2-
errors::Error,
3-
objects::{JObject, JString},
4-
JNIEnv,
5-
};
6-
7-
struct Inner<'env> {
8-
env: JNIEnv<'env>,
9-
object: JObject<'env>,
10-
}
1+
use jni::{errors::Error, objects::JObject, JNIEnv};
112

12-
/// A messaging object you can use to request an action from another android app component.
133
#[must_use]
144
pub struct Intent<'env> {
15-
inner: Result<Inner<'env>, Error>,
5+
pub(crate) env: JNIEnv<'env>,
6+
pub(crate) object: JObject<'env>,
7+
}
8+
9+
impl Intent<'_> {
10+
// TODO: Could also return a borrowed JString
11+
pub fn action(&self) -> std::io::Result<String> {
12+
let action = self
13+
.env
14+
.call_method(self.object, "getAction", "()Ljava/lang/String;", &[])
15+
.map_err(std::io::Error::other)?
16+
.l()
17+
.map_err(std::io::Error::other)?;
18+
dbg!(action);
19+
let action = self
20+
.env
21+
.get_string(action.into())
22+
.map_err(std::io::Error::other)?;
23+
Ok(action.into())
24+
}
25+
26+
pub fn data_string(&self) -> std::io::Result<String> {
27+
let data_string = self
28+
.env
29+
.call_method(self.object, "getDataString", "()Ljava/lang/String;", &[])
30+
.map_err(std::io::Error::other)?
31+
.l()
32+
.map_err(std::io::Error::other)?;
33+
let data_string = self
34+
.env
35+
.get_string(data_string.into())
36+
.map_err(std::io::Error::other)?;
37+
Ok(data_string.into())
38+
}
39+
40+
/// <https://developer.android.com/reference/android/content/Intent#getStringExtra(java.lang.String)>
41+
pub fn string_extra(&self, name: &str) -> std::io::Result<String> {
42+
let name = self.env.new_string(name).map_err(std::io::Error::other)?;
43+
44+
let extra = self
45+
.env
46+
.call_method(
47+
self.object,
48+
"getStringExtra",
49+
"(Ljava/lang/String;)Ljava/lang/String;",
50+
&[name.into()],
51+
)
52+
.map_err(std::io::Error::other)?
53+
.l()
54+
.map_err(std::io::Error::other)?;
55+
let extra = self
56+
.env
57+
.get_string(extra.into())
58+
.map_err(std::io::Error::other)?;
59+
Ok(extra.into())
60+
}
61+
}
62+
63+
/// A messaging object you can use to request an action from another Android app component.
64+
#[must_use]
65+
pub struct IntentBuilder<'env> {
66+
inner: Result<Intent<'env>, Error>,
1667
}
1768

18-
impl<'env> Intent<'env> {
69+
impl<'env> IntentBuilder<'env> {
1970
pub fn from_object(env: JNIEnv<'env>, object: JObject<'env>) -> Self {
2071
Self {
21-
inner: Ok(Inner { env, object }),
72+
inner: Ok(Intent { env, object }),
2273
}
2374
}
2475

25-
fn from_fn(f: impl FnOnce() -> Result<Inner<'env>, Error>) -> Self {
76+
fn from_fn(f: impl FnOnce() -> Result<Intent<'env>, Error>) -> Self {
2677
let inner = f();
2778
Self { inner }
2879
}
@@ -33,10 +84,9 @@ impl<'env> Intent<'env> {
3384
let action_view =
3485
env.get_static_field(intent_class, action.as_ref(), "Ljava/lang/String;")?;
3586

36-
let intent =
37-
env.new_object(intent_class, "(Ljava/lang/String;)V", &[action_view.into()])?;
87+
let intent = env.new_object(intent_class, "(Ljava/lang/String;)V", &[action_view])?;
3888

39-
Ok(Inner {
89+
Ok(Intent {
4090
env,
4191
object: intent,
4292
})
@@ -51,7 +101,7 @@ impl<'env> Intent<'env> {
51101
uri_class,
52102
"parse",
53103
"(Ljava/lang/String;)Landroid/net/Uri;",
54-
&[JString::from(url_string).into()],
104+
&[url_string.into()],
55105
)?;
56106

57107
let intent_class = env.find_class("android/content/Intent")?;
@@ -61,10 +111,10 @@ impl<'env> Intent<'env> {
61111
let intent = env.new_object(
62112
intent_class,
63113
"(Ljava/lang/String;Landroid/net/Uri;)V",
64-
&[action_view.into(), uri.into()],
114+
&[action_view, uri],
65115
)?;
66116

67-
Ok(Inner {
117+
Ok(Intent {
68118
env,
69119
object: intent,
70120
})
@@ -80,7 +130,11 @@ impl<'env> Intent<'env> {
80130
/// intent.set_class_name("com.excample", "IntentTarget")
81131
/// # })
82132
/// ```
83-
pub fn set_class_name(self, package_name: impl AsRef<str>, class_name: impl AsRef<str>) -> Self {
133+
pub fn set_class_name(
134+
self,
135+
package_name: impl AsRef<str>,
136+
class_name: impl AsRef<str>,
137+
) -> Self {
84138
self.and_then(|inner| {
85139
let package_name = inner.env.new_string(package_name)?;
86140
let class_name = inner.env.new_string(class_name)?;
@@ -195,7 +249,7 @@ impl<'env> Intent<'env> {
195249
})
196250
}
197251

198-
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, Error>) -> Self {
199253
self.inner = self.inner.and_then(f);
200254
self
201255
}

src/lib.rs

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,44 @@ 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

17-
f(env.clone());
18+
// TODO: Pass current activity?
19+
20+
f(*env);
21+
}
22+
23+
/// Provides the intent from [`Activity#getIntent()`].
24+
///
25+
/// [`Activity#getIntent()`]: https://developer.android.com/reference/android/app/Activity#getIntent()
26+
pub fn with_current_intent<T>(f: impl FnOnce(Intent<'_>) -> T) -> std::io::Result<T> {
27+
let cx = ndk_context::android_context();
28+
let vm = unsafe { JavaVM::from_raw(cx.vm().cast()) }.unwrap();
29+
let env = vm.attach_current_thread().unwrap();
30+
let activity = unsafe { JObject::from_raw(cx.context() as jni::sys::jobject) };
31+
32+
let object = env
33+
.call_method(
34+
activity,
35+
"getIntent",
36+
"()Landroid/content/Intent;",
37+
// &[JValue::from(&j_url)],
38+
&[],
39+
)
40+
.unwrap()
41+
.l()
42+
.unwrap();
43+
// dbg!(intent);
44+
45+
let intent = Intent { env: *env, object };
46+
47+
Ok(f(intent))
1848
}

0 commit comments

Comments
 (0)