Selasa, 01 Oktober 2024

Bab 6 Pemrograman Web dan Perangkat Bergerak Kls 12 Rpl


 Library dan Modifikasi Aplikasi Mobile dengan Web


A. Library pada Aplikasi Mobile

Modul library berguna dalam membangun aplikasi yang ada dalam variasi APK versi gratis dan versi i berbayar, sehingga membutuhkan komponen inti yang sama dalam kedua versi. Di samping itu modul library juga berguna membangun beberapa aplikasi yang menggunakan beberapa komponen yang sama, misalnya aktivitas, layanan, atau layout Ul. Namun demikian, dapat memindah file yang ingin digunakan kembali ke dalam modul library kemudian menambahkan library sebagai dependensi untuk setiap modul aplikasi



1. Konsep Penggunaan Library dalam Aplikasi Perangkat Bergerak

Dengan menyediakan open development platform, Android menawarkan kepada para pengembang untuk membuat aplikasi-aplikasi yang inovatif, yang mana pe- ngembang memiliki akses penuh ke framework API yang digunakan oleh aplikasi inti. Selain itu juga bebas dalam mengoptimalkan penggunaan hardware, mengakses informasi lokasi, menjalankan layanan sendiri, mengatur alarm, dan berbagai fungsi- fungsi lainnya. Untuk libraries yang dapat digunakan oleh komponen-komponen dalam sistem, Android menyediakan satu set C/C++ libraries sebagai bagian dari Android application framework sebagai berikut.


a. RxJava dan RxAndroid


Jika ingin menerapkan reactive programming pada project aplikasi android, maka RxJava dan RxAndroid adalah pilihan yang tepat.


b. GSON

GSON adalah library dari Google untuk meng-convert JSON menjadi java object dan java object menjadi JSON.


c. Retrofit

Retrofit adalah library untuk meng-handle REST API dan termasuk salah satu library yang sangat populer di kalangan android developer. Beberapa faktor penyebab populernya retrofit di antaranya sebagai berikut.


1) Konsep annotation akan membuat codingan kita lebih rapih dan enak dipandang.

2) Retrofit merupakan library yang simpel untuk meng-organize API calls.

3) Retrofit men-support RxJava.

4) Retrofit bisa memakai OkHttp sebagai Http client-nya.

5) Retrofit men-support penggunaan GSON dan Jackson.


d. Realm

Realm adalah mobile database yang powerful. Realm merupakan object-oriented database sehingga tidak menggunakan query SQL layaknya SQLite, dan ini me- rupakan salah satu keunggulannya.

e. Glide

Salah satu kelebihan pada glide adalah pada disk caching-nya. Glide merupakan image loading library yang mendukung menampilkan video stills, image, dan animated gif.


f. LeakCanary

Sebagai developer mobile, seorang programmer harus memperhatikan pengguna- an memory, meskipun ada kalanya our messy code menyebabkan memory leak se- hingga mengakibatkan out of memory error. Guna mendeteksi memory leak yang terdapat pada aplikasi dan meminimalisirnya, kita dapat menggunakan LeakCanary.


g. ButterKnife

ButterKnife adalah salah satu library yang dikembangkan oleh Jake Wharton yang berguna untuk membantu proses pengembangan aplikasi android, terutama dalam hal mem-binding view dengan layout pada aplikasi. Biasanya menggunakan View pada resource id di layout, menggunakan findViewById(R.id.view). Namun dengan menggunakan library ButterKnife kita hanya perlu meng-inject view ter- sebut, sehingga fungsi library ButterKnife digunakan untuk mencegah terjadinya pengulangan baris code (boilerpate), dan baris code menjadi lebih sedikit serta mudah dibaca.

1) Cara Menambahkan dan Menggunakan Library ButterKnife Library Android bernama ButterKnife dapat membantu dan mempersingkat inisialisasi komponen yang ada di layout.xml. Selain mempermudah inisialisasi komponen, jika menggunakan library maka kodin pun akan lebih simpel dan mudah dibaca. Langkah-langkah dalam menambahkan library ButterKnife di- awali dengan membuka gradle app module project lalu tambahkan kode berikut.


compile 'com.jakewharton:butterknife:8.5.1'


annotation Processor 'com.jakewharton:butterknife-compiler:8.5.1'


Selanjutnya melakukan sync project hingga proses selesai dikerjakan.


2) Cara Menggunakan Library ButterKnife


