Utilisation du NDK : Lecture & gestion des PDF (@TAUG, Juin 2014)5. Pdf et Android SDK
1/ Laisser la main à l’OS
File file = new File("/sdcard/files/mypdf.pdf");
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
Uri uri = Uri.fromFile(file);
intent.setDataAndType(uri, "application/pdf");
6. Pdf et QuickOffice
2/ Quickoffice + webview
String myUrl = "https://drive.google.com/viewer?url=" + myPdfFile;
mWebview = (WebView) findViewById(R.id.webview);
mWebview.getSettings().setJavaScriptEnabled(true);
mWebview.loadUrl(myUrl);
8. Pdf et Android SDK
3/ Faire son propre rendu
> Bibliothèque Java : qoppa, IText, PdfJet, PSPDFkit
> Bibliothèque JNI : muPdf, Android Pdf Viewer (APV)
10. NDK : Native Developement Kit
Qu’est ce que le NDK ?
https://developer.android.com/tools/sdk/ndk/
11. NDK : Usage
JNIEXPORT jint JNICALL com_myndklib_myNdkFunction
(JNIEnv * env, jobject pThis, jstring jParam) {
return 2+2;
}
public class myClass {
static { System.loadLibrary("myndklib"); }
private native int myNdkFunction(String param); // => 4
}
12. NDK : Avantages / Contraintes
Avantages
- Performances++
- Plus de mémoire (heap) disponible
- Cross-plaform
- Sécurité
- Utilisation de bibliothèque C
Contraintes
- Langage : C/C++
- Peu d’API : Interfaces--
- Dépendant de l’architecture CPU
- Pas d’outil d’obfuscation
13. SDK : Taille mémoire
Heap Sizes :
- Galaxy S3 : 256Mo
- Galaxy Tab : 64 Mb
- HTC Wildfire : 16 Mo
/system/build.prop
14. NDK dans le SDK
ex: Allocation de Bitmap
=> bibliothèques systèmes dans /system/lib
// File : android.graphics.Bitmap.java:1566
private static native Bitmap nativeCreate(int[] colors, int offset, int stride, int
width, int height, int nativeConfig, boolean mutable);
private static native void nativeDestructor(int nativeBitmap);
private static native boolean nativeRecycle(int nativeBitmap);
16. Plus sur le NDK ?
-> Session du Paris AUG, Mars 2013
par Sylvain Ratabouil
http://youtu.be/K4TgkzpEEvM
18. Rendu PDF : MuPDF
- Developpé par Artifex Software depuis 2006
- Gratuit et open source
- Licence GNU GPL v3
https/code.google.com/p/mupdf/
19. MuPDF : Etape 1
Récupération des sources & third-party :
$ git clone git://git.ghostscript.com/mupdf.git
$ cd mupdf/
$ git submodule update --init
$ make generate
20. MuPDF : Etape 2
Compilation de la bibliothèque :
-> mupdf/platform/android/libs/armeabi-v7a/libmupdf.so
$ cd platform/android/
$ NDK_PATH/ndk-build
[armeabi-v7a] Install : libmupdf.so => libs/armeabi-v7a/libmupdf.so
22. MuPDF : Etape 3
Eclipse : intégration bibliothèque/projet externe
Android Studio (gradle > 0.7.2) :
/src/main/jniLibs /armeabi/myndklib.so
/armeabi-v7a/myndklib.so
/x86/myndklib.so
Changer le répertoire par défaut (build.gradle) :
sourceSets.main { jniLibs.srcDir 'src/main/myNDKlibs'}
23. MuPDF : Etape 4
Appel bibliothèque coté SDK :
Intent intent = new Intent(activity, MuPDFActivity.class);
Uri data_decoded = Uri.parse(myUrl); // ex: sdcard; internal storage;
ressources
intent.setAction(Intent.ACTION_VIEW);
intent.setData(data_decoded);
activity.startActivity(intent);
24. MuPdf : Etape 5 (finale)
Génération de l’executable :
$ ./gradlew assemble
26. Architecture CPU
Architectures : armv7, armeabi-v7a, mips, intel x86
> 1 exécutable par architecture
File : mupdf/platform/android/jni/Application.mk
APP_ABI := all
#APP_ABI := armeabi armeabi-v7a x86 mips
27. MuPdf : Options de compilation
Fonts CJK (China/Japan/Korea) :
// File : mupdf/platform/source/pdf/pdf-fontfile.c:17
#ifdef NOCJK
#define NOCJKFONT
#endif
…
#ifndef NOCJKFONT
#ifndef NOCJKFULL
#include "gen_font_cjk_full.h"
28. MuPdf : Options de compilation(2)
// File : mupdf/platform/android/jni/Core.mk:7
LOCAL_CFLAGS := -DNOCJK
ifeq ($(TARGET_ARCH),arm)
LOCAL_CFLAGS += -DARCH_ARM -DARCH_THUMB -
DARCH_ARM_CAN_LOAD_UNALIGNED
ifdef NDK_PROFILER
Ajout d’un flag ‘NOCJK’ :
30. MuPdf : immersive mode
// File : MuPDFActivity:485
if (android.os.Build.VERSION.SDK_INT >= 11){
mDocView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
| View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
| View.SYSTEM_UI_FLAG_IMMERSIVE); // kitkat
}
layout.addView(mDocView);
34. Accès fichiers sous Android
Fichiers distants (via web) = stockage :
Inclus dans executable (ex: res/raw) :
$ adb pull /data/com.package/files/myfile.pdf ./ // ou sdcard
$ adb pull /data/app/com.package.apk ./
$ tar -xvf com.package.apk
35. Sécurité : Chiffrage coté Java
Génération de la clé :
String seed = “myseed”;
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(seed.getBytes();
kgen.init(128, sr);
SecretKeySpec sKey = new SecretKeySpec(kgen.generateKey().getEncoded(),
"AES");
36. Sécurité : Chiffrage coté Java
Génération du vecteur d’initialisation (iv) :
byte[] iv = new byte[16];
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
random.nextBytes(iv);
37. Sécurité : Chiffrage coté Java
Chiffrage / Dechiffrage :
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec ivspec = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, sKey, ivspec); // ou DECRYPT_MODE
encryptedCount = cipher.update(data, 0, bytesRead, encryptedData);
38. Plus de sécurité
- Fichier PDF avec mot de passe :
- Chiffrage coté JNI
- SSL (+ vérification certificats)
MuPDFCore.authenticatePassword(“mypassword”);