├── .github
└── workflows
│ └── android.yml
├── .gitignore
├── .idea
├── .gitignore
├── .name
├── compiler.xml
├── deploymentTargetDropDown.xml
├── gradle.xml
├── migrations.xml
├── misc.xml
└── vcs.xml
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── lvnvceo
│ │ └── ollamadroid
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── lvnvceo
│ │ │ └── ollamadroid
│ │ │ ├── ChatActivity.java
│ │ │ ├── ChatAdapter.java
│ │ │ ├── ChatMessage.java
│ │ │ ├── MainActivity.java
│ │ │ ├── SettingsActivity.java
│ │ │ └── ollama
│ │ │ ├── ChatRequest.java
│ │ │ ├── ChatResponse.java
│ │ │ ├── Messages.java
│ │ │ └── OllamaModels.java
│ └── res
│ │ ├── drawable
│ │ ├── baseline_account_circle_24.xml
│ │ ├── check_fill0_wght700_grad200_opsz48.xml
│ │ ├── close_fill0_wght700_grad200_opsz48.xml
│ │ ├── ic_launcher_background.xml
│ │ ├── ic_launcher_foreground.xml
│ │ ├── settings_fill0_wght200_grad0_opsz24.xml
│ │ ├── settings_fill1_wght100_grad_25_opsz24.xml
│ │ └── settings_fill1_wght100_grad_25_opsz40.xml
│ │ ├── layout
│ │ ├── activity_chat.xml
│ │ ├── activity_main.xml
│ │ ├── activity_settings.xml
│ │ ├── appbar.xml
│ │ └── chat_message_item.xml
│ │ ├── mipmap-anydpi
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ ├── values-night
│ │ └── themes.xml
│ │ ├── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── themes.xml
│ │ └── xml
│ │ ├── backup_rules.xml
│ │ └── data_extraction_rules.xml
│ └── test
│ └── java
│ └── com
│ └── lvnvceo
│ └── ollamadroid
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.github/workflows/android.yml:
--------------------------------------------------------------------------------
1 | name: Android CI
2 |
3 | on:
4 | push:
5 | branches: [ "master" ]
6 | pull_request:
7 | branches: [ "master" ]
8 |
9 | jobs:
10 | build:
11 |
12 | runs-on: ubuntu-latest
13 |
14 | steps:
15 | - uses: actions/checkout@v3
16 | - name: set up JDK 17
17 | uses: actions/setup-java@v3
18 | with:
19 | java-version: '17'
20 | distribution: 'temurin'
21 | cache: gradle
22 |
23 | - name: Grant execute permission for gradlew
24 | run: chmod +x gradlew
25 | - name: Build with Gradle
26 | run: ./gradlew build
27 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 | .cxx
15 | local.properties
16 | /app/release/
17 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/.idea/.name:
--------------------------------------------------------------------------------
1 | OllamaDroid
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/deploymentTargetDropDown.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
18 |
19 |
--------------------------------------------------------------------------------
/.idea/migrations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # OllamaDroid
3 |
4 | Ollama + Android = OllamaDroid
5 |
6 |
7 | # THIS IS NO LONGER MAINTAINED
8 |
9 | context: I've been busy with irl stuff and work. I sadly am moving on to other projects. If you'd like make your own OllamaDroid project, fork it, recreate it, doesnt matter. Please, if you have an alternative to OllamaDroid, create an issue and ill post a link to that GitHub to redirect others.
10 | | | | |
11 | |--|--|--|
12 | |  |  |  |
13 |
14 | ## Features
15 |
16 | - [x] Text streaming responses
17 | - [ ] Profile customization
18 | - [x] Custom username
19 | - [ ] Custom profile picture
20 | - [ ] System prompt implementation
21 | - [x] Model selection
22 | - [ ] Dark theme / Light theme
23 |
24 | ## Installation
25 |
26 | 1. Clone the repository: `git clone https://github.com/ollamadroid.git`
27 | 2. Open the project in Android Studio.
28 | 3. Build and run the application on your Android device or emulator.
29 |
30 | Alternatively, you can download the APK file from the [releases](https://github.com/lvnvceo/ollamadroid/releases) section and install it directly on your Android device.
31 |
32 | ## Support
33 |
34 | For any inquiries or issues, please [open an issue](https://github.com/lvnvceo/ollamadroid/issues/new) on GitHub.
35 |
36 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.android.application'
3 | }
4 |
5 | android {
6 | namespace 'com.lvnvceo.ollamadroid'
7 | compileSdk 34
8 |
9 | defaultConfig {
10 | applicationId "com.lvnvceo.ollamadroid"
11 | minSdk 28
12 | targetSdk 34
13 | versionCode 1
14 | versionName "1.0"
15 |
16 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
17 | }
18 |
19 | buildTypes {
20 | release {
21 | minifyEnabled false
22 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
23 | }
24 | }
25 |
26 | compileOptions {
27 | sourceCompatibility JavaVersion.VERSION_1_8
28 | targetCompatibility JavaVersion.VERSION_1_8
29 | }
30 | }
31 |
32 | dependencies {
33 | implementation 'com.squareup.okhttp3:okhttp:4.9.0'
34 | implementation 'com.google.code.gson:gson:2.10.1'
35 | implementation 'androidx.appcompat:appcompat:1.6.1'
36 | implementation 'com.google.android.material:material:1.9.0'
37 | implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
38 | testImplementation 'junit:junit:4.13.2'
39 | androidTestImplementation 'androidx.test.ext:junit:1.1.5'
40 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
41 | }
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/lvnvceo/ollamadroid/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.lvnvceo.ollamadroid;
2 |
3 | import android.content.Context;
4 |
5 | import androidx.test.platform.app.InstrumentationRegistry;
6 | import androidx.test.ext.junit.runners.AndroidJUnit4;
7 |
8 | import org.junit.Test;
9 | import org.junit.runner.RunWith;
10 |
11 | import static org.junit.Assert.*;
12 |
13 | /**
14 | * Instrumented test, which will execute on an Android device.
15 | *
16 | * @see Testing documentation
17 | */
18 | @RunWith(AndroidJUnit4.class)
19 | public class ExampleInstrumentedTest {
20 | @Test
21 | public void useAppContext() {
22 | // Context of the app under test.
23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
24 | assertEquals("com.lvnvceo.ollamadroid", appContext.getPackageName());
25 | }
26 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
16 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
27 |
28 |
29 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lvnvceo/ollamadroid/ChatActivity.java:
--------------------------------------------------------------------------------
1 | package com.lvnvceo.ollamadroid;
2 |
3 | import android.content.Intent;
4 | import android.content.SharedPreferences;
5 | import android.os.Bundle;
6 | import android.os.NetworkOnMainThreadException;
7 | import android.text.Editable;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.widget.Button;
11 | import android.widget.EditText;
12 | import android.widget.ImageButton;
13 | import android.widget.TextView;
14 |
15 | import androidx.appcompat.app.AppCompatActivity;
16 | import androidx.recyclerview.widget.LinearLayoutManager;
17 | import androidx.recyclerview.widget.RecyclerView;
18 |
19 | import com.google.gson.Gson;
20 | import com.lvnvceo.ollamadroid.ollama.ChatRequest;
21 | import com.lvnvceo.ollamadroid.ollama.ChatResponse;
22 | import com.lvnvceo.ollamadroid.ollama.Messages;
23 |
24 | import java.io.IOException;
25 | import java.util.ArrayList;
26 | import java.util.List;
27 |
28 | import okhttp3.Call;
29 | import okhttp3.Callback;
30 | import okhttp3.MediaType;
31 | import okhttp3.OkHttpClient;
32 | import okhttp3.Request;
33 | import okhttp3.RequestBody;
34 | import okhttp3.Response;
35 | import okhttp3.ResponseBody;
36 |
37 | public class ChatActivity extends AppCompatActivity {
38 |
39 | private RecyclerView recyclerView;
40 | private ImageButton settingsButton;
41 | private final OkHttpClient okHttpClient = new OkHttpClient();
42 | private ChatAdapter adapter;
43 | private final Messages llamaMessages = new Messages();
44 | private final Gson gson = new Gson();
45 |
46 | // Constants
47 | private static final String SETTINGS_KEY = "settings";
48 | private static final String MODEL_KEY = "model";
49 | private static final String OLLAMA_URL_KEY = "ollama_url";
50 | private static final String SYSTEM_PROMPT = "system_prompt";
51 | private List messages =new ArrayList<>();
52 | private TextView modelTextView;
53 |
54 | @Override
55 | protected void onResume() {
56 | super.onResume();
57 | SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences(SETTINGS_KEY, MODE_PRIVATE);
58 | modelTextView.setText(sharedPreferences.getString(MODEL_KEY,""));
59 | messages.clear();
60 | llamaMessages.messages.clear();
61 |
62 | }
63 |
64 | @Override
65 | protected void onCreate(Bundle savedInstanceState) {
66 | super.onCreate(savedInstanceState);
67 | setContentView(R.layout.activity_chat);
68 |
69 | recyclerView = findViewById(R.id.recycler_view);
70 | settingsButton = findViewById(R.id.buttonSettings);
71 | recyclerView.setLayoutManager(new LinearLayoutManager(this));
72 | modelTextView = findViewById(R.id.modelName);
73 |
74 | SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences(SETTINGS_KEY, MODE_PRIVATE);
75 | adapter = new ChatAdapter(messages);
76 | recyclerView.setAdapter(adapter);
77 | Button sendButton = findViewById(R.id.button_send);
78 | Button stopButton = findViewById(R.id.button_stop);
79 |
80 | // Settings button click listener
81 | settingsButton.setOnClickListener(v -> {
82 | Intent settingsIntent = new Intent(ChatActivity.this, SettingsActivity.class);
83 | startActivity(settingsIntent);
84 | });
85 |
86 | // Stop button click listener
87 | stopButton.setOnClickListener(v -> {
88 | stopButton.setVisibility(View.INVISIBLE);
89 | sendButton.setVisibility(View.VISIBLE);
90 | });
91 |
92 | sendButton.setOnClickListener(v -> {
93 | stopButton.setVisibility(View.VISIBLE);
94 | sendButton.setVisibility(View.INVISIBLE);
95 |
96 | EditText editTextMessage = findViewById(R.id.edit_text_message);
97 | Editable newTextMessage = editTextMessage.getText();
98 | adapter.addMessage(new ChatMessage(R.drawable.baseline_account_circle_24, sharedPreferences.getString("username", "John Doe"), newTextMessage.toString()));
99 | adapter.addMessage(new ChatMessage(R.drawable.ic_launcher_foreground,"AI", ""));
100 | adapter.notifyItemInserted(messages.size() - 1);
101 | recyclerView.smoothScrollToPosition(messages.size() - 1);
102 | llamaMessages.messages.add(new Messages.Message("user", editTextMessage.getText().toString()));
103 | ChatRequest chatRequest = new ChatRequest(sharedPreferences.getString(MODEL_KEY, ""), llamaMessages.messages,true);
104 | RequestBody body = RequestBody.create(gson.toJson(chatRequest), MediaType.parse("application/json"));
105 | Request request = new Request.Builder()
106 | .url(sharedPreferences.getString(OLLAMA_URL_KEY, "")+"/api/chat")
107 | .post(body)
108 | .build();
109 |
110 | okHttpClient.newCall(request).enqueue(new Callback() {
111 | @Override
112 | public void onFailure(Call call, IOException e) {
113 | e.printStackTrace();
114 | }
115 |
116 | @Override
117 | public void onResponse(Call call, Response response) throws IOException {
118 | if (!response.isSuccessful()) {
119 | handleResponseError(sendButton, stopButton);
120 | }
121 |
122 | try (ResponseBody responseBody = response.body()) {
123 | if (responseBody != null) {
124 | stopButton.setOnClickListener(v -> {
125 | try {
126 | response.close();
127 | } catch (NetworkOnMainThreadException ignored) {}
128 | handleResponseError(sendButton,stopButton);
129 | });
130 | processResponseBody(responseBody, messages, sendButton, stopButton);
131 | }
132 | }
133 | }
134 | });
135 | editTextMessage.setText("");
136 | });
137 | }
138 |
139 | private void handleResponseError(Button sendButton, Button stopButton) {
140 | runOnUiThread(() -> {
141 | stopButton.setVisibility(View.INVISIBLE);
142 | sendButton.setVisibility(View.VISIBLE);
143 | });
144 | }
145 |
146 | private void processResponseBody(ResponseBody responseBody, List messages, Button sendButton, Button stopButton) {
147 | TextView textViewMessageContent = recyclerView.getLayoutManager().getChildAt(((LinearLayoutManager) recyclerView.getLayoutManager()).getChildCount() - 1).findViewById(R.id.message_content);
148 | ChatResponse chatResponse = new ChatResponse();
149 | String line;
150 | StringBuilder fullResponse = new StringBuilder();
151 |
152 | try {
153 | while ((line = responseBody.source().readUtf8Line()) != null) {
154 |
155 | chatResponse = gson.fromJson(line, ChatResponse.class);
156 | fullResponse.append(chatResponse.message.content);
157 | runOnUiThread(() -> {
158 | textViewMessageContent.setText(fullResponse);
159 | recyclerView.smoothScrollToPosition(recyclerView.getScrollBarSize());
160 | });
161 | }
162 |
163 | runOnUiThread(() -> {
164 | textViewMessageContent.setText(fullResponse.toString());
165 | recyclerView.smoothScrollToPosition(recyclerView.getScrollBarSize());
166 | });
167 |
168 | if (chatResponse.done) {
169 | addMessage(chatResponse,fullResponse.toString(),stopButton,sendButton);
170 | }
171 | } catch (IOException | NumberFormatException | IllegalStateException e) {
172 | addMessage(chatResponse,fullResponse.toString(),stopButton,sendButton);
173 | e.printStackTrace();
174 | }
175 | }
176 | private void addMessage(ChatResponse finalChatResponse, String fullResponse,Button stopButton, Button sendButton) {
177 | runOnUiThread(() -> {
178 | adapter.removeMessage(adapter.getItemCount() - 1);
179 | adapter.addMessage(new ChatMessage(R.drawable.ic_launcher_foreground, "AI", fullResponse));
180 | llamaMessages.messages.add(new Messages.Message(finalChatResponse.message.role, fullResponse));
181 | stopButton.setVisibility(View.INVISIBLE);
182 | sendButton.setVisibility(View.VISIBLE);
183 | });
184 | }
185 | }
186 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lvnvceo/ollamadroid/ChatAdapter.java:
--------------------------------------------------------------------------------
1 | package com.lvnvceo.ollamadroid;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 | import android.widget.ImageView;
8 | import android.widget.TextView;
9 |
10 | import androidx.annotation.NonNull;
11 | import androidx.recyclerview.widget.RecyclerView;
12 |
13 | import java.util.List;
14 |
15 | public class ChatAdapter extends RecyclerView.Adapter {
16 |
17 | private final List messages;
18 |
19 | public ChatAdapter(List messages) {
20 | this.messages = messages;
21 | }
22 |
23 | @NonNull
24 | @Override
25 | public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
26 | View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.chat_message_item, parent, false);
27 | return new ViewHolder(view);
28 | }
29 |
30 | @Override
31 | public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
32 | ChatMessage message = messages.get(position);
33 | holder.profileImage.setImageResource(message.getProfileImage());
34 | holder.profileName.setText(message.getProfileName());
35 | holder.messageContent.setText(message.getMessageContent());
36 | }
37 |
38 | @Override
39 | public int getItemCount() {
40 | return messages.size();
41 | }
42 |
43 | public static class ViewHolder extends RecyclerView.ViewHolder {
44 | ImageView profileImage;
45 | TextView profileName;
46 | TextView messageContent;
47 |
48 | public ViewHolder(@NonNull View itemView) {
49 | super(itemView);
50 | profileImage = itemView.findViewById(R.id.profile_image);
51 | profileName = itemView.findViewById(R.id.profile_name);
52 | messageContent = itemView.findViewById(R.id.message_content);
53 | }
54 | }
55 | @SuppressLint("NotifyDataSetChanged")
56 | public void addMessage(ChatMessage message) {
57 | messages.add(message);
58 | notifyDataSetChanged(); // Notify adapter of dataset change
59 | }
60 | @SuppressLint("NotifyDataSetChanged")
61 | public void removeMessage(int pos){
62 | messages.remove(pos);
63 | notifyDataSetChanged();
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lvnvceo/ollamadroid/ChatMessage.java:
--------------------------------------------------------------------------------
1 | package com.lvnvceo.ollamadroid;
2 |
3 | public class ChatMessage {
4 | private final int profileImage;
5 | private final String profileName;
6 | private final String messageContent;
7 |
8 | public ChatMessage(int profileImage, String profileName, String messageContent) {
9 | this.profileImage = profileImage;
10 | this.profileName = profileName;
11 | this.messageContent = messageContent;
12 | }
13 |
14 | public int getProfileImage() {
15 | return profileImage;
16 | }
17 |
18 | public String getProfileName() {
19 | return profileName;
20 | }
21 |
22 | public String getMessageContent() {
23 | return messageContent;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lvnvceo/ollamadroid/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.lvnvceo.ollamadroid;
2 |
3 | import androidx.annotation.NonNull;
4 | import androidx.appcompat.app.AppCompatActivity;
5 |
6 | import android.content.Context;
7 | import android.content.Intent;
8 | import android.os.AsyncTask;
9 | import android.os.Bundle;
10 | import android.os.Handler;
11 | import android.os.HandlerThread;
12 | import android.view.View;
13 | import android.widget.Button;
14 | import android.widget.EditText;
15 | import android.widget.ImageButton;
16 | import android.widget.ImageView;
17 | import android.widget.TextView;
18 |
19 | import com.google.android.material.snackbar.Snackbar;
20 |
21 | import java.io.IOException;
22 | import java.net.MalformedURLException;
23 | import java.net.URL;
24 | import java.util.Objects;
25 |
26 | import okhttp3.Call;
27 | import okhttp3.Callback;
28 | import okhttp3.OkHttp;
29 | import okhttp3.OkHttpClient;
30 | import okhttp3.Request;
31 | import okhttp3.Response;
32 |
33 | public class MainActivity extends AppCompatActivity {
34 | private OkHttpClient client = new OkHttpClient();
35 | ImageView connectionStatusImage;
36 | TextView connectionStatusText;
37 | Button goToChatButton;
38 | private EditText editOllamaURL;
39 | @Override
40 | protected void onResume() {
41 | super.onResume();
42 | getConnectionStatus();
43 | }
44 | @Override
45 | protected void onCreate(Bundle savedInstanceState) {
46 | super.onCreate(savedInstanceState);
47 | setContentView(R.layout.activity_main);
48 | ImageButton settingsButton = findViewById(R.id.buttonSettings);
49 | connectionStatusImage = findViewById(R.id.imageConnectionStatus);
50 | connectionStatusText = findViewById(R.id.textConnectionStatus);
51 | goToChatButton = findViewById(R.id.goToChatButton);
52 | settingsButton.setOnClickListener(v -> {
53 | Intent settingsIntent = new Intent(MainActivity.this, SettingsActivity.class);
54 | startActivity(settingsIntent);
55 | });
56 | goToChatButton.setOnClickListener(v -> {
57 | Intent chatIntent = new Intent(MainActivity.this,ChatActivity.class);
58 | startActivity(chatIntent);
59 | });
60 | getConnectionStatus();
61 |
62 | }
63 | private void displayError() {
64 | connectionStatusImage.setImageResource(R.drawable.close_fill0_wght700_grad200_opsz48);
65 | connectionStatusText.setText(R.string.connection_test_failed);
66 | goToChatButton.setVisibility(View.INVISIBLE);
67 | }
68 | private void displayOK() {
69 | connectionStatusImage.setImageResource(R.drawable.check_fill0_wght700_grad200_opsz48);
70 | connectionStatusText.setText(R.string.connection_test_successful);
71 | goToChatButton.setVisibility(View.VISIBLE);
72 |
73 | }
74 | private void getConnectionStatus() {
75 | String ollamaURLStr = getApplicationContext().getSharedPreferences("settings", Context.MODE_PRIVATE).getString("ollama_url", null);
76 |
77 | URL ollamaURL;
78 | try {
79 | ollamaURL = new URL(ollamaURLStr);
80 | } catch (MalformedURLException ignored) {
81 | Snackbar.make(findViewById(R.id.textConnectionStatus),"Invalid URL",2)
82 | .show();
83 | return;
84 | }
85 | if(ollamaURL.getHost().equals("")) {
86 | return;
87 | }
88 | Request request = new Request.Builder()
89 | .url(ollamaURL)
90 | .build();
91 | client.newCall(request).enqueue(new Callback() {
92 | @Override
93 | public void onFailure(@NonNull Call call, @NonNull IOException e) {
94 | runOnUiThread(() -> {
95 | displayError();
96 | e.printStackTrace();
97 | });
98 | }
99 |
100 | @Override
101 | public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
102 | if(!response.isSuccessful()) {
103 | runOnUiThread(() -> {
104 | displayError();
105 | });
106 | throw new IOException("Unexpected code " + response);
107 | } else {
108 | runOnUiThread(() -> {
109 | displayOK();
110 | });
111 | }
112 | }
113 | });
114 |
115 | }
116 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/lvnvceo/ollamadroid/SettingsActivity.java:
--------------------------------------------------------------------------------
1 | package com.lvnvceo.ollamadroid;
2 |
3 | import android.content.Context;
4 | import android.content.SharedPreferences;
5 | import android.graphics.Color;
6 | import android.os.Bundle;
7 | import android.text.Editable;
8 | import android.text.TextWatcher;
9 | import android.view.View;
10 | import android.widget.AdapterView;
11 | import android.widget.ArrayAdapter;
12 | import android.widget.Button;
13 | import android.widget.EditText;
14 | import android.widget.Spinner;
15 | import android.widget.TextView;
16 |
17 | import androidx.annotation.NonNull;
18 | import androidx.appcompat.app.AppCompatActivity;
19 |
20 | import com.google.android.material.snackbar.Snackbar;
21 | import com.google.gson.Gson;
22 | import com.lvnvceo.ollamadroid.ollama.OllamaModels;
23 |
24 | import java.io.IOException;
25 | import java.net.MalformedURLException;
26 | import java.net.URL;
27 | import java.sql.Array;
28 | import java.util.ArrayList;
29 | import java.util.Map;
30 | import java.util.stream.Stream;
31 |
32 | import okhttp3.Call;
33 | import okhttp3.Callback;
34 | import okhttp3.OkHttpClient;
35 | import okhttp3.Request;
36 | import okhttp3.Response;
37 |
38 | public class SettingsActivity extends AppCompatActivity {
39 | private EditText ollamaAPIURL;
40 | private EditText systemPrompt;
41 | private EditText username;
42 | private Spinner modelSpinner;
43 | private OkHttpClient okHttpClient;
44 | private String model;
45 | private SharedPreferences sharedPreferences;
46 |
47 |
48 |
49 | @Override
50 | public void onCreate(Bundle savedInstance) {
51 | super.onCreate(savedInstance);
52 | setContentView(R.layout.activity_settings);
53 | Button saveButton = findViewById(R.id.buttonSave);
54 | okHttpClient = new OkHttpClient();
55 | systemPrompt = findViewById(R.id.editSystemPrompt);
56 | ollamaAPIURL = findViewById(R.id.editOllamaAPIURL);
57 | username = findViewById(R.id.editUsername);
58 | modelSpinner = findViewById(R.id.spinnerModels);
59 |
60 | sharedPreferences = getApplicationContext().getSharedPreferences(getString(R.string.settings_key), Context.MODE_PRIVATE);
61 | systemPrompt.setText(sharedPreferences.getString(getString(R.string.system_prompt_key), null));
62 | ollamaAPIURL.setText(sharedPreferences.getString(getString(R.string.ollama_url_key),null));
63 | username.setText(sharedPreferences.getString(getString(R.string.username_key), null));
64 |
65 | System.out.println(sharedPreferences.getString(getString(R.string.ollama_url_key), ""));
66 | saveButton.setOnClickListener(v -> {
67 |
68 | SharedPreferences.Editor editor = sharedPreferences.edit();
69 | editor.putString(getString(R.string.ollama_url_key), ollamaAPIURL.getText().toString());
70 | editor.putString(getString(R.string.system_prompt_key), systemPrompt.getText().toString());
71 | editor.putString(getString(R.string.username_key), username.getText().toString().equals("") ? "John Doe":username.getText().toString());
72 | editor.putString(getString(R.string.model_key), model);
73 | editor.apply();
74 | finish();
75 | });
76 | ollamaAPIURL.addTextChangedListener(new TextWatcher() {
77 | @Override
78 | public void beforeTextChanged(CharSequence s, int start, int count, int after) {
79 |
80 | }
81 |
82 | @Override
83 | public void onTextChanged(CharSequence s, int start, int before, int count) {
84 |
85 | }
86 |
87 | @Override
88 | public void afterTextChanged(Editable s) {
89 | try {
90 | getModels(new URL(ollamaAPIURL.getText().toString()));
91 | } catch (MalformedURLException e) {
92 | e.printStackTrace();
93 | }
94 | }
95 | });
96 |
97 | modelSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
98 | @Override
99 | public void onItemSelected(AdapterView> parent, View view, int position, long id) {
100 | model = parent.getItemAtPosition(position).toString();
101 | ((TextView) parent.getChildAt(0)).setTextColor(getColor(com.google.android.material.R.color.design_default_color_on_primary));
102 | }
103 | @Override
104 | public void onNothingSelected(AdapterView> parent) {
105 | }
106 | });
107 | try {
108 | getModels(new URL(sharedPreferences.getString(getString(R.string.ollama_url_key),"")));
109 | } catch (MalformedURLException e) {
110 | e.printStackTrace();
111 | }
112 | }
113 | private void getModels(URL ollamaURL) {
114 | if(ollamaURL.getHost().equals("")) {
115 | return;
116 | }
117 | Request request = new Request.Builder()
118 | .url(ollamaURL+"/api/tags")
119 | .build();
120 |
121 | okHttpClient.newCall(request).enqueue(new Callback() {
122 | @Override
123 | public void onFailure(@NonNull Call call, @NonNull IOException e) {
124 | Snackbar.make(findViewById(R.id.editSystemPrompt), "Failed to pull models", 2)
125 | .show();
126 | }
127 |
128 | @Override
129 | public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
130 | if(!response.isSuccessful()) {
131 | return;
132 | }
133 | Gson gson = new Gson();
134 | OllamaModels ollamaModels = gson.fromJson(response.body().string(), OllamaModels.class);
135 | ArrayList ollamaStrings = new ArrayList<>();
136 | for (OllamaModels.OllamaModel ollamaModel : ollamaModels.models) {
137 | ollamaStrings.add(ollamaModel.name);
138 | }
139 | ArrayAdapter arrayAdapter = new ArrayAdapter<>(getApplicationContext(), android.R.layout.simple_spinner_item, ollamaStrings);
140 | runOnUiThread(() -> {
141 | modelSpinner.setAdapter(arrayAdapter);
142 | arrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
143 | modelSpinner.setSelection(arrayAdapter.getPosition(sharedPreferences.getString(getString(R.string.model_key), "")));
144 | });
145 | }
146 | });
147 |
148 | }
149 | }
150 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lvnvceo/ollamadroid/ollama/ChatRequest.java:
--------------------------------------------------------------------------------
1 | package com.lvnvceo.ollamadroid.ollama;
2 |
3 | import java.util.ArrayList;
4 |
5 | public class ChatRequest {
6 | public String model;
7 | public ArrayList messages;
8 | public boolean stream;
9 | public ChatRequest(String model, ArrayList message, boolean stream){
10 | this.model = model;
11 | this.messages = message;
12 | this.stream = stream;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lvnvceo/ollamadroid/ollama/ChatResponse.java:
--------------------------------------------------------------------------------
1 | package com.lvnvceo.ollamadroid.ollama;
2 |
3 | import java.util.Date;
4 |
5 | public class ChatResponse {
6 | public String model;
7 | public Date created_at;
8 | public Messages.Message message;
9 | public boolean done;
10 | public long total_duration;
11 | public int load_duration;
12 | public int prompt_eval_count;
13 | public int prompt_eval_duration;
14 | public int eval_count;
15 | public long eval_duration;
16 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/lvnvceo/ollamadroid/ollama/Messages.java:
--------------------------------------------------------------------------------
1 | package com.lvnvceo.ollamadroid.ollama;
2 |
3 | import java.util.ArrayList;
4 |
5 | public class Messages {
6 | public ArrayList messages = new ArrayList<>();
7 | public static class Message {
8 | public String role;
9 | public String content;
10 | public Message(String role, String string) {
11 | this.role = role;
12 | this.content = string;
13 |
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lvnvceo/ollamadroid/ollama/OllamaModels.java:
--------------------------------------------------------------------------------
1 | package com.lvnvceo.ollamadroid.ollama;
2 |
3 | import java.util.ArrayList;
4 |
5 | public class OllamaModels {
6 | public ArrayList models;
7 | public class OllamaModel {
8 |
9 | public String name;
10 | public String modified_at;
11 | public Object size;
12 | public String digest;
13 | public Details details;
14 |
15 | private class Details {
16 | public String format;
17 | public String family;
18 | public Object families;
19 | public String parameter_size;
20 | public String quantization_level;
21 | }
22 | }
23 | }
24 |
25 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/baseline_account_circle_24.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/check_fill0_wght700_grad200_opsz48.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/close_fill0_wght700_grad200_opsz48.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
15 |
18 |
21 |
22 |
23 |
24 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/settings_fill0_wght200_grad0_opsz24.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/settings_fill1_wght100_grad_25_opsz24.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/settings_fill1_wght100_grad_25_opsz40.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_chat.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
15 |
21 |
29 |
37 |
38 |
39 |
40 |
48 |
49 |
55 |
56 |
66 |
67 |
73 |
80 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
14 |
20 |
28 |
29 |
30 |
31 |
32 |
38 |
39 |
40 |
47 |
48 |
49 |
57 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
12 |
13 |
20 |
21 |
22 |
26 |
27 |
33 |
34 |
35 |
39 |
40 |
46 |
47 |
48 |
52 |
53 |
59 |
60 |
61 |
62 |
66 |
70 |
71 |
72 |
78 |
79 |
80 |
85 |
86 |
93 |
94 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/appbar.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/chat_message_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
13 |
14 |
23 |
24 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDropp/OllamaDroid/3c96b6389583f2e32b09076a0e9fb62321c34137/app/src/main/res/mipmap-hdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDropp/OllamaDroid/3c96b6389583f2e32b09076a0e9fb62321c34137/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDropp/OllamaDroid/3c96b6389583f2e32b09076a0e9fb62321c34137/app/src/main/res/mipmap-mdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDropp/OllamaDroid/3c96b6389583f2e32b09076a0e9fb62321c34137/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDropp/OllamaDroid/3c96b6389583f2e32b09076a0e9fb62321c34137/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDropp/OllamaDroid/3c96b6389583f2e32b09076a0e9fb62321c34137/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDropp/OllamaDroid/3c96b6389583f2e32b09076a0e9fb62321c34137/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDropp/OllamaDroid/3c96b6389583f2e32b09076a0e9fb62321c34137/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDropp/OllamaDroid/3c96b6389583f2e32b09076a0e9fb62321c34137/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDropp/OllamaDroid/3c96b6389583f2e32b09076a0e9fb62321c34137/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/values-night/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FF000000
4 | #FFFFFFFF
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | OllamaDroid
3 | Ollama API URL
4 | Enter the Ollama API URL
5 | OllamaDroid
6 | Message
7 | Send
8 | Enter
9 | System Prompt
10 | Enter System Prompt
11 | Username
12 | Enter Username
13 | Select Model
14 | Profile Picture
15 | Select Picture
16 | Save
17 | Go to Chat
18 | Connection Test Successful
19 | Connection Test Failed
20 | OllamaDroid
21 | Stop
22 | system_prompt
23 | ollama_url
24 | username
25 | settings
26 | model
27 |
--------------------------------------------------------------------------------
/app/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/backup_rules.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/data_extraction_rules.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
12 |
13 |
19 |
--------------------------------------------------------------------------------
/app/src/test/java/com/lvnvceo/ollamadroid/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.lvnvceo.ollamadroid;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | plugins {
3 | id 'com.android.application' version '8.2.2' apply false
4 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app's APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Enables namespacing of each library's R class so that its R class includes only the
19 | # resources declared in the library itself and none from the library's dependencies,
20 | # thereby reducing the size of the R class for that library
21 | android.nonTransitiveRClass=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDropp/OllamaDroid/3c96b6389583f2e32b09076a0e9fb62321c34137/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Feb 14 15:21:08 PST 2024
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
5 | zipStoreBase=GRADLE_USER_HOME
6 | zipStorePath=wrapper/dists
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | #
4 | # Copyright 2015 the original author or authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | ##
21 | ## Gradle start up script for UN*X
22 | ##
23 | ##############################################################################
24 |
25 | # Attempt to set APP_HOME
26 | # Resolve links: $0 may be a link
27 | PRG="$0"
28 | # Need this for relative symlinks.
29 | while [ -h "$PRG" ] ; do
30 | ls=`ls -ld "$PRG"`
31 | link=`expr "$ls" : '.*-> \(.*\)$'`
32 | if expr "$link" : '/.*' > /dev/null; then
33 | PRG="$link"
34 | else
35 | PRG=`dirname "$PRG"`"/$link"
36 | fi
37 | done
38 | SAVED="`pwd`"
39 | cd "`dirname \"$PRG\"`/" >/dev/null
40 | APP_HOME="`pwd -P`"
41 | cd "$SAVED" >/dev/null
42 |
43 | APP_NAME="Gradle"
44 | APP_BASE_NAME=`basename "$0"`
45 |
46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
48 |
49 | # Use the maximum available, or set MAX_FD != -1 to use that value.
50 | MAX_FD="maximum"
51 |
52 | warn () {
53 | echo "$*"
54 | }
55 |
56 | die () {
57 | echo
58 | echo "$*"
59 | echo
60 | exit 1
61 | }
62 |
63 | # OS specific support (must be 'true' or 'false').
64 | cygwin=false
65 | msys=false
66 | darwin=false
67 | nonstop=false
68 | case "`uname`" in
69 | CYGWIN* )
70 | cygwin=true
71 | ;;
72 | Darwin* )
73 | darwin=true
74 | ;;
75 | MINGW* )
76 | msys=true
77 | ;;
78 | NONSTOP* )
79 | nonstop=true
80 | ;;
81 | esac
82 |
83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
84 |
85 |
86 | # Determine the Java command to use to start the JVM.
87 | if [ -n "$JAVA_HOME" ] ; then
88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
89 | # IBM's JDK on AIX uses strange locations for the executables
90 | JAVACMD="$JAVA_HOME/jre/sh/java"
91 | else
92 | JAVACMD="$JAVA_HOME/bin/java"
93 | fi
94 | if [ ! -x "$JAVACMD" ] ; then
95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
96 |
97 | Please set the JAVA_HOME variable in your environment to match the
98 | location of your Java installation."
99 | fi
100 | else
101 | JAVACMD="java"
102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
103 |
104 | Please set the JAVA_HOME variable in your environment to match the
105 | location of your Java installation."
106 | fi
107 |
108 | # Increase the maximum file descriptors if we can.
109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
110 | MAX_FD_LIMIT=`ulimit -H -n`
111 | if [ $? -eq 0 ] ; then
112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
113 | MAX_FD="$MAX_FD_LIMIT"
114 | fi
115 | ulimit -n $MAX_FD
116 | if [ $? -ne 0 ] ; then
117 | warn "Could not set maximum file descriptor limit: $MAX_FD"
118 | fi
119 | else
120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
121 | fi
122 | fi
123 |
124 | # For Darwin, add options to specify how the application appears in the dock
125 | if $darwin; then
126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
127 | fi
128 |
129 | # For Cygwin or MSYS, switch paths to Windows format before running java
130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
133 |
134 | JAVACMD=`cygpath --unix "$JAVACMD"`
135 |
136 | # We build the pattern for arguments to be converted via cygpath
137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
138 | SEP=""
139 | for dir in $ROOTDIRSRAW ; do
140 | ROOTDIRS="$ROOTDIRS$SEP$dir"
141 | SEP="|"
142 | done
143 | OURCYGPATTERN="(^($ROOTDIRS))"
144 | # Add a user-defined pattern to the cygpath arguments
145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
147 | fi
148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
149 | i=0
150 | for arg in "$@" ; do
151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
153 |
154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
156 | else
157 | eval `echo args$i`="\"$arg\""
158 | fi
159 | i=`expr $i + 1`
160 | done
161 | case $i in
162 | 0) set -- ;;
163 | 1) set -- "$args0" ;;
164 | 2) set -- "$args0" "$args1" ;;
165 | 3) set -- "$args0" "$args1" "$args2" ;;
166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
172 | esac
173 | fi
174 |
175 | # Escape application args
176 | save () {
177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
178 | echo " "
179 | }
180 | APP_ARGS=`save "$@"`
181 |
182 | # Collect all arguments for the java command, following the shell quoting and substitution rules
183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
184 |
185 | exec "$JAVACMD" "$@"
186 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if "%ERRORLEVEL%"=="0" goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84 | exit /b 1
85 |
86 | :mainEnd
87 | if "%OS%"=="Windows_NT" endlocal
88 |
89 | :omega
90 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | repositories {
3 | google()
4 | mavenCentral()
5 | gradlePluginPortal()
6 | }
7 | }
8 | dependencyResolutionManagement {
9 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
10 | repositories {
11 | google()
12 | mavenCentral()
13 | }
14 | }
15 |
16 | rootProject.name = "OllamaDroid"
17 | include ':app'
18 |
--------------------------------------------------------------------------------