Skip to content

Upgrade jni to 0.21 #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ license = "MIT"
description = "Android intent utilities"

[dependencies]
jni = "0.20.0"
jni = "0.21"
ndk-context = "0.1.1"

[workspace]
Expand Down
2 changes: 1 addition & 1 deletion example/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ crate-type = ["cdylib"]
[dependencies]
android-activity = { version = "0.4.0", features = ["native-activity"] }
android-intent.path = "../"
jni = "0.20.0"
jni = "0.21"
ndk-context = "0.1.1"

[package.metadata.android.sdk]
Expand Down
75 changes: 45 additions & 30 deletions src/intent.rs
Original file line number Diff line number Diff line change
@@ -1,35 +1,43 @@
use jni::{errors::Error, objects::JObject, JNIEnv};

struct Inner<'env> {
env: JNIEnv<'env>,
use jni::{
errors::Error,
objects::{JObject, JString, JValue},
JNIEnv,
};

struct Inner<'vm, 'env> {
env: &'vm mut JNIEnv<'env>,
object: JObject<'env>,
}

/// A messaging object you can use to request an action from another android app component.
#[must_use]
pub struct Intent<'env> {
inner: Result<Inner<'env>, Error>,
pub struct Intent<'vm, 'env> {
inner: Result<Inner<'vm, 'env>, Error>,
}

impl<'env> Intent<'env> {
pub fn from_object(env: JNIEnv<'env>, object: JObject<'env>) -> Self {
impl<'vm, 'env> Intent<'vm, 'env> {
pub fn from_object(env: &'vm mut JNIEnv<'env>, object: JObject<'env>) -> Self {
Self {
inner: Ok(Inner { env, object }),
}
}

fn from_fn(f: impl FnOnce() -> Result<Inner<'env>, Error>) -> Self {
fn from_fn(f: impl FnOnce() -> Result<Inner<'vm, 'env>, Error>) -> Self {
let inner = f();
Self { inner }
}

pub fn new(env: JNIEnv<'env>, action: impl AsRef<str>) -> Self {
pub fn new(env: &'vm mut JNIEnv<'env>, action: impl AsRef<str>) -> Self {
Self::from_fn(|| {
let intent_class = env.find_class("android/content/Intent")?;
let action_view =
env.get_static_field(intent_class, action.as_ref(), "Ljava/lang/String;")?;
env.get_static_field(&intent_class, action.as_ref(), "Ljava/lang/String;")?;

let intent = env.new_object(intent_class, "(Ljava/lang/String;)V", &[action_view])?;
let intent = env.new_object(
&intent_class,
"(Ljava/lang/String;)V",
&[action_view.borrow()],
)?;

Ok(Inner {
env,
Expand All @@ -38,25 +46,30 @@ impl<'env> Intent<'env> {
})
}

pub fn new_with_uri(env: JNIEnv<'env>, action: impl AsRef<str>, uri: impl AsRef<str>) -> Self {
pub fn new_with_uri(
env: &'env mut JNIEnv<'env>,
action: impl AsRef<str>,
uri: impl AsRef<str>,
) -> Self {
Self::from_fn(|| {
let url_string = env.new_string(uri)?;
let uri_class = env.find_class("android/net/Uri")?;
let uri = env.call_static_method(
uri_class,
"parse",
"(Ljava/lang/String;)Landroid/net/Uri;",
&[url_string.into()],
&[JValue::Object(&url_string)],
)?;

let intent_class = env.find_class("android/content/Intent")?;
let action_view =
env.get_static_field(intent_class, action.as_ref(), "Ljava/lang/String;")?;
let action_view = env
.get_static_field(&intent_class, action.as_ref(), "Ljava/lang/String;")?
.l()?;

let intent = env.new_object(
intent_class,
&intent_class,
"(Ljava/lang/String;Landroid/net/Uri;)V",
&[action_view, uri],
&[JValue::Object(&action_view), uri.borrow()],
)?;

Ok(Inner {
Expand Down Expand Up @@ -85,10 +98,10 @@ impl<'env> Intent<'env> {
let class_name = inner.env.new_string(class_name)?;

inner.env.call_method(
inner.object,
&inner.object,
"setClassName",
"(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent;",
&[package_name.into(), class_name.into()],
&[JValue::Object(&package_name), JValue::Object(&class_name)],
)?;

Ok(inner)
Expand All @@ -110,10 +123,10 @@ impl<'env> Intent<'env> {
let value = inner.env.new_string(value)?;

inner.env.call_method(
inner.object,
&inner.object,
"putExtra",
"(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent;",
&[key.into(), value.into()],
&[JValue::Object(&key), JValue::Object(&value)],
)?;

Ok(inner)
Expand All @@ -136,18 +149,17 @@ impl<'env> Intent<'env> {
pub fn into_chooser_with_title(self, title: Option<impl AsRef<str>>) -> Self {
self.and_then(|mut inner| {
let title_value = if let Some(title) = title {
let s = inner.env.new_string(title)?;
s.into()
inner.env.new_string(title)?
} else {
JObject::null().into()
JString::default()
};

let intent_class = inner.env.find_class("android/content/Intent")?;
let intent = inner.env.call_static_method(
intent_class,
"createChooser",
"(Landroid/content/Intent;Ljava/lang/CharSequence;)Landroid/content/Intent;",
&[inner.object.into(), title_value],
&[JValue::Object(&inner.object), JValue::Object(&title_value)],
)?;

inner.object = intent.try_into()?;
Expand All @@ -169,10 +181,10 @@ impl<'env> Intent<'env> {
let jstring = inner.env.new_string(type_name)?;

inner.env.call_method(
inner.object,
&inner.object,
"setType",
"(Ljava/lang/String;)Landroid/content/Intent;",
&[jstring.into()],
&[JValue::Object(&jstring)],
)?;

Ok(inner)
Expand All @@ -188,14 +200,17 @@ impl<'env> Intent<'env> {
activity,
"startActivity",
"(Landroid/content/Intent;)V",
&[inner.object.into()],
&[JValue::Object(&inner.object)],
)?;

Ok(())
})
}

fn and_then(mut self, f: impl FnOnce(Inner) -> Result<Inner, Error>) -> Self {
fn and_then(
mut self,
f: impl FnOnce(Inner<'vm, 'env>) -> Result<Inner<'vm, 'env>, Error>,
) -> Self {
self.inner = self.inner.and_then(f);
self
}
Expand Down
6 changes: 3 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ pub use intent::Intent;
use jni::{JNIEnv, JavaVM};

/// Run 'f' with the current [`JNIEnv`] from [`ndk_context`].
pub fn with_current_env(f: impl FnOnce(JNIEnv)) {
pub fn with_current_env(f: impl FnOnce(&mut JNIEnv<'_>)) {
let cx = ndk_context::android_context();
let vm = unsafe { JavaVM::from_raw(cx.vm().cast()) }.unwrap();
let env = vm.attach_current_thread().unwrap();
let mut env = vm.attach_current_thread().unwrap();

f(*env);
f(&mut env);
}