Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
8827ba7
Upgrade compile and target SDK versions to 27
Trollhunters501 Jul 10, 2026
5fef228
Delete app/libs/Compatv4.jar
Trollhunters501 Jul 10, 2026
ceb1860
Delete app/libs/customTabs.jar
Trollhunters501 Jul 10, 2026
e27e046
Delete app/libs/zappcompats.jar
Trollhunters501 Jul 10, 2026
2fe6c99
Update targetSdkVersion to 27 in AndroidManifest.xml
Trollhunters501 Jul 10, 2026
f83fb9d
Implement permission requests and checks in JSInterface
Trollhunters501 Jul 10, 2026
9009eca
Refactor CSS styles for chat application
Trollhunters501 Jul 10, 2026
1361323
Refactor HTML structure and permissions section
Trollhunters501 Jul 10, 2026
11f092f
Refactor main.js for better structure and readability
Trollhunters501 Jul 10, 2026
fa274ff
Add AndroidX and Jetifier settings to properties
Trollhunters501 Jul 10, 2026
1485cd1
Remove AndroidX and Jetifier settings
Trollhunters501 Jul 10, 2026
5bfbab2
Enable AndroidX and Jetifier in gradle.properties
Trollhunters501 Jul 10, 2026
6cc778c
Upgrade compile and target SDK versions to 28
Trollhunters501 Jul 10, 2026
b678b69
Update target SDK version in AndroidManifest.xml
Trollhunters501 Jul 10, 2026
abf4245
Update Android compatibility version in README
Trollhunters501 Jul 10, 2026
3c1407c
Refactor GithubUpdate to use androidx.browser
Trollhunters501 Jul 10, 2026
e99ce9b
Delete app/src/main/res/drawable-hdpi directory
Trollhunters501 Jul 10, 2026
10e53b4
Delete app/src/main/res/drawable-ldpi directory
Trollhunters501 Jul 10, 2026
06591c9
Delete app/src/main/res/drawable-mdpi directory
Trollhunters501 Jul 10, 2026
95bff94
Delete app/src/main/res/drawable-xhdpi directory
Trollhunters501 Jul 10, 2026
2c9d39b
arreglar logo
Trollhunters501 Jul 10, 2026
3d38657
arreglar logo y optimizar código de inicio de IA
Trollhunters501 Jul 10, 2026
6374a7b
Refactor main.js for improved readability and structure
Trollhunters501 Jul 11, 2026
070274d
Refactor MainActivity to use a new Conscrypt provider
Trollhunters501 Jul 11, 2026
287c58b
Refactor MainActivity to improve structure and clarity
Trollhunters501 Jul 11, 2026
5580cbe
Add Conscrypt support for OkHttpClient
Trollhunters501 Jul 11, 2026
296457a
Remove Conscrypt SSL socket factory usage
Trollhunters501 Jul 11, 2026
82a7e20
Refactor MainActivity for improved readability
Trollhunters501 Jul 11, 2026
6dfc6e3
Update Conscrypt dependency version to 2.5.3
Trollhunters501 Jul 11, 2026
f8ed6e5
Refactor main.js for improved structure and readability
Trollhunters501 Jul 11, 2026
930dd81
Refactor MainActivity for improved structure
Trollhunters501 Jul 11, 2026
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
10 changes: 4 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
# CreaProDroid