Dua metode ButterKnife yang sering digunakan adalah @BindView dan @ OnClick. Misalnya pada layout MainActivity.xml terdapat komponen edittext dengan id etNama dan komponen button dengan id btnTmbSimpan. Maka penggunaan ButterKnife di MainActivity adalah sebagai berikut.


@BindView(R.id.etNama) EditText etNama;


@BindView(R.id.btnTmbSimpan) Button btnTmbSimpan;


Lalu di dalam method onCreate tambahkan kode Butterknife.bind(this); sedang- kan untuk listener onclick button bisa di dalam onCreate dengan methode btnTmbSimpan.setOnClickListener atau memanfaatkan anotasi yang sudah disediakan oleh Butterknife.

@OnClick(R.id.btnTmbSimpan)


void simpan(){


// lakukan sesuatu


}


2. Prosedur Penggunaan Library dalam Aplikasi Perangkat Bergerak


Kelebihan mobile application terletak pada kemudahan dan kepraktisan dalam penggunaannya. Di samping itu, aplikasi mobile tidak membutuhkan koneksi internet sesudah diunduh, sehingga hal tersebut sangat menguntungkan bagi user yang berada di daerah yang tidak terkoneksi dengan internet. Meskipun user berada di daerah yang terkoneksi dengan internet, belum tentu koneksi internet berjalan dengan lancar. Kelebihan ini tentu menjadi nilai lebih yang besar untuk mobile application. Oleh sebab itu, terhubungnya aplikasi dengan banyak fitur membuat user lebih nyaman dalam menjalankan aplikasi mobile. User bisa langsung terhubung dengan fitur gadget seperti kamera, speaker, dan fitur lainnya.

Guna membuat aplikasi sederhana dengan menggunakan Google map me- merlukan Android Developer Tools (ADT) dan koneksi internet. Hal ini bisa diawali dengan membuat project melalui File → New Android Project atau menggunakan ikon New yang ada pada taskbar Eclipse dengan menggunakan setting default dari SDK. Pada saat project telah aktif, dilanjutkan dengan mem- buka file AndroidManifest.xml. Beberapa perubahan harus dilakukan pada bagian ini antara lain sebagai berikut.


a. Menambahkan Permission


Tujuan utamanya adalah memberikan aplikasi izin untuk mengakses beberapa fitur dari sistem Android. Beberapa hal yang berhubungan dengan permission adalah sebagai berikut.


1) android.permission.INTERNET yang digunakan untuk mengakses internet ketika melakukan download API Google Maps.


2)android.permission.ACCESS_NETWORK_STATE yang digunakan untuk melakukan check ketersediaan koneksi internet.

3)android.permission.WRITE_EXTERNAL_STORAGE yang digunakan untuk menyimpan cache pada memory.


4)android.permission.ACCESS_COARSE_LOCATION yang digunakan untuk melakukan akses lokasi melalui WIFI yang sedang digunakan.


5)android.permission.ACCESS_FINE_LOCATION yang digunakan untuk melakukan deteksi lokasi secara terperinci.


b. Melakukan Spesifikasi OpenGL.


Hal yang perlu dipahami adalah beberapa device tidak mampu menggunakan Google Play Service pada saat tidak compatible dengan OpenGL. Implementasinya dilakukan dengan menambahkan perintah sebagai berikut.


<uses-feature


android:glEsVersion="0x00020000"


android:required="true" />


c. Menambahkan Meta Data

Meta data yang ditambahkan berasal dari Google Playstore dan Google maps dalam bentuk key. Dalam hal ini bisa menambahkan tag meta data dalam Application Tree. Diawali dengan menambahkan meta data Google play service dilanjutkan dengan meta data dari API Google Maps yang berisi API_KEY yang dapat melakukan generate. Langkah-langkah dalam mengubah AndroidManifest.xml adalah sebagai berikut.

<?xml version="1.0" encoding="utf-8"?>


<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.elfarqy.androidmaps"


android:versionCode="1"


android:versionName="1.0">


<uses-sdk


android:minSdkVersion="8"


android:targetSdkVersion="19" />


<uses-permission android:name="android.permission.INTERNET" />


<uses-permission STORAGE" /> android:name="android.permission.WRITE_EXTERNAL_


<uses-permission android:name="android.permission.ACCESS_NETWORK_ STATE" />


<uses-permission LOCATION" /> android:name="android.permission.ACCESS_COARSE_


