[BUG] WebView Error No Permissions net::ERR_ACCESS_DENIED

WebView does not work with local files in Assets. I have some index.html, script.js and styles.css, the block configurations are in the image below, which works perfectly in App Inventor. Performing the same steps gives the error net::ERR_ACCES_DENIED, even with the permissions blocks enabled.


The correct path is

http://localhost/index.html

Taifun

1 Like

I have the index.html file below but the CSS is not loaded. I have tried the relative path but it does not work.

index.html

Click to view
<!DOCTYPE html>
<html lang="pt-BR">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Grade de Horários Escolar</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <h1>Grade de Horários Escolar</h1>
    
    <!-- Gerenciamento de Séries e Turmas -->
    <div class="class-management">
        <h3>Gerenciamento de Séries e Turmas</h3>
        <div class="class-form">
            <div>
                <label>Série: </label>
                <input type="text" id="gradeName" placeholder="Ex: 1º Ano">
            </div>
            <div>
                <label>Turma: </label>
                <input type="text" id="className" placeholder="Ex: A">
            </div>
            <div class="form-buttons">
                <button onclick="addClass()" id="addClassBtn">Adicionar Turma</button>
                <button onclick="updateClass()" id="updateClassBtn" style="display: none;">Atualizar Turma</button>
                <button onclick="cancelClassEdit()" id="cancelClassEditBtn" style="display: none;">Cancelar</button>
            </div>
        </div>

        <div class="class-list">
            <h4>Turmas Cadastradas:</h4>
            <select id="currentClass" onchange="updateCurrentClass()">
                <option value="">Selecione uma turma</option>
            </select>
            <div id="classesList"></div>
        </div>
    </div>
    
    <div class="settings">
        <!-- Resto do código HTML permanece igual -->
    </div>
    
    <!-- Resto do arquivo HTML continua igual -->

    <script src="script.js"></script>
</body>
</html><!DOCTYPE html>
<html lang="pt-BR">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Grade de Horários Escolar</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <h1>Grade de Horários Escolar</h1>
    
    <div class="settings">
        <h3>Configurações de Turnos</h3>
        <div class="shift-settings">
            <div>
                <label>Início do turno matutino: </label>
                <input type="time" id="startTimeMorning" value="07:00">
            </div>
            <div>
                <label>Fim do turno matutino: </label>
                <input type="time" id="endTimeMorning" value="12:00">
            </div>
            <div>
                <label>Início do turno vespertino: </label>
                <input type="time" id="startTimeAfternoon" value="13:00">
            </div>
            <div>
                <label>Fim do turno vespertino: </label>
                <input type="time" id="endTimeAfternoon" value="18:00">
            </div>
            <div>
                <label>Início do turno noturno: </label>
                <input type="time" id="startTimeNight" value="18:30">
            </div>
            <div>
                <label>Fim do turno noturno: </label>
                <input type="time" id="endTimeNight" value="22:30">
            </div>
        </div>

        <h3>Configurações de Aulas</h3>
        <div class="class-settings">
            <div>
                <label>Duração da aula (minutos): </label>
                <input type="number" id="classDuration" value="40" min="30" max="120">
            </div>
            <div>
                <label>Quantidade de recreios: </label>
                <input type="number" id="breakCount" value="1" min="1" max="3" onchange="updateBreakInputs()">
            </div>
            <div id="breakInputsContainer">
                <!-- Break inputs will be generated here -->
            </div>
        </div>
    </div>

    <div class="teacher-management">
        <h3>Gerenciamento de Professores</h3>
        <div class="teacher-form">
            <div>
                <label>Nome do Professor: </label>
                <input type="text" id="teacherName">
            </div>
            <div>
                <label>Disciplina: </label>
                <input type="text" id="subject">
            </div>
            <div>
                <label>Quantidade de aulas semanais: </label>
                <input type="number" id="weeklyClasses" min="1" max="40">
            </div>
            <div class="form-buttons">
                <button onclick="addTeacher()" id="addTeacherBtn">Adicionar Professor</button>
                <button onclick="updateTeacher()" id="updateTeacherBtn" style="display: none;">Atualizar Professor</button>
                <button onclick="cancelEdit()" id="cancelEditBtn" style="display: none;">Cancelar</button>
            </div>
        </div>
        
        <div class="teacher-list">
            <h4>Professores Cadastrados:</h4>
            <select id="currentTeacher" onchange="updateCurrentTeacher()">
                <option value="">Selecione um professor</option>
            </select>
            <div id="teachersList"></div>
        </div>
    </div>

    <div class="schedule-controls">
        <button onclick="generateSchedule()" class="generate-button">Gerar Grade</button>
        <button onclick="checkConflicts()" class="check-conflicts">Verificar Choques</button>
        <button onclick="applyResolvedSchedule()" class="apply-schedule">Aplicar Sugestões</button>
        <button onclick="saveToCache()" class="save-button">Salvar Dados</button>
        <button onclick="generatePDF()" class="pdf-button">Gerar PDF</button>
        <button onclick="clearCache()" class="clear-button">Limpar Dados</button>
    </div>

    <div id="suggestions-panel" class="suggestions-panel"></div>

    <div id="schedule-container" class="schedule-container">
        <!-- Schedule table will be generated here -->
    </div>
    
    <script src="script.js"></script>
    <script src="html2canvas.min.js"></script>
    <script src="jspdf.umd.min.js"></script>
