android: images sharing
This commit is contained in:
parent
493d801aad
commit
5689be4579
7 changed files with 74 additions and 1 deletions
|
@ -19,11 +19,22 @@
|
|||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.Main">
|
||||
|
||||
<provider
|
||||
android:name=".FileProvider"
|
||||
android:authorities="mw.gri.android.fileprovider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/paths" />
|
||||
</provider>
|
||||
|
||||
<activity
|
||||
android:launchMode="singleTask"
|
||||
android:name=".MainActivity"
|
||||
android:configChanges="orientation|screenSize"
|
||||
android:exported="true">
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
package mw.gri.android;
|
||||
|
||||
public class FileProvider extends androidx.core.content.FileProvider {
|
||||
public FileProvider() {
|
||||
super(R.xml.paths);
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ import android.Manifest;
|
|||
import android.content.*;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Configuration;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Process;
|
||||
|
@ -17,6 +18,7 @@ import androidx.annotation.NonNull;
|
|||
import androidx.camera.core.*;
|
||||
import androidx.camera.lifecycle.ProcessCameraProvider;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.content.FileProvider;
|
||||
import androidx.core.graphics.Insets;
|
||||
import androidx.core.view.DisplayCutoutCompat;
|
||||
import androidx.core.view.ViewCompat;
|
||||
|
@ -24,6 +26,7 @@ import androidx.core.view.WindowInsetsCompat;
|
|||
import com.google.androidgamesdk.GameActivity;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
|
@ -62,6 +65,11 @@ public class MainActivity extends GameActivity {
|
|||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
// Clear cache on start.
|
||||
if (savedInstanceState == null) {
|
||||
Utils.deleteDirectoryContent(new File(getExternalCacheDir().getPath()), false);
|
||||
}
|
||||
|
||||
// Setup environment variables for native code.
|
||||
try {
|
||||
Os.setenv("HOME", getExternalFilesDir("").getPath(), true);
|
||||
|
@ -70,6 +78,7 @@ public class MainActivity extends GameActivity {
|
|||
} catch (ErrnoException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
super.onCreate(null);
|
||||
|
||||
// Register receiver to finish activity from the BackgroundService.
|
||||
|
@ -334,4 +343,14 @@ public class MainActivity extends GameActivity {
|
|||
|
||||
// Pass image from camera into native code.
|
||||
public native void onCameraImage(byte[] buff, int rotation);
|
||||
|
||||
// Called from native code to share image from provided path.
|
||||
public void shareImage(String path) {
|
||||
File file = new File(path);
|
||||
Uri uri = FileProvider.getUriForFile(this, "mw.gri.android.fileprovider", file);
|
||||
Intent intent = new Intent(Intent.ACTION_SEND);
|
||||
intent.putExtra(Intent.EXTRA_STREAM, uri);
|
||||
intent.setType("image/*");
|
||||
startActivity(Intent.createChooser(intent, "Share image"));
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@ import android.media.Image;
|
|||
import androidx.camera.core.ImageProxy;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class Utils {
|
||||
|
@ -135,4 +136,14 @@ public class Utils {
|
|||
rowStart += plane.getRowStride();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean deleteDirectoryContent(File directoryToBeDeleted, boolean deleteDirectory) {
|
||||
File[] allContents = directoryToBeDeleted.listFiles();
|
||||
if (allContents != null) {
|
||||
for (File file : allContents) {
|
||||
deleteDirectoryContent(file, true);
|
||||
}
|
||||
}
|
||||
return directoryToBeDeleted.delete();
|
||||
}
|
||||
}
|
||||
|
|
4
android/app/src/main/res/xml/paths.xml
Normal file
4
android/app/src/main/res/xml/paths.xml
Normal file
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<paths>
|
||||
<external-cache-path name="images" path="images/" />
|
||||
</paths>
|
|
@ -12,6 +12,11 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use std::env;
|
||||
use std::ffi::OsString;
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use std::path::PathBuf;
|
||||
use lazy_static::lazy_static;
|
||||
use std::sync::Arc;
|
||||
use parking_lot::RwLock;
|
||||
|
@ -116,6 +121,22 @@ impl PlatformCallbacks for Android {
|
|||
}
|
||||
|
||||
fn share_data(&self, name: String, data: Vec<u8>) -> Result<(), std::io::Error> {
|
||||
// Create file at cache dir.
|
||||
let default_cache = OsString::from(dirs::cache_dir().unwrap());
|
||||
let mut cache = PathBuf::from(env::var_os("XDG_CACHE_HOME").unwrap_or(default_cache));
|
||||
cache.push("images");
|
||||
std::fs::create_dir_all(cache.to_str().unwrap())?;
|
||||
cache.push(name);
|
||||
let mut image = File::create_new(cache.clone()).unwrap();
|
||||
image.write_all(data.as_slice()).unwrap();
|
||||
image.sync_all().unwrap();
|
||||
// Call share modal at system.
|
||||
let vm = unsafe { jni::JavaVM::from_raw(self.android_app.vm_as_ptr() as _) }.unwrap();
|
||||
let env = vm.attach_current_thread().unwrap();
|
||||
let arg_value = env.new_string(cache.to_str().unwrap()).unwrap();
|
||||
self.call_java_method("shareImage",
|
||||
"(Ljava/lang/String;)V",
|
||||
&[JValue::Object(&JObject::from(arg_value))]).unwrap();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ use std::thread;
|
|||
use egui::{SizeHint, TextureHandle, TextureOptions};
|
||||
use egui::load::SizedTexture;
|
||||
use egui_extras::image::load_svg_bytes_with_size;
|
||||
use image::{EncodableLayout, ExtendedColorType, ImageEncoder};
|
||||
use image::{ExtendedColorType, ImageEncoder};
|
||||
use image::codecs::png::{CompressionType, FilterType, PngEncoder};
|
||||
use qrcodegen::QrCode;
|
||||
use crate::gui::Colors;
|
||||
|
|
Loading…
Reference in a new issue