CreaProDroid es un asistente de inteligencia artificial diseñado específicamente para dispositivos Android antiguos (versiones 4.2 a 8.1). Este asistente utiliza la tecnología de Google Gemini y Pollinations.ai, y está optimizado para ofrecer una experiencia fluida y útil en dispositivos con recursos limitados.
CreaProDroid es un asistente de inteligencia artificial diseñado específicamente para dispositivos Android antiguos (versiones 4.2 a 9). Este asistente utiliza la tecnología de Google Gemini y Pollinations.ai, y está optimizado para ofrecer una experiencia fluida y útil en dispositivos con recursos limitados.
Si este no es compatible puedes probar [CreaProPhone J2ME](https://github.com/Creadores-Program/CreaProPhone) con [J2ME Loader de SpoxgoStore](https://spoxgostore-blogspot.com/p/j2me-loader.html) que extiende la compatibilidad a Android 2.3

## **Características**
- **Asistente de IA**: Responde preguntas, realiza tareas y ofrece asistencia personalizada.
- **Compatibilidad con Android Antiguo**: Diseñado para funcionar en dispositivos con Android 4.2 a 8.1.
- **Compatibilidad con Android Antiguo**: Diseñado para funcionar en dispositivos con Android 4.2 a 9.
- **Reconocimiento de Voz**: Permite interactuar mediante comandos de voz.
- **Generación de Imágenes**: Genera imágenes basadas en descripciones proporcionadas por el usuario con Pollinations.ai.
- **Apertura de Aplicaciones**: Puede abrir aplicaciones instaladas en el dispositivo.
- **Soporte para Archivos**: Procesa archivos de texto proporcionados por el usuario.
- **Interfaz Amigable**: Diseño intuitivo y fácil de usar.

## **Requisitos**
- **Versión de Android**: 4.2 (Jelly Bean) a 8.1 (Oreo).
- **Versión de Android**: 4.2 (Jelly Bean) a 9 (Pie).
- **Permisos Necesarios**:
- Acceso a Internet.
- Lectura y escritura en almacenamiento externo.
Expand Down Expand Up @@ -65,10 +65,8 @@ Para preguntas o soporte, contacta a [Creadores Program](https://github.com/Crea
- Gemini
- MarkdownToHtml for es5
- Google Fonts
- Support Custom Tabs
- Okhttp
- okio
- Support App Compats
- Support Compat v4
- Androidx Browser custom tabs
- Pollinations.ai
- Conscrypt
10 changes: 4 additions & 6 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,17 @@ plugins {
}
dependencies {
implementation 'com.squareup.okhttp3:okhttp:3.12.13'
implementation 'org.conscrypt:conscrypt-android:2.5.2'
implementation files('libs/Compatv4.jar')
implementation files('libs/zappcompats.jar')
implementation files('libs/customTabs.jar')
implementation 'org.conscrypt:conscrypt-android:2.5.3'
implementation 'androidx.browser:browser:1.3.0'
}

android {
namespace 'org.CreadoresProgram.CreaProDroid'
compileSdkVersion 21
compileSdkVersion 28

defaultConfig {
minSdkVersion 17
targetSdkVersion 21
targetSdkVersion 28
versionCode 6
versionName "1.4.0-beta"
}
Expand Down
Binary file removed app/libs/Compatv4.jar
Binary file not shown.
Binary file removed app/libs/customTabs.jar
Binary file not shown.
Binary file removed app/libs/zappcompats.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" ?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.CreadoresProgram.CreaProDroid" android:versionCode="6" android:versionName="1.4.0-beta">
<uses-sdk android:minSdkVersion="17" android:targetSdkVersion="21" />
<uses-sdk android:minSdkVersion="17" android:targetSdkVersion="28" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Expand Down
13 changes: 13 additions & 0 deletions app/src/main/assets/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,19 @@ <h1>CreaProDroid</h1>
<button onclick="if(confirm('Quieres Borrar la conversacion?')){ Android.clearChat(); document.getElementById('Chat').innerHTML = ''; }" style="background: url('./resources/chat_error.png') 50% 50% no-repeat;"></button>
</div>
</div>
<div class="InterfaceH HideDef" id="ReqPerms">
<div id="reqPerms-header" style="position: -webkit-sticky; position: sticky; top: 0;">
<h1>Permisos</h1>
</div>
<div id="reqPermsDesq">
<p>Permisos Requeridos para el funcionamiento de la app:<br/>
• Almacenamiento: requerido para guardar imágenes generadas o subir archivos para la IA.<br/>
• Grabar Audio: requerido para grabar tu voz para hablar con la IA<br/>
• Contactos: requerido para que la IA pueda ver tus contactos para enviar mensajes, hacer llamadas y más (solo si el plugin está activo)<br/>
Además está app es totalmente de código abierto y puedes ver su código <button class="github-btn" onclick="Android.openUrl('https://github.com/Creadores-Program/CreaProDroid')">en Github</button></p><br/>
<button id="reqPermsBtn" onclick="Android.reqPerms(); if(!Android.hasPerms()){ alert('Porfavor acepta los permisos'); }else{ document.getElementById('ReqPerms').style.display = 'none'; document.getElementById('Home').style.display = 'block'; }">Aceptar Permisos</button>
</div>
</div>
<div class="InterfaceH HideDef" id="OldsChats">
<div id="oldChats-header" style="position: -webkit-sticky; position: sticky; top: 0;">
<div id="backOlCBtn" style="width: 40px; height: 40px; background: url('./resources/close.png') 50% 50% no-repeat; background-size: contain;" onclick="document.getElementById('OldsChats').style.display = 'none'; document.getElementById('Home').style.display = 'block';"></div>
Expand Down
11 changes: 10 additions & 1 deletion app/src/main/assets/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ if(localStorage.getItem("apiKey") == null){
Android.finish();
throw new Error("No se puede continuar sin la API key.");
}
if(localStorage.getItem("model") == null){
localStorage.setItem("model", "1");
}
Android.setModel(parseInt(localStorage.getItem("model")));
try{
if(Android.promptGemini("Este Es Un Test de ti porfavor responde un Saludo!", apiKey) == "{{KeyInvalidTest74284}}") throw new Error("Error Key Invalida!");
}catch(e){
Expand Down Expand Up @@ -54,6 +58,10 @@ if(localStorage.getItem("historyChats") == null){
}else{
chatHistoryOld = JSON.parse(localStorage.getItem("historyChats"));
}
if(!Android.hasPerms()){
document.getElementById('Home').style.display = 'none';
document.getElementById('ReqPerms').style.display = 'block';
}
function saveChatHistory(){
var timeCreatedCekj = new Date();
chatHistoryOld.push({
Expand All @@ -70,6 +78,7 @@ function loadChatHistory(name){
for(var i = 0; i < chatHistoryOld.length; i++){
if(chatHistoryOld[i].name == name){
chatHistoryloda = chatHistoryOld[i].history;
chatHistoryOld.splice(i, 1);
break;
}
}
Expand Down Expand Up @@ -139,7 +148,7 @@ function sendToHtml(msg){
var chatIAd = document.createElement("div");
chatIAd.className += "message bot clearfix";
var IAavatar = document.createElement("img");
IAavatar.src = "./resources/AvatarIA.jpeg";
IAavatar.src = "file:///android_res/drawable/ic_launcher";
IAavatar.className += "avatar";
chatIAd.appendChild(IAavatar);
var djdfiimtemBtn = document.createElement("button");
Expand Down
Binary file removed app/src/main/assets/resources/AvatarIA.jpeg
Binary file not shown.
75 changes: 75 additions & 0 deletions app/src/main/assets/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -352,3 +352,78 @@ pre code textarea:focus {
border-radius: 4px;
font-weight: bold;
}

#ReqPerms {
background-color: #121212;
}

#reqPerms-header {
background-color: #1e1e1e;
padding: 10px 20px;
border-bottom: 1px solid #333333;
}

#reqPerms-header h1 {
margin: 0;
font-size: 24px;
color: #ffffff;
}

#reqPermsDesq {
padding: 20px;
max-width: 600px;
margin: 0 auto;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}

#reqPermsDesq p {
line-height: 1.6;
color: #e0e0e0;
margin-bottom: 25px;
}

#reqPermsDesq {
background-color: #333333;
color: #ffffff;
border: 1px solid #444444;
cursor: pointer;
font-size: 14px;
vertical-align: middle;
margin-left: 4px;
transition: background-color 0.2s;
}

#reqPermsDesq .github-btn:hover {
background-color: #444444;
}

#reqPermsBtn {
display: block;
width: 100%;
max-width: 300px;
margin: 30px auto 0 auto;
padding: 12px 20px;
background-color: #6200ee;
color: #ffffff;
border: none;
font-size: 16px;
font-weight: bold;
cursor: pointer;
text-align: center;
-webkit-border-radius: 8px;
border-radius: 8px;
-webkit-box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);
transition: background-color 0.2s, transform 0.2s;
}

