forked from usefulsensors/moonshine
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: init Android setup & main activity (cpws)
* **Build Configuration** - Add `android/build.gradle` for project-level build configuration - Add `android/app/build.gradle` for app module build configuration * **Main Activity and Layout** - Add `MainActivity.java` for handling audio and video file selection and transcription - Add `activity_main.xml` for main activity layout - Add `AndroidManifest.xml` for app configuration * **Resources** - Add `strings.xml` for string resources - Add `styles.xml` for app theme * **Transcription Service and Utilities** - Add `TranscriptionService.java` for handling transcription tasks - Add `AudioUtils.java` and `VideoUtils.java` for audio and video file handling - Add `TranscriptionUtils.java` for transcription conversion and saving * **File Picker Fragment** - Add `FilePickerFragment.java` for selecting audio/video files - Add `fragment_file_picker.xml` for file picker fragment layout * **Real-Time ASR Fragment** - Add `RealTimeASRFragment.java` for real-time transcription - Add `fragment_real_time_asr.xml` for real-time ASR fragment layout * **Transcription Display** - Add `TranscriptionAdapter.java` for displaying transcription items - Add `item_transcription.xml` for transcription item layout * **Documentation** - Update `README.md` with instructions on building and running the Android app * **CI Configuration** - Add `.github/workflows/android.yml` for GitHub Actions workflow to generate APK on every commit
- Loading branch information
1 parent
021e394
commit 575ed6e
Showing
19 changed files
with
812 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
name: Android CI | ||
|
||
on: | ||
push: | ||
branches: | ||
- main | ||
pull_request: | ||
branches: | ||
- main | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- name: Checkout repository | ||
uses: actions/checkout@v2 | ||
|
||
- name: Set up JDK 11 | ||
uses: actions/setup-java@v2 | ||
with: | ||
java-version: 11 | ||
|
||
- name: Build with Gradle | ||
run: ./gradlew build | ||
|
||
- name: Upload APK | ||
uses: actions/upload-artifact@v2 | ||
with: | ||
name: app-release.apk | ||
path: android/app/build/outputs/apk/release/app-release.apk |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
apply plugin: 'com.android.application' | ||
|
||
android { | ||
compileSdkVersion 30 | ||
defaultConfig { | ||
applicationId "com.usefulsensors.moonshine" | ||
minSdkVersion 21 | ||
targetSdkVersion 30 | ||
versionCode 1 | ||
versionName "1.0" | ||
} | ||
buildTypes { | ||
release { | ||
minifyEnabled false | ||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' | ||
} | ||
} | ||
} | ||
|
||
dependencies { | ||
implementation fileTree(dir: 'libs', include: ['*.jar']) | ||
implementation 'androidx.appcompat:appcompat:1.2.0' | ||
implementation 'androidx.core:core-ktx:1.3.2' | ||
implementation 'com.google.android.material:material:1.3.0' | ||
implementation 'androidx.constraintlayout:constraintlayout:2.0.4' | ||
testImplementation 'junit:junit:4.13.1' | ||
androidTestImplementation 'androidx.test.ext:junit:1.1.2' | ||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||
package="com.usefulsensors.moonshine"> | ||
|
||
<application | ||
android:allowBackup="true" | ||
android:icon="@mipmap/ic_launcher" | ||
android:label="@string/app_name" | ||
android:roundIcon="@mipmap/ic_launcher_round" | ||
android:supportsRtl="true" | ||
android:theme="@style/AppTheme"> | ||
<activity android:name=".MainActivity"> | ||
<intent-filter> | ||
<action android:name="android.intent.action.MAIN" /> | ||
<category android:name="android.intent.category.LAUNCHER" /> | ||
</intent-filter> | ||
</activity> | ||
<service android:name=".TranscriptionService" /> | ||
</application> | ||
|
||
</manifest> |
38 changes: 38 additions & 0 deletions
38
android/app/src/main/java/com/usefulsensors/moonshine/AudioUtils.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package com.usefulsensors.moonshine; | ||
|
||
import android.content.Context; | ||
import android.net.Uri; | ||
import android.util.Log; | ||
|
||
import java.io.File; | ||
import java.io.FileOutputStream; | ||
import java.io.IOException; | ||
import java.io.InputStream; | ||
|
||
public class AudioUtils { | ||
|
||
private static final String TAG = "AudioUtils"; | ||
|
||
public static File getFileFromUri(Context context, Uri uri) throws IOException { | ||
InputStream inputStream = context.getContentResolver().openInputStream(uri); | ||
File tempFile = File.createTempFile("audio", null, context.getCacheDir()); | ||
FileOutputStream outputStream = new FileOutputStream(tempFile); | ||
|
||
byte[] buffer = new byte[1024]; | ||
int length; | ||
while ((length = inputStream.read(buffer)) > 0) { | ||
outputStream.write(buffer, 0, length); | ||
} | ||
|
||
outputStream.close(); | ||
inputStream.close(); | ||
|
||
return tempFile; | ||
} | ||
|
||
public static String transcribeAudio(File audioFile) { | ||
// Placeholder for actual transcription logic | ||
Log.i(TAG, "Transcribing audio file: " + audioFile.getAbsolutePath()); | ||
return "Transcription result"; | ||
} | ||
} |
87 changes: 87 additions & 0 deletions
87
android/app/src/main/java/com/usefulsensors/moonshine/FilePickerFragment.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
package com.usefulsensors.moonshine; | ||
|
||
import android.content.Intent; | ||
import android.net.Uri; | ||
import android.os.Bundle; | ||
import android.provider.MediaStore; | ||
import android.view.LayoutInflater; | ||
import android.view.View; | ||
import android.view.ViewGroup; | ||
import android.widget.Button; | ||
import android.widget.TextView; | ||
import androidx.annotation.NonNull; | ||
import androidx.annotation.Nullable; | ||
import androidx.fragment.app.Fragment; | ||
|
||
public class FilePickerFragment extends Fragment { | ||
|
||
private static final int REQUEST_CODE_PICK_AUDIO = 1; | ||
private static final int REQUEST_CODE_PICK_VIDEO = 2; | ||
|
||
private TextView statusTextView; | ||
|
||
@Nullable | ||
@Override | ||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { | ||
View view = inflater.inflate(R.layout.fragment_file_picker, container, false); | ||
|
||
statusTextView = view.findViewById(R.id.statusTextView); | ||
|
||
Button pickAudioButton = view.findViewById(R.id.pickAudioButton); | ||
pickAudioButton.setOnClickListener(new View.OnClickListener() { | ||
@Override | ||
public void onClick(View v) { | ||
pickAudioFile(); | ||
} | ||
}); | ||
|
||
Button pickVideoButton = view.findViewById(R.id.pickVideoButton); | ||
pickVideoButton.setOnClickListener(new View.OnClickListener() { | ||
@Override | ||
public void onClick(View v) { | ||
pickVideoFile(); | ||
} | ||
}); | ||
|
||
return view; | ||
} | ||
|
||
private void pickAudioFile() { | ||
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI); | ||
startActivityForResult(intent, REQUEST_CODE_PICK_AUDIO); | ||
} | ||
|
||
private void pickVideoFile() { | ||
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Video.Media.EXTERNAL_CONTENT_URI); | ||
startActivityForResult(intent, REQUEST_CODE_PICK_VIDEO); | ||
} | ||
|
||
@Override | ||
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { | ||
super.onActivityResult(requestCode, resultCode, data); | ||
if (resultCode == getActivity().RESULT_OK && data != null) { | ||
Uri uri = data.getData(); | ||
if (requestCode == REQUEST_CODE_PICK_AUDIO) { | ||
transcribeAudio(uri); | ||
} else if (requestCode == REQUEST_CODE_PICK_VIDEO) { | ||
transcribeVideo(uri); | ||
} | ||
} | ||
} | ||
|
||
private void transcribeAudio(Uri uri) { | ||
Intent intent = new Intent(getActivity(), TranscriptionService.class); | ||
intent.setData(uri); | ||
intent.putExtra("type", "audio"); | ||
getActivity().startService(intent); | ||
statusTextView.setText("Transcribing audio..."); | ||
} | ||
|
||
private void transcribeVideo(Uri uri) { | ||
Intent intent = new Intent(getActivity(), TranscriptionService.class); | ||
intent.setData(uri); | ||
intent.putExtra("type", "video"); | ||
getActivity().startService(intent); | ||
statusTextView.setText("Transcribing video..."); | ||
} | ||
} |
112 changes: 112 additions & 0 deletions
112
android/app/src/main/java/com/usefulsensors/moonshine/MainActivity.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
package com.usefulsensors.moonshine; | ||
|
||
import android.Manifest; | ||
import android.content.Intent; | ||
import android.content.pm.PackageManager; | ||
import android.net.Uri; | ||
import android.os.Bundle; | ||
import android.provider.MediaStore; | ||
import android.view.View; | ||
import android.widget.Button; | ||
import android.widget.TextView; | ||
import androidx.annotation.NonNull; | ||
import androidx.appcompat.app.AppCompatActivity; | ||
import androidx.core.app.ActivityCompat; | ||
import androidx.core.content.ContextCompat; | ||
|
||
public class MainActivity extends AppCompatActivity { | ||
|
||
private static final int REQUEST_CODE_PICK_AUDIO = 1; | ||
private static final int REQUEST_CODE_PICK_VIDEO = 2; | ||
private static final int REQUEST_CODE_PERMISSIONS = 3; | ||
|
||
private TextView statusTextView; | ||
|
||
@Override | ||
protected void onCreate(Bundle savedInstanceState) { | ||
super.onCreate(savedInstanceState); | ||
setContentView(R.layout.activity_main); | ||
|
||
statusTextView = findViewById(R.id.statusTextView); | ||
|
||
Button pickAudioButton = findViewById(R.id.pickAudioButton); | ||
pickAudioButton.setOnClickListener(new View.OnClickListener() { | ||
@Override | ||
public void onClick(View v) { | ||
pickAudioFile(); | ||
} | ||
}); | ||
|
||
Button pickVideoButton = findViewById(R.id.pickVideoButton); | ||
pickVideoButton.setOnClickListener(new View.OnClickListener() { | ||
@Override | ||
public void onClick(View v) { | ||
pickVideoFile(); | ||
} | ||
}); | ||
|
||
if (!hasPermissions()) { | ||
requestPermissions(); | ||
} | ||
} | ||
|
||
private boolean hasPermissions() { | ||
return ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED; | ||
} | ||
|
||
private void requestPermissions() { | ||
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, REQUEST_CODE_PERMISSIONS); | ||
} | ||
|
||
private void pickAudioFile() { | ||
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI); | ||
startActivityForResult(intent, REQUEST_CODE_PICK_AUDIO); | ||
} | ||
|
||
private void pickVideoFile() { | ||
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Video.Media.EXTERNAL_CONTENT_URI); | ||
startActivityForResult(intent, REQUEST_CODE_PICK_VIDEO); | ||
} | ||
|
||
@Override | ||
protected void onActivityResult(int requestCode, int resultCode, Intent data) { | ||
super.onActivityResult(requestCode, resultCode, data); | ||
if (resultCode == RESULT_OK && data != null) { | ||
Uri uri = data.getData(); | ||
if (requestCode == REQUEST_CODE_PICK_AUDIO) { | ||
transcribeAudio(uri); | ||
} else if (requestCode == REQUEST_CODE_PICK_VIDEO) { | ||
transcribeVideo(uri); | ||
} | ||
} | ||
} | ||
|
||
private void transcribeAudio(Uri uri) { | ||
Intent intent = new Intent(this, TranscriptionService.class); | ||
intent.setData(uri); | ||
intent.putExtra("type", "audio"); | ||
startService(intent); | ||
statusTextView.setText("Transcribing audio..."); | ||
} | ||
|
||
private void transcribeVideo(Uri uri) { | ||
Intent intent = new Intent(this, TranscriptionService.class); | ||
intent.setData(uri); | ||
intent.putExtra("type", "video"); | ||
startService(intent); | ||
statusTextView.setText("Transcribing video..."); | ||
} | ||
|
||
@Override | ||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { | ||
super.onRequestPermissionsResult(requestCode, permissions, grantResults); | ||
if (requestCode == REQUEST_CODE_PERMISSIONS) { | ||
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { | ||
// Permissions granted | ||
} else { | ||
// Permissions denied | ||
statusTextView.setText("Permissions denied. Cannot access files."); | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.