<uses-permission android:name="android.permission.ACCESS_FINE_ LOCATION" />


<uses-permission android:name="com.elfarqy.androidmaps.permission. MAPS_RECEIVE" />


<uses-permission android:name="com.Google.android.providers.gsf. permission.READ_GSERVICES" />


<uses-feature


android:glEsVersion="0x00020000"


android:required="true" />


<application


android:allowBackup="true"


android:icon="@drawable/ic_launcher"


android:label="@string/app_name"


android:theme="@style/AppTheme" >


<activity


android:name="com.elfarqy.androidmaps.MainActivity"


android:label="@string/app_name">


<intent-filter>


<action android:name="android.intent.action.MAIN" />


<category android:name="android.intent.category.LAUNCHER" />


</intent-filter>


</activity>


<meta-data


android:name="com.Google.android.gms.version"

android:value="@integer/Google_play_services_version"/


<meta-data


android:name="com.Google.android.maps.v2.API_KEY"


android:value="AlzaSyCCOsnRs6BuQpHgKgDTlafvIwjopSuurto" />


</application>


</manifest>


d. Menambahkan Library Google Play Service

Untuk membuat aplikasi dengan API Google Maps akan membutuhkan Google Play Service sebagai library dalam project. Aplikasi ini bisa dibuka melalui Android SDK Manager lewat Eclipse ataupun pada directory tempat instalasinya. Arahkan pada pilihan menu EXTRAS, pilih Google Play Services. Jika melakukan upgrade ADT versi terbaru maka tampak 2 tipe Google play services, yaitu Google Play Service for Froyo dan Google Play Services. Google Play services For Froyo bisa di-install jika aplikasi yang dibangun ditujukan untuk froyo, sedang Google Play Service digunakan untuk Android versi Ginger Bread ke atas. Setelah itu dilanjutkan dengan menambah ke dalam project yang diawali dengan meng-import library Google Play services yang telah diinstall sebelumnya. Pilih pada menu File → Import → Existing Android Code Into Workspace, pilih direktori ADT → SDK → extras Google Google_play_services →libproject→ Google-play-services-lib. Klik kanan pada project yang telah dibuat sebelumnya dengan memilih properties → Android. Klik Add pada tab group library untuk menambahkan project tersebut sebagai Library.


e. Mendapatkan API KEY

API Key merupakan kode unik yang digunakan untuk mengakses aplikasi dari penyedia API. Untuk mendapatkan API terlebih dahulu harus memiliki akun Google. Langkah-langkah untuk mendapatkan API Google adalah sebagai berikut.

1) Akses Laman Google API Console Jika sudah memiliki project sebelumnya maka akan ditampilkan list beberapa project yang sudah dibuat sebelumnya atau dilanjutkan pada laman baru dengan cara klik menu APIs & auth > APIs sehingga akan ditampilkan pilihan API yang bisa digunakan. Misalnya menggunakan "Google Maps Android API v2", untuk mengaktifkan ub ubah status dari OFF menjadi ON.


2) Setelah selesai, akses menu Credentials yang berada di bawah menu APIs. Pada bagian ini akan membuat API key dengan cara klik pada Create New Key → Android Key. Kotak dialog akan dimunculkan untuk menempatkan fingerprints dari project yang dibuat.


Penggunaan fitur Eclipse (ADT) lebih memudahkan untuk mendapatkannya. Akses menu Window→ Preferences → Android Build. Selanjutnya lakukan copy paste SHA1 pada window ke dialog. Secara otomatis API key akan ditampilkan.



f. Menampilkan Peta

Guna menampilkan peta sederhana dalam aplikasi yang dibangun dengan membuat sebuah layout sederhana yang diletakkan pada folder res dalam project. Misalkan saja activity_main.xml, dengan mengubah xml layout menjadi sebagai berikut.


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/ android"


xmlns:tools="http://schemas.android.com/tools"


android:layout_width="match_parent"


android:layout_height="match_parent"


android:paddingBottom="@dimen/activity_vertical_margin"


android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin"


android:padding Top="@dimen/activity_vertical_margin"


tools:context="com.elfarqy.androidmaps.MainActivity$PlaceholderFragment


">


<fragment


android:id="@+id/map"


android:name="com.Google.android.gms.maps.MapFragment"


android:layout_width="match_parent"


android:layout_height="match_parent" />


</RelativeLayout>


Jika berhasil maka map akan berhasil ditampilkan pada aplikasi yang dibangun sebagai berikut.