</body>
</html>

styles.css

Click to see
body {
    font-family: Arial, sans-serif;
    max-width: 1400px;
    margin: 0 auto;
    padding: 20px;
    background-color: #f5f5f5;
}

h1 {
    text-align: center;
    color: #333;
}

.settings {
    background: white;
    padding: 20px;
    border-radius: 8px;
    margin-bottom: 20px;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

.shift-settings, .class-settings {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 15px;
    margin-bottom: 20px;
}

.teacher-management {
    background: white;
    padding: 20px;
    border-radius: 8px;
    margin-bottom: 20px;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

.teacher-form {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 15px;
    margin-bottom: 20px;
}

.form-buttons {
    display: flex;
    gap: 10px;
}

.teacher-list {
    margin-top: 20px;
}

input[type="time"],
input[type="number"],
input[type="text"],
select {
    width: 100%;
    padding: 8px;
    border: 1px solid #ddd;
    border-radius: 4px;
    box-sizing: border-box;
}

button {
    padding: 10px 20px;
    background-color: #4CAF50;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    font-size: 14px;
    transition: background-color 0.3s ease;
}

button:hover {
    background-color: #45a049;
}

.generate-button {
    background-color: #2196F3;
}

.generate-button:hover {
    background-color: #1976D2;
}

.pdf-button {
    background-color: #FF5722;
}

.pdf-button:hover {
    background-color: #E64A19;
}

.check-conflicts {
    background-color: #FFC107;
    color: #000;
}

.check-conflicts:hover {
    background-color: #FFA000;
}

.apply-schedule {
    background-color: #4CAF50;
}

.apply-schedule:hover {
    background-color: #388E3C;
}

.save-button {
    background-color: #9C27B0;
}

.save-button:hover {
    background-color: #7B1FA2;
}

.clear-button {
    background-color: #F44336;
}

.clear-button:hover {
    background-color: #D32F2F;
}

.schedule-container {
    overflow-x: auto;
    margin-top: 20px;
}

table {
    width: 100%;
    border-collapse: collapse;
    background: white;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

th, td {
    border: 1px solid #ddd;
    padding: 12px;
    text-align: center;
}

th {
    background-color: #f8f9fa;
    font-weight: bold;
}

.time-cell {
    background-color: #f8f9fa;
    font-weight: bold;
    width: 150px;
}

.editable {
    cursor: pointer;
    position: relative;
    min-width: 120px;
}

.editable:hover {
    background-color: #f5f5f5;
}

.break-cell {
    background-color: #e9ecef;
    font-style: italic;
}

.teacher-info {
    font-size: 12px;
    color: #666;
    margin-top: 5px;
}

.conflict {
    background-color: #ffebee;
}

.resolved {
    background-color: #e8f5e9;
    transition: background-color 0.3s ease;
}

#teachersList {
    margin-top: 10px;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
    gap: 10px;
}

.teacher-card {
    background: #f8f9fa;
    padding: 15px;
    border-radius: 4px;
    border: 1px solid #ddd;
    position: relative;
}

.teacher-card .edit-buttons {
    position: absolute;
    top: 5px;
    right: 5px;
    display: flex;
    gap: 5px;
}

.teacher-card .edit-button,
.teacher-card .delete-button {
    padding: 3px 8px;
    font-size: 12px;
}

.suggestions-panel {
    margin: 20px 0;
    padding: 15px;
    background: white;
    border-radius: 8px;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
    display: none;
}

.suggestions-panel.active {
    display: block;
}

.shift-header {
    background-color: #e3f2fd;
    font-weight: bold;
    text-align: center;
}

.schedule-controls {
    display: flex;
    gap: 10px;
    margin: 20px 0;
    flex-wrap: wrap;
    justify-content: center;
}

/* Responsividade */
@media (max-width: 768px) {
    body {
        padding: 10px;
    }
    h1 {
        font-size: 1.5rem;
    }
    .settings, .teacher-management {
        padding: 15px;
    }
    .form-buttons {
        flex-wrap: wrap;
    }
    button {
        font-size: 12px;
        padding: 8px 15px;
    }
    .schedule-container {
        font-size: 0.9rem;
    }
}

@media (orientation: landscape) and (max-aspect-ratio: 16/9) {
    body {
        font-size: 0.8rem;
    }
    table {
        font-size: 0.9rem;
    }
}

@media (hover: none) and (pointer: coarse) {
    button {
        padding: 12px;
        font-size: 16px;
    }
    .editable {
        padding: 10px;
        font-size: 14px;
    }
}

#schedule-container {
    width: auto;
    min-width: 100%; /* Permite que o conteúdo ocupe a largura total */
    overflow: visible; /* Impede o corte do conteúdo */
    white-space: nowrap; /* Garante que os elementos não quebrem para a próxima linha */
    background-color: #fff;
    border: 1px solid #ccc;
    box-sizing: border-box;
}

All files in Assets

├── html2canvas.min.js
├── index.html
├── jspdf.umd.min.js
├── script.js
└── styles.css

Yes, this should be the way to go

Taifun

Show us again a screenshot of your relevant blocks
Open the webviewer in a button click event after permissions have been granted
Btw. to ask for Internet permission is not required, because this is a non dangerous permission
Also test the apk file

Taifun

I’m using it like this in App Inventor and it’s working and loading everything, but in Kodular it doesn’t load.

The answer is here

and btw. that path should also work in App Inventor
Taifun

Both paths work with the APK:

but the second one doesn’t work with Companion. I think it’s one of the countless known bugs.

What is the Do it result of that path?


Taifun

It doesn’t work if you don’t use “/index.html”. The main problem with Kodular now is that it is not loading CSS.

You may try using Load html block with html code directly.

:question:

As I said, both work with the APK. So what could be the problem with the CSS file? Show your blocks.

1 Like

I understand what you said. It should generate the APK, how tragic. I was talking about the simulated environment. The blocks work in App Inventor both in the simulator and with the APK.

The question is, are you interested in finding a solution to the problem or in pointing out bugs in Kodular? The latter would be a Sisyphean task…

The moment we stop pointing out the errors of the platforms, then they will be lost in a sea of errors.

Just as it has long been the case with Kodular.

1 Like