Android WebView
Este guia apresenta como integrar o smart checkout em aplicações Android nativas utilizando WebView, permitindo incorporar a experiência de pagamento diretamente no aplicativo.
O objetivo é fornecer uma implementação estável, segura e compatível com os principais métodos de pagamento suportados.
📋 Requisitos mínimos
Android
minSdkVersion: 21 (Android 5.0)targetSdkVersion: 33 (Android 13)compileSdkVersion: 33
Dependências Gradle
dependencies {
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.9.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
}⚙️ Configuração do projeto
build.gradle (Projeto)
build.gradle (Projeto)buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.4.2'
}
}build.gradle (App)
build.gradle (App)android {
namespace 'com.exemplo.webview'
compileSdkVersion 33
defaultConfig {
minSdkVersion 21
targetSdkVersion 33
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}🔐 Permissões necessárias
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Permissões Básicas -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- Permissões para Download -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:usesCleartextTraffic="true"
android:requestLegacyExternalStorage="true">
<!-- FileProvider para Downloads -->
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
</application>
</manifest>file_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path name="external_files" path="." />
<external-cache-path name="external_cache" path="." />
<cache-path name="cache" path="." />
<files-path name="files" path="." />
</paths>🧩 Implementação da WebView
Layout (activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="@+id/urlEditText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="Digite a URL"
android:inputType="textUri"
android:padding="8dp" />
<Button
android:id="@+id/loadButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="Carregar" />
</LinearLayout>
<WebView
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_marginTop="16dp" />
</LinearLayout>Configuração da WebView (MainActivity.java)
public class MainActivity extends AppCompatActivity {
private WebView webView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Inicializa a WebView
webView = findViewById(R.id.webView);
// Configurações Básicas
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setDomStorageEnabled(true);
webSettings.setLoadWithOverviewMode(true);
webSettings.setUseWideViewPort(true);
// Configurações Adicionais
webSettings.setAllowFileAccess(true);
webSettings.setAllowContentAccess(true);
webSettings.setDatabaseEnabled(true);
webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
// Habilita Debugging
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
WebView.setWebContentsDebuggingEnabled(true);
}
// Configura o WebViewClient
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
}
@Override
public void onReceivedError(WebView view, WebResourceRequest request,
WebResourceError error) {
// Tratamento de erros
}
});
// Carrega a URL do Smart Checkout
webView.loadUrl("https://domain.com");
}
}👉 Recursos Adicionais
Tratamento de permissões em runtime
private void checkAndRequestPermissions() {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE
},
PERMISSION_REQUEST_CODE);
}
}
@Override
public void onRequestPermissionsResult(int requestCode,
String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PERMISSION_REQUEST_CODE) {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permissão concedida
} else {
// Permissão negada
}
}
}Interceptação de downloads
webView.setDownloadListener(new DownloadListener() {
@Override
public void onDownloadStart(String url, String userAgent,
String contentDisposition, String mimetype, long contentLength) {
// Para URLs normais
if (!url.startsWith("data:")) {
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.setMimeType(mimetype);
request.addRequestHeader("User-Agent", userAgent);
request.setDescription("Baixando arquivo...");
request.setTitle(URLUtil.guessFileName(url, contentDisposition, mimetype));
request.allowScanningByMediaScanner();
request.setNotificationVisibility(
DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setDestinationInExternalPublicDir(
Environment.DIRECTORY_DOWNLOADS,
URLUtil.guessFileName(url, contentDisposition, mimetype));
DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
dm.enqueue(request);
} else {
// Para data URLs (base64)
handleBase64Download(url, mimetype);
}
}
});⚠️ Problemas comuns e soluções
ERR_CLEARTEXT_NOT_PERMITTED
- Adicione android:usesCleartextTraffic="true" no AndroidManifest.xml
- Ou use HTTPS
Erro de permissão de armazenamento
- Verifique se as permissões estão declaradas no manifest
- Implemente a solicitação de permissão em runtime
- Para Android 10+, use android:requestLegacyExternalStorage="true"
WebView não carrega
- Verifique a conexão com a internet
- Confirme se INTERNET permission está no manifest
- Verifique se JavaScript está habilitado
Downloads não funcionam
- Verifique permissões de armazenamento
- Configure o FileProvider
- Implemente DownloadListener
🧪 Debug e logs
// Habilita logs do console
webView.setWebChromeClient(new WebChromeClient() {
@Override
public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
Log.d("WebView", consoleMessage.message());
return true;
}
});
// Debugging via Chrome DevTools
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
WebView.setWebContentsDebuggingEnabled(true);
}✅ Boas práticas
- Sempre usar HTTPS
- Testar em múltiplas versões Android
- Validar fluxo completo (Pix, cartão, etc.)
- Monitorar logs da WebView
- Utilizar Webhook para confirmação de pagamento (não confiar apenas na UI)
🎯 Resumo
A integração via WebView é a forma mais rápida de incorporar o smart checkout em apps Android, mantendo controle da experiência sem precisar implementar uma UI de pagamento nativa.
Updated 4 months ago
Did this page help you?