B. Memodifikasi Aplikasi Mobile Menggunakan Library


Di masa sekarang, pengembangan aplikasi untuk perangkat komputasi sedang berkembang. Apalagi dengan kemajuan teknologi yang makin pesat, di antaranya perkembangan teknologi mobile dan perangkat smartphone. Karena perkembangan teknologi tersebut berpengaruh pada banyaknya developer yang mengembangkan aplikasi-aplikasi baru. Aplikasi-aplikasi itu tidak hanya ditujukan untuk perangkat desktop tetapi juga perangkat mobile. Pemrograman aplikasi bergerak tidak banyak berbeda dengan pemrograman konvensional pada PC. Dalam pemrograman aplikasi bergerak berbagai aspek teknis perangkat lebih menonjol karena memiliki banyak keterbatasan dibandingkan komputer konvensional atau PC. Aspek karakteristik dari perangkat bergerak sering memengaruhi arsitektur dan implementasi dari aplikasi tersebut. Beberapa alasan memodifikasi Android di antaranya untuk me- lakukan test, membuat aplikasi bisa berjalan lagi, dan untuk mencurangi game. Untuk pentesting, modifikasi yang sering perlu dilakukan adalah mematikan certificate pinning, mematikan root checking, dan menambahkan tracing untuk melihat logika aplikasi lebih jelas.


1. Konsep Konektivitas antara Aplikasi Web dengan Aplikasi Perangkat Bergerak


Aplikasi berbasis mobile ini sedikit berbeda dengan aplikasi web. Aplikasi berbasis mobile umumnya ditujukan untuk perangkat mobile seperti smartphone. Karena bentuk smartphone yang lebih kecil daripada desktop, otomatis tampilan pada aplikasi mobile disesuaikan dengan kebutuhan dengan user smartphone. Karena itu, pengembangan aplikasinya juga berbeda. Pada dasarnya jenis aplikasi perangkat bergerak dikategorikan menjadi empat, yaitu aplikasi yang 100% gratis, aplikasi gratis dengan tayangan iklan di dalamnya. Aplikasi gratis dengan pembelian fitur di dalamnya, dan aplikasi berbayar yang memang harus dibeli sebelum menggunakannya.


Aplikasi berbasis mobile sendiri terbagi menjadi aplikasi berbasis mobile web dan native apps.


a. Aplikasi Berbasis Mobile Web

Aplikasi berbasis mobile web umumnya adalah tampilan aplikasi web dalam bentuk mobile. Untuk menggunakan aplikasi ini, user dapat mengakses web browser di perangkat smartphone. Sebelum era mobile populer, banyak situs yang tampil di perangkat mobile akan tampil seperti halnya tampilan web di desktop. Di masa sekarang, sudah banyak aplikasi berbasis web yang bisa menyesuaikan sendiri tampilan web tergantung perangkat yang digunakan. Hal ini biasa disebut sebagai tampilan situs mobile friendly.


b. Native Apps

Native apps ini biasanya didistribusikan di toko aplikasi semacam Google Play untuk Android atau Apple Store untuk iOS. Native apps adalah istilah untuk aplikasi mobile yang fungsinya sedikit mirip dengan aplikasi desktop yaitu user perlu meng- instal terlebih dulu aplikasi tersebut sebelum menggunakannya, Guna menggunakan aplikasi ini, ada proses persetujuan penggunaan aplikasi. Misalnya memperbolehkan aplikasi untuk mengakses fungsi tertentu di smartphone. Bahkan ada aplikasi yang meminta izin untuk memperbolehkan akses membaca data kontak telepon dan identitas perangkat (device id). Saat ini, native apps memang sedang naik daun. Hal ini didasarkan karena penggunaan native apps lebih mudah dan aksesnya lebih cepat meskipun kadang-kadang membuat smartphone user penuh dengan banyak aplikasi. Ada juga yang beranggapan pengembangan aplikasi berbasis Android atau iOS lebih unggul dibandingkan aplikasi berbasis web.


XPosed adalah sebuah framework open