#reqPermsBtn:hover {
background-color: #7c22ff;
}

#reqPermsBtn:active {
background-color: #4d00b8;
-webkit-transform: scale(0.98);
transform: scale(0.98);
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,92 +65,78 @@ static Charset getUTF8(){
public MaxIaManager(Context context) {
this.context = context;
AssetManager assetManager = context.getAssets();
try{
String[] files = assetManager.list("IA/MaxIA");
if(files != null) {
for (String file : files) {
InputStream inputStream = null;
try{
inputStream = assetManager.open("IA/MaxIA/" + file);
byte[] buff = new byte[inputStream.available()];
int bytesRea;
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
while ((bytesRea = inputStream.read(buff)) != -1) {
outputStream.write(buff, 0, bytesRea);
}
byte[] fileBytes = outputStream.toByteArray();
this.BaseDataIA += " . " + new String(fileBytes, dataCodeStr);
}finally {
if(inputStream != null) inputStream.close();
}
}
try {
StringBuilder baseDataBuilder = new StringBuilder();
loadFolderData(assetManager, "IA/MaxIA", baseDataBuilder);
this.BaseDataIA = baseDataBuilder.toString();
StringBuilder gamesDataBuilder = new StringBuilder();
loadFolderData(assetManager, "IA/Games", gamesDataBuilder);
this.gamesIA = gamesDataBuilder.toString();
String botPromptsStr = readAssetAsString(assetManager, "IA/Data/MaxIA/BotPromptsv2.json");
if (botPromptsStr != null) {
this.maxBotPrompts = new JSONArray(botPromptsStr);
}
String[] filesGames = assetManager.list("IA/Games");
if(filesGames != null) {
for (String file : filesGames) {
InputStream inputStream = null;
try{
inputStream = assetManager.open("IA/Games/" + file);
byte[] buff = new byte[inputStream.available()];
int bytesRea;
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
while ((bytesRea = inputStream.read(buff)) != -1) {
outputStream.write(buff, 0, bytesRea);
}
byte[] fileBytes = outputStream.toByteArray();
this.gamesIA += " . " + new String(fileBytes, dataCodeStr);
}finally {
if(inputStream != null) inputStream.close();
}
}
String noSeBotStr = readAssetAsString(assetManager, "IA/Data/MaxIA/NoseBotv2.json");
if (noSeBotStr != null) {
this.maxNoSeBotPrompts = new JSONArray(noSeBotStr);
}
InputStream inputS = null;
InputStream inputS2 = null;
try{
inputS = assetManager.open("IA/Data/MaxIA/BotPromptsv2.json");
inputS2 = assetManager.open("IA/Data/MaxIA/NoseBotv2.json");
byte[] buff = new byte[inputS.available()];
int bytesRea;
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
while ((bytesRea = inputS.read(buff)) != -1) {
outputStream.write(buff, 0, bytesRea);
}
byte[] fileBytes = outputStream.toByteArray();
this.maxBotPrompts = new JSONArray(new String(fileBytes, dataCodeStr));
byte[] buff2 = new byte[inputS2.available()];
int bytesRea2;
ByteArrayOutputStream outputStream2 = new ByteArrayOutputStream();
while ((bytesRea2 = inputS2.read(buff2)) != -1) {
outputStream2.write(buff2, 0, bytesRea2);
}
byte[] fileBytes2 = outputStream2.toByteArray();
this.maxNoSeBotPrompts = new JSONArray(new String(fileBytes2, dataCodeStr));
}finally {
if(inputS != null) inputS.close();
if(inputS2 != null) inputS2.close();
}
}catch (Exception e) {
} catch (Exception e) {
e.printStackTrace();
}
//Cargar Apps para abrir
PackageManager pm = context.getPackageManager();
Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
List<ResolveInfo> activities = pm.queryIntentActivities(intent, 0);
for (ResolveInfo pkg : activities) {
ApplicationInfo appInfo;
PackageManager packageManager = context.getPackageManager();
Intent launcherIntent = new Intent(Intent.ACTION_MAIN, null);
launcherIntent.addCategory(Intent.CATEGORY_LAUNCHER);
List<ResolveInfo> launchableActivities = packageManager.queryIntentActivities(launcherIntent, 0);
for (ResolveInfo resolveInfo : launchableActivities) {
try {
appInfo = pm.getApplicationInfo(pkg.activityInfo.packageName, 0);
} catch (PackageManager.NameNotFoundException e) {
ApplicationInfo appInfo = packageManager.getApplicationInfo(resolveInfo.activityInfo.packageName, 0);
CharSequence appLabel = packageManager.getApplicationLabel(appInfo);
JSONObject appJson = new JSONObject();
appJson.put("name", appLabel != null ? appLabel.toString() : "");
appJson.put("package", appInfo.packageName);
this.apps.put(appJson);
} catch (Exception e) {
continue;
}
JSONObject jsonObj = new JSONObject();
try{
jsonObj.put("name", pm.getApplicationLabel(appInfo).toString());
jsonObj.put("package", appInfo.packageName);
this.apps.put(jsonObj);
}catch (Exception e){
continue;
}
}
private void loadFolderData(AssetManager assetManager, String folderPath, StringBuilder outputBuilder) {
try {
String[] files = assetManager.list(folderPath);
if (files != null) {
for (String fileName : files) {
String fileContent = readAssetAsString(assetManager, folderPath + "/" + fileName);
if (fileContent != null) {
outputBuilder.append(" . ").append(fileContent);
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}

private String readAssetAsString(AssetManager assetManager, String filePath) {
InputStream inputStream = null;
ByteArrayOutputStream outputStream = null;
try {
inputStream = assetManager.open(filePath);
outputStream = new ByteArrayOutputStream();
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
return new String(outputStream.toByteArray(), dataCodeStr);
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
if (outputStream != null) {
try { outputStream.close(); } catch (IOException ignored) {}
}
if (inputStream != null) {
try { inputStream.close(); } catch (IOException ignored) {}
}
}
}
Expand Down
Loading