added storing of scope and sharing

This commit is contained in:
Ahmet Inan 2024-04-27 14:26:59 +02:00
parent d6ee2a3a43
commit fff69bd4fe
5 changed files with 133 additions and 0 deletions

View file

@ -2,7 +2,18 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<queries>
<intent>
<action android:name="android.intent.action.SEND" />
<data android:mimeType="image/png" />
</intent>
</queries>
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="28" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"

View file

@ -7,7 +7,10 @@ Copyright 2024 Ahmet Inan <xdsopl@gmail.com>
package xdsopl.robot36;
import android.Manifest;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
@ -15,25 +18,40 @@ import android.graphics.Bitmap;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.ParcelFileDescriptor;
import android.provider.MediaStore;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ImageView;
import android.widget.Toast;
import androidx.activity.EdgeToEdge;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.appcompat.widget.ShareActionProvider;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.Insets;
import androidx.core.view.MenuItemCompat;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Locale;
public class MainActivity extends AppCompatActivity {
@ -336,6 +354,8 @@ public class MainActivity extends AppCompatActivity {
} else {
initAudioRecord();
}
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P && ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (!permissions.isEmpty())
ActivityCompat.requestPermissions(this, permissions.toArray(new String[0]), permissionID);
}
@ -361,6 +381,10 @@ public class MainActivity extends AppCompatActivity {
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_store_scope) {
storeBitmap(scopeBitmap);
return true;
}
if (id == R.id.action_set_record_rate_8000) {
setRecordRate(8000);
return true;
@ -494,6 +518,81 @@ public class MainActivity extends AppCompatActivity {
builder.show();
}
void storeBitmap(Bitmap bitmap) {
Date date = new Date();
String name = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(date);
name += ".png";
String title = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US).format(date);
ContentValues values = new ContentValues();
File dir;
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
if (!dir.exists() && !dir.mkdirs()) {
showToast(R.string.creating_picture_directory_failed);
return;
}
File file;
try {
file = new File(dir, name);
FileOutputStream stream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
stream.close();
} catch (IOException e) {
showToast(R.string.creating_picture_file_failed);
return;
}
values.put(MediaStore.Images.ImageColumns.DATA, file.toString());
} else {
values.put(MediaStore.Images.Media.DISPLAY_NAME, name);
values.put(MediaStore.Images.Media.RELATIVE_PATH, "Pictures/");
values.put(MediaStore.Images.Media.IS_PENDING, 1);
}
values.put(MediaStore.Images.ImageColumns.TITLE, title);
values.put(MediaStore.Images.ImageColumns.MIME_TYPE, "image/png");
ContentResolver resolver = getContentResolver();
Uri uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
if (uri == null) {
showToast(R.string.storing_picture_failed);
return;
}
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
try {
ParcelFileDescriptor descriptor = getContentResolver().openFileDescriptor(uri, "w");
if (descriptor == null) {
showToast(R.string.storing_picture_failed);
return;
}
FileOutputStream stream = new FileOutputStream(descriptor.getFileDescriptor());
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
stream.close();
descriptor.close();
} catch (IOException e) {
showToast(R.string.storing_picture_failed);
return;
}
values.clear();
values.put(MediaStore.Images.Media.IS_PENDING, 0);
resolver.update(uri, values, null, null);
}
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_STREAM, uri);
intent.setType("image/png");
ShareActionProvider share = (ShareActionProvider) MenuItemCompat.getActionProvider(menu.findItem(R.id.menu_item_share));
if (share != null)
share.setShareIntent(intent);
showToast(name);
}
private void showToast(String message) {
Toast toast = Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL, 0, 0);
toast.show();
}
private void showToast(int id) {
showToast(getString(id));
}
@Override
protected void onResume() {
startListening();

View file

@ -0,0 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
<path android:fillColor="@android:color/white" android:pathData="M19,12v7L5,19v-7L3,12v7c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2v-7h-2zM13,12.67l2.59,-2.58L17,11.5l-5,5 -5,-5 1.41,-1.41L11,12.67L11,3h2z"/>
</vector>

View file

@ -1,7 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context="xdsopl.robot36.MainActivity">
<item
android:id="@+id/action_store_scope"
android:title="@string/store_scope"
android:icon="@drawable/baseline_save_alt_24"
app:iconTint="@color/tint"
app:showAsAction="always"
tools:ignore="AlwaysShowAction" />
<item
android:id="@+id/menu_item_share"
android:title="@string/action_share"
app:actionProviderClass="androidx.appcompat.widget.ShareActionProvider"
app:showAsAction="always" />
<item android:title="@string/audio_settings">
<menu>
<item android:title="@string/sample_rate">

View file

@ -1,5 +1,7 @@
<resources>
<string name="app_name">Robot36</string>
<string name="action_share">Share</string>
<string name="store_scope">Store Scope</string>
<string name="listening">Listening</string>
<string name="audio_settings">Audio Settings</string>
<string name="sample_rate">Sample Rate</string>
@ -24,6 +26,9 @@
<string name="audio_setup_failed">Audio setup failed</string>
<string name="audio_permission_denied">Audio permission denied</string>
<string name="audio_recording_error">Audio recording error</string>
<string name="creating_picture_directory_failed">Creating picture directory failed</string>
<string name="creating_picture_file_failed">Creating picture file failed</string>
<string name="storing_picture_failed">Storing picture failed</string>
<string name="scope_description">Decoded SSTV picture</string>
<string name="freq_plot_description">Frequency plot</string>
<string name="peak_meter_description">Peak audio signal level</string>