source yang memungkinkan kita membuat modul untuk memodifikasi sistem dan apli- kasi Android yang ditulis menggunakan Java. Dari sudut pandang programming, framework menarik karena menambahkan dan menginter- sepsi kode pada aplikasi closed source Android, sedikit mirip Aspect Oriented Programming. Prosedur pendekatan XPosed framework yang lebih dinamik adalah Frida dalam memanipu- lasi berbagai hal secara dinamis menggunakan JavaScript, termasuk juga mengganti beberapa kode native. Frida bisa dijalankan pada HP yang sudah di-root, dengan ini signature APK yang tidak berubah. Kelemahan Frida dibandingkan XPosed adalah perubahan yang dilakukannya tidak permanen. Jika ingin menyebarkan modi- fikasi tanpa menyertakan aplikasi asli karena masalah hak cipta maka XPosed bisa digunakan dengan baik, bahkan sangat cocok jika ingin membuat perubahan semi permanen. Ketika terdapat sistem operasi yang baru, biasanya XPosed dan Frida tidak langsung bisa dipakai jika ada perubahan mendasar di sistem operasi, sehingga tetap perlu tahu cara modifikasi manual. XPosed bekerja dengan memodifi- kasi runtime Android (Dalvik/Art) sehingga untuk memanggil kode custom di awal/ akhir sebuah method apa pun. Untuk memakai XPosed, yang harus dilakukan adalah meng-install recovery alternatif (CWM, TWRP, dan sebagainya) serta meng-install framework-nya. Di samping itu juga perlu meng-install XPosed installer yang akan me-manage modul mana saja yang aktif.

Supaya bisa mengintersepsi dengan mengembalikan agar is Valid License selalu menjadi TRUE dilakukan dengan cara memodifikasinya. Dalam method checkRoot, untuk melakukan pemeriksaan, device di-root oleh user dan cara memeriksanya meng gunakan XML berisi daftar command dan package yang harus diperiksa bisa mengganti parameter input XML menjadi XML kosong. Kode-kode yang digunakan untuk mem- patch agar isValidLicense selalu mengembalikan true adalah sebagai berikut.

import de.robv.android.xposed.IXposedHookLoadPackage; import de.robv.android.xposed.XC_MethodHook;

import de.robv.android.xposed.XposedBridge;

import de.robv.android.xposed.callbacks.XC_LoadPackage. LoadPackageParam;

import static de.robv.android.xposed.XposedHelpers.findAndHookMethod; IXposedHookLoadPackage {

public class JoeHackXposed implements private void hackLicense(final LoadPackageParam Ipparam) {

findAndHookMethod("es.thoriq.examples.LicenseChecker", Ipparam. classLoader,

"isValidLicense",

String.class,

new XC_MethodHook() {

@Override

protected void beforeHookedMethod(MethodHookParam param) throws Throwable {

}

@Override

protected void afterHookedMethod(MethodHookParam param) throws Throwable (

param.setResult(true);

}

});

}

public void handleLoadPackage(final LoadPackageParam Ipparam) throws Throwable { XposedBridge.log("Loaded app: " + Ipparam.packageName); if (lpparam.packageName.equals("es.thoriq.examples")) { hackLicense(Ipparam);

}

}

}


Jika ingin mengubah detail sebuah method dengan Xposed dengan cara menulis ulang method itu, dan di beforeHookedMethod memberitahu XPosed framework agar tidak

memanggil method aslinya. Kebanyakan modul di repository XPosed berguna mengatasi masalah spesifik yang dimiliki oleh user. Sebagai programmer, modifikasi ini bisa dilakukan meskipun tidak memiliki source code aplikasinya. Bagian tersulit adalah mencari tahu bagian yang perlu di-hook untuk mengimplementasikan fungsionalitas tertentu. Modifikasi dengan XPosed framework melengkapi hack android yang lain. Rooting aplikasi tidak cukup untuk mengubah internal program. Modifikasi dan compile ROM sendiri bisa mengubah hal-hal yang di luar kemampuan XPosed tetapi tidak bisa mengubah aplikasi. Modifikasi aplikasi dengan cara patching manual bisa dilakukan.


2. Prosedur Koneksi antara Aplikasi Web dengan Aplikasi Perangkat Bergerak

Konsep dasar koneksi HP android dengan PC/Laptop menggunakan aplikasi smartcam. Smartcam adalah aplikasi yang dapat membantu dalam memanfaatkan kamera ponsel pintar dengan desktop. Cara koneksinya hanya membutuhkan konek- si WIFI/konektivitas bluetooth pada desktop dan menggunakan aplikasi SmartCam. Pada langkah pertama yang dilakukan adalah meng-install Smartcam untuk android pada ponsel android dan kemudian Install Smartcam untuk PC/komputer. Setelah semua instalasi dengan benar, selanjutnya dihubungkan ponsel dengan PC melalui jaringan WIFI atau bluetooth.


Pengetahuan tentang API sangat dibutuhkan ketika developer aplikasi menemui hambatan dan problem yang menyebabkan aplikasi tidak berjalan sebagaimana mestinya. Mengembangkan sebuah aplikasi berbasis android membutuhkan dasar pengetahuan tentang API dan basic OOP (native Java). Di dalam project android yang dibuat menggunakan Eclipse terdapat sebuah file bernama AndroidManifest. xml. File memiliki fungsi layaknya gudang informasi bagi aplikasi android itu sendiri. Informasi di dalam Manifest tersebut memiliki beberapa kegunaan di antaranya memberi akses permission untuk fitur pada aplikasi, menginformasikan set SDK yang digunakan dalam aplikasi, merubah kode versi aplikasi saat melakukan update aplikasi, inisialisasi dukungan layar perangkat, menerjemahkan string atau label ke dalam aplikasi yang diperlukan seperti string icon launcher/app name, dan lain-lain. Pada intinya, konfigurasi AndroidManifest sangat dibutuhkan sebagai penggambaran dalam paket aplikasi Android.


a. Perubahan Kode Versi Aplikasi


Di dalam file AndroidManifest, terdapat beberapa baris string yang menunjukkan informasi versi dari kode aplikasi yang dibuat. Beberapa kode versi di dalam AndroidManifest adalah sebagai berikut.


<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.my.application"

android:versionCode="2"

android:versionName="2.0" >

String android:version Code menunjukkan kode versi aplikasi untuk mendefinisi- kan penggantian kode yang dilakukan oleh developer (pengembang). Dan android: versionName adalah string versi yang akan ditampilkan pada user aplikasi. Jadi per- bedaan mendasar dari kedua string tersebut terletak pada objek tujuan, di mana versionCode untuk pengembang dan versionName untuk ditampilkan kepada user. Hal yang perlu diperhatikan pada string di atas adalah merubah versionCode dan versionName dalam melakukan update aplikasi di Google Play. Jika tidak mengganti versi-versi tersebut, Google Play tidak akan menerima versi terbaru dari aplikasi yang akan diupload.


b. Set Versi SDK


Elemen/string ini merupakan representasi dari versi SDK yang dipakai untuk membuild aplikasi android. Contoh kode versi SDK yang terletak di dalam string <uses-sdk /> adalah sebagai berikut.

<uses-sdk android:minSdkVersion="4" android:targetSdkVersion="15" />


Eclipse akan membaca string manifest di atas bahwa aplikasi yang dibuat minimal memiliki target SDK versi 4 hingga versi 15 yang akan berguna pada saat developer ingin menambahkan sebuah fitur-fitur tertentu yang telah didukung versi SDK tersebut. Penggunaan minimal dan maksimal target memiliki keuntungan di sisi user yang masih menggunakan perangkat Android versi lama. SDK versi terkecil memungkinkan mendukung semua perangkat.


c. Set Permission


Jika aplikasi yang diinginkan dapat menyokong fitur native tertentu device Android, dapat dilakukan dengan men-setting pengaturan permission pada AndroidManifest secara benar. Bentuk string permission yang dapat di-setting adalah sebagai berikut.

<uses-permission android:name="android.permission. VIBRATE" />

<uses-permission android:name="android.permission.INTERNET" />

<uses-permission android:name="android.permission.RECORD_AUDIO" />


Perintah <uses-permission /> bermanfaat saat aplikasi yang dikembangkan membutuhkan fitur asli perangkat Android. Misalnya dengan memasukkan per- mission untuk vibrasi perangkat, dukungan internet, dan recording audio. Permission tersebut mutlak dimasukkan dalam file AndroidManifest agar aplikasi berjalan sesuai perancangan.


d. Set Dukungan Layar


File AndroidManifest bisa juga melakukan pengaturan dukungan mode layar dan ukuran layar aplikasi. Bentuk setting untuk besar ukuran layar yang menggunakan elemen <supports-screens/> adalah sebagai berikut.


<supports-screens

android:largeScreens="true"

android:normalScreens="true"

android:smallScreens="true"

android:reSizeable="true"

android:anyDensity="true"

/>


Kode di atas memperbolehkan aplikasi berjalan pada perangkat android yang memililiki layar kecil (small) hingga besar (large). Sedangkan android:reSizeable bernilai "true" berfungsi agar aplikasi dapat menyesuaikan pada semua kondisi besar/kecilnya layar perangkat. Sedangkan string android:anyDensity memiliki fungsi yang bermanfaat pada saat aplikasi berjalan di berbagai layar dengan resolusi tinggi maupun rendah.


Codingan game tetris tahap ke -4 modifikasi:

<!doctype html>

<html>

<head>

  <title>Basic Julia Tetris HTML Game</title>

  <meta charset="UTF-8">

  <style>

  html, body {

    height: 100%;

    margin: 0;

  }

  body {

    background: rgb(182, 7, 226);

    display: flex;

    align-items: center;

    justify-content: center;

  }

  canvas {

    border: 1px solid rgb(0, 0, 0);

  }

  </style>

</head>

<body>

<canvas width="320" height="635" id="game">

</canvas>

<script>

// https://tetris.fandom.com/wiki/Tetris_Guideline

// get a random integer between the range of [min,max]

// @see https://stackoverflow.com/a/1527820/2124254

function getRandomInt(min, max) {

  min = Math.ceil(min);

  max = Math.floor(max);

  return Math.floor(Math.random() * (max - min + 1)) + min;

}

// generate a new tetromino sequence

// @see https://tetris.fandom.com/wiki/Random_Generator

function generateSequence() {

  const sequence = ['I', 'J', 'L', 'O', 'C', 'T', 'U'];

  while (sequence.length) {

    const rand = getRandomInt(0, sequence.length - 1);

    const name = sequence.splice(rand, 1)[0];

    tetrominoSequence.push(name);

  }

}

// get the next tetromino in the sequence

function getNextTetromino() {

  if (tetrominoSequence.length === 0) {

    generateSequence();

  }

  const name = tetrominoSequence.pop();

  const matrix = tetrominos[name];

  // I and O start centered, all others start in left-middle

  const col = playfield[0].length / 2 - Math.ceil(matrix[0].length / 2);

  // I starts on row 21 (-1), all others start on row 22 (-2)

  const row = name === 'I' ? -1 : -2;

  return {

    name: name, // name of the piece (L, O, etc.)

    matrix: matrix, // the current rotation matrix

    row: row, // current row (starts offscreen)

    col: col // current col

  };

}

// rotate an NxN matrix 90deg

// @see https://codereview.stackexchange.com/a/186834

function rotate(matrix) {

  const N = matrix.length - 1;

  const result = matrix.map((row, i) =>

    row.map((val, j) => matrix[N - j][i])

  );

  return result;

}

// check to see if the new matrix/row/col is valid

function isValidMove(matrix, cellRow, cellCol) {

  for (let row = 0; row < matrix.length; row++) {

    for (let col = 0; col < matrix[row].length; col++) {

      if (matrix[row][col] && (

          // outside the game bounds

          cellCol + col < 0 ||

          cellCol + col >= playfield[0].length ||

          cellRow + row >= playfield.length ||

          // collides with another piece

          playfield[cellRow + row][cellCol + col])

        ) {

        return false;

      }

    }

  }

  return true;

}

// place the tetromino on the playfield

function placeTetromino() {

  for (let row = 0; row < tetromino.matrix.length; row++) {

    for (let col = 0; col < tetromino.matrix[row].length; col++) {

      if (tetromino.matrix[row][col]) {

        // game over if piece has any part offscreen

        if (tetromino.row + row < 0) {

          return showGameOver();

        }

        playfield[tetromino.row + row][tetromino.col + col] = tetromino.name;

      }

    }

  }

  // check for line clears starting from the bottom and working our way up

  for (let row = playfield.length - 1; row >= 0; ) {

    if (playfield[row].every(cell => !!cell)) {

      // drop every row above this one

      for (let r = row; r >= 0; r--) {

        for (let c = 0; c < playfield[r].length; c++) {

          playfield[r][c] = playfield[r-1][c];

        }

      }

    }

    else {

      row--;

    }

  }

  tetromino = getNextTetromino();

}

// show the game over screen

function showGameover() {

  cancelAnimationFrame(rAF);

  gameOver = true;

  context.fillStyle = 'black';

  context.globalAlpha = 0.75;

  context.fillRect(0, canvas.height / 2 - 30, canvas.width, 60);

  context.globalAlpha = 1;

  context.fillStyle = 'white';

  context.font = '36px monospace';

  context.textAlign = 'center';

  context.textBaseline = 'middle';

  context.fillText('GAME OVER!', canvas.width / 2, canvas.height / 2);

}

const canvas = document.getElementById('game');

const context = canvas.getContext('2d');

const grid = 32;

const tetrominoSequence = [];

// keep track of what is in every cell of the game using a 2d array

// tetris playfield is 10x20, with a few rows offscreen

const playfield = [];

// populate the empty state

for (let row = -2; row < 20; row++) {

  playfield[row] = [];

  for (let col = 0; col < 10; col++) {

    playfield[row][col] = 0;

  }

}

// how to draw each tetromino

// @see https://tetris.fandom.com/wiki/SRS

const tetrominos = {

  'I': [

    [0,0,0,0],


    [1,1,1,1],


    [0,0,0,0],


    [0,0,0,0]


  ],


  'J': [


    [1,0,0],


    [1,1,1],


    [0,0,0],


  ],


  'L': [


    [0,0,1],


    [1,1,1],


    [0,0,0],


  ],


  'O': [


    [1,1],


    [1,1],


  ],


  's': [


    [0,1,1],


    [1,1,0],


    [0,0,0],


  ],


  'Z': [


    [1,1,0],


    [0,1,1],


    [0,0,0],


  ],


  'T': [


    [0,1,0],


    [1,1,1],


    [0,0,0],


  ]

};

// color of each tetromino

const colors = {

  'I': 'maroon',

  'O': 'maroon',

  'T': 'maroon',

  'S': 'maroon',

  'Z': 'maroon',

  'J': 'maroon',

  'L': 'maroon'

};

let count = 0;

let tetromino = getNextTetromino();

let rAF = null; // keep track of the animation frame so we can cancel it

let gameOver = false;

// game loop

function loop() {

  rAF = requestAnimationFrame(loop);

  context.clearRect(0,0,canvas.width,canvas.height);

  // draw the playfield

  for (let row = 0; row < 20; row++) {

    for (let col = 0; col < 10; col++) {

      if (playfield[row][col]) {

        const name = playfield[row][col];

        context.fillStyle = colors[name];

        // drawing 1 px smaller than the grid creates a grid effect

        context.fillRect(col * grid, row * grid, grid-1, grid-1);

      }

    }

  }

  // draw the active tetromino

  if (tetromino) {

    // tetromino falls every 35 frames

    if (++count > 35) {

      tetromino.row++;

      count = 0;

      // place piece if it runs into anything

      if (!isValidMove(tetromino.matrix, tetromino.row, tetromino.col)) {

        tetromino.row--;

        placeTetromino();

      }

    }

    context.fillStyle = colors[tetromino.name];

    for (let row = 0; row < tetromino.matrix.length; row++) {

      for (let col = 0; col < tetromino.matrix[row].length; col++) {

        if (tetromino.matrix[row][col]) {

          // drawing 1 px smaller than the grid creates a grid effect

          context.fillRect((tetromino.col + col) * grid, (tetromino.row + row) * grid, grid-1, grid-1);

        }

      }

    }

  }

}

// listen to keyboard events to move the active tetromino

document.addEventListener('keydown', function(e) {

  if (gameOver) return;

  // left and right arrow keys (move)

  if (e.which === 37 || e.which === 39) {

    const col = e.which === 37

    ?tetromino.col - 1 

      : tetromino.col + 1;

    if (isValidMove(tetromino.matrix, tetromino.row, col)) {

      tetromino.col = col;

    }

  }

  // up arrow key (rotate)

  if (e.which === 38) {

    const matrix = rotate(tetromino.matrix);

    if (isValidMove(matrix, tetromino.row, tetromino.col)) {

      tetromino.matrix = matrix;

    }

  }

  // down arrow key (drop)

  if(e.which === 40) {

    const row = tetromino.row + 1;

    if (!isValidMove(tetromino.matrix, row, tetromino.col)) {

      tetromino.row = row - 1;

      placeTetromino();

      return;

    }


    tetromino.row = row;


  }


});


// start the game

rAF = requestAnimationFrame(loop);


</script>

</body>

</html>

Tidak ada komentar:

Posting Komentar

Ulangan Akhir Bab 5

 A. Pilihlah salah satu jawaban yang tepat.  1. Jenis usaha yang memiliki uang kas sebagai modal dan biaya produksi dengan besaran tidak leb...