Showing posts with label android. Show all posts
Showing posts with label android. Show all posts

Jan 14, 2021

Troubleshooting: Could not initialize class org.codehaus.groovy.reflection.ReflectionCache

I am a Ionic Capacitor user, I didn’t know since when my android build keep failing and no clue what’s the cause.


And I keep getting these errors when I run “npx cap add android”:

	
Syncing GradleError running gradle sync Starting a Gradle Daemon, 1 stopped Daemon could not be reused, use --status for details

java.lang.NoClassDefFoundError: Could not initialize class org.codehaus.groovy.vmplugin.v7.Java7

… #skipped verbose error messages

FAILURE: Build failed with an exception.


* What went wrong:
Could not initialize class org.codehaus.groovy.reflection.ReflectionCache


* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org
BUILD FAILED in 21s

Unable to infer default Android SDK settings. This is fine, just run npx cap open android and import and sync gradle manually
	





The Solution

Firstly, you'll to know which java version is your android studio is using, find the info in "About Android Studio". 





Set environment variable to point JAVA_HOME to the path where openjdk version of "1.8.0_242-release” (or embedded jdk inside Android Studio app folder) located. On Mac, it's usually 

/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home


MacOS (Android Studio 4.1.1):

export JAVA_HOME="/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home"


jenv User:

You can add Android Studio embedded openjdk path to your jenv and then switch to your prefered java version with jenv local VERSION_NO for local or  jenv global VERSION_NO for system wide.
jenv add "/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home"

Window:

Add/update environment variable JAVA_HOME and point it to path where the correct version of openjdk extracted.

Jul 24, 2020

Troubleshooting Custom Capacitor Plugin: No such module 'PushNotifications'

As a Capacitor hybrid app developer, default plugins offered by Capacitor can be not enough to achieve what we want for our project.

For beginner like me, who hope to create a simple custom plugin, set aside Javascript related code, it can be a tough experience as we have to learn and put into practise for both Android and iOS build.

Building a custom plugin for Capacitor (Ionic)

Fortunately, Capacitor has built-in API we could use to build any custom plugin.

No such module 'PushNotifications' (iOS)

On one of my custom plugin, it has dependency on Pusher's client iOS SDK which is imported through cocoapod. Running app "build" on xcode on this plugin is successful.

On my ionic app project folder, when import the created custom plugin causes error, and I get 
"No such module 'PushNotifications'
for importing the custom plugin. Which it's weird as I've checked and certain PushNotifications plugin installed in pods folder on both the actual app project and in the custom plugin.

When I navigate inside xcode Pods project, I'm able to see PushNotifications library correctly placed under pods folder.



Solution:

1. In the Capacitor custom plugin folder, find the .podspec file (usually located at root folder of your Plugin project), and add s.xcconfig to your podspec file, it's added to tell xcode about where to look the PushNotifications framework required by this plugin in your main project.
	
		
  require 'json'

  package = JSON.parse(File.read(File.join(__dir__, 'package.json')))

  Pod::Spec.new do |s|
    s.name = 'CapacitorPusherBeams'
    s.version = package['version']
    s.summary = package['description']
    s.license = package['license']
    s.homepage = package['repository']['url']
    s.author = package['author']
    s.source = { :git => package['repository']['url'], :tag => s.version.to_s }
    s.source_files = 'ios/Plugin/**/*.{swift,h,m,c,cc,mm,cpp}'
    s.ios.deployment_target  = '11.0'
    s.dependency 'Capacitor'
    s.swift_version = '5.0'
    s.xcconfig = { 'FRAMEWORK_SEARCH_PATHS' => "${PODS_CONFIGURATION_BUILD_DIR}/PushNotifications" }
  end

	

2. Or, alternatively, you can add the PushNotification framework path manually as below (you'll have to do this every time when the plugin get updated or after you run npx cap update)
Steps
  1. Go to Pods project's Build settings, find "Framework Search Paths"
  2. Select your affected plugin (by the missing module error mentioned above)
  3. Add the missing path to both Debug and Release as needed.

Apr 11, 2019

Troubleshooting Android Flashing Custom ROM / Recovery

Troubleshooting

Cannot boot into TWRP without rooting

The sentence above is somewhat misleading, "without rooting" doesn't mean "no flash", I said so because I was inexperienced, so I keep trying to boot without flashing. And I've stuck in the retrying loop until I gave up several for 2 weeks of countless attempts.
I would rather name the title to "Flashing TWRP without rooting" before anyone else get stuck in the hopeless loop again.

In order to boot into custom recovery, you cannot skip flashing the custom recovery first. Lesson learned,
No One Can Boot Into Twrp Without Flashing With TWRP Recovery first!
As a Asus device user, I did trial and error this many time until I finally learnt and come to a conclusion "we can't boot into custom recovery without flashing them beforehand".

Let me summarise the general steps after I've gone through wide amount of online articles:
  1. adb reboot bootloader (boot into fastboot mode)
  2. fastboot devices (to make sure your device is connected)
  3. fastboot flash recovery twrp.img
  4. fastboot reboot (or press and hold Volume button to boot into TWRP recovery mode)
What I've learned from this:
- Flashing TWRP will still unlock the bootloader in your device
- for Asus, flashing TWRP custom recovery will also root your device (void warranty)

I haven't seen any of my trial and error that won't root my device after flashing TWRP recovery.

You can check your device info by running command below:
  fastboot oem device-info
The Root status will show as "Rooted"

Endless re-booting bootloader/bootup screen

I encounter this problem after flashed an incorrect recovery into my device.
Potential cause: Usually, you'll run into this problem after running the command below in fashboot mode (with a unsuitable recovery file):

  fastboot flash recovery example-recovery-filename.img

Solution

To resolve this, you'll have to find the correct version of recovery rom that fits your device. If you spent hours looking for one and still no luck getting one, then you may need to consider a more generally owned by the developer community or learn to compile a custom recovery by yourself. TWRP itself is a open source project, if you need something not existence

For TWRP custom recovery, please visit: https://twrp.me/Devices/
For Asus, I usually have to keep googling at their dedicated Asus Forum - Zentalk for specific/older device's discussion.

For Asus device, if you run into unrecoverable flashing issue (bricked), you can always get back the stock (official) version of ROM/firmware from Asus official support website and flash your device back into the original device firmware.

* note: avoid losing all your data, always backup your device before flashing anything

Booting into Fastboot/Recovery Mode

1) How do I get into fastboot mode?
Run the command below in order to boot into fastboot mode from "normal UI" screen (the UI show up for normal daily use made for general user.):

  adb reboot fastboot

You can boot into fastboot mode by restart/power on your phone by holding Volume Up button (for Asus Android phone).
Steps:
  1. From power off mode, press and hold volume buttons
    1. volume up - for fastboot mode
    2. volume down - for recovery mode
  2. Keep on holding the volume button after device is powered on until the expected screen mode is correctly shown.
*note: Booting into fastboot/recovery mode doesn't render your warranty void.

2) "adb: command not found", what is missing?
Which command unavailable in your system, you can't proceed any further.
To install required tools, you need run the command above using:

  • (Window) adb.exe (ROM flashing kits)
  • (Unix) For Unix system, 2 choices: 
    • Install full official android development tools Android Studio (follow their installation tutorials), or 
    • Visit Android Studio (same url as above), scroll until Command Line Tools only section and install the only the command line tools, which will install required general tools like adb (Android Debug Bridge) and fastboot tools to access to your android devices through USB cable.

Some useful articles that worth your time (for understanding about flashing custom recovery):
Discover hidden fastboot commands
Guide to customise Android device
Install TWRP recovery on Android (no root)

Aug 27, 2015

URL Scheme for Android in Cordova

My project's spec:
- Onsen UI
- Cordova

Simply following the step in Custom URL scheme PhoneGap Plugin would get your android or ios app ready with custom URL scheme.

But testing it the wrong way cause my hours to figure what is wrong with my configuration.

So, in the end, I found out testing URL scheme in android is different with how we test in ios.

In ios device,  ipod as example,
we just simply use browser with "myapp://" would do all job.

Which it is different in android,
so you'll have to utilise easyhyperlinks.com to initiate the scheme correctly,
because in android, it automatically prefix url with "http://" in browsers.

You can refer to this Using Custom URL Schemes In Your Ionic Framework App and see how he tested the scheme in the easy way.

Reference:
github repo: Custom URL scheme PhoneGap Plugin
video tutorial: Using Custom URL Schemes In Your Ionic Framework App
testing tool for android: easyhyperlinks.com

Aug 25, 2015

Cordova, store image from data URL or base64

In order to get image resized and store the image right away, we need some workaround to achieve this result.

First, resize the image into thumbnail-like size
2nd, store the image into targeted directory

This is achievable with Phonegap-image-resizer


$window.imageResizer.resizeImage(function(resizedImage) {

  // Store image into local
  $window.imageResizer.storeImage(function(response) { // cache
    var filePath = response.filename,
        pathOnly = filePath.substring(0, sourceFile.lastIndexOf('/')) + '/',
        filename = filePath.split('/').pop().replace(/\#(.*?)$/, '').replace(/\?(.*?)$/, '');


    // store file into targeted location here with 
    // cordova official File plugin
    $cordovaFile.moveFile(pathOnly, filename, cordova.file.dataDirectory).then(function(success) {
      console.log(success);
    }, function(error) {
      console.log(errir);
    });


  }, function(error) {
    return error;

  }, resizedImage.imageData, {
    imageDataType: ImageResizer.IMAGE_DATA_TYPE_BASE64,
    format: 'jpg',
    filename: // new name,
    directory: // location to store,
    quality: 80
  });

}, function(error) {
  return error;

}, photo.url, 0.2, 0.2, {
  imageDataType: ImageResizer.IMAGE_DATA_TYPE_URL,
  resizeType: ImageResizer.RESIZE_TYPE_FACTOR,
  format: 'jpg'
});


Two parts here:


TL;DR

1st step, $window.imageResizer.resizeImage will resize the image
2nd step, $window.imageResizer.storeImage store image

Cursory go through resizeImage.js to better understand how to utilise the code.

Reference: Converting Large Images to Base64Strings in Ionic Framework

Aug 5, 2015

Default Hash key of Android apk

I found the solution from this,
every IDE will have the default keystore password.

Like the case when I build my apk (android app package),
it will generated with the default hash key.

Generating an APK in the Debug Mode

  • Keystore name: debug.keystore
  • Keystore password: android
  • Key alias: androiddebugkey
  • Key password: android
  • CN (common name): CN=Android Debug,O=Android,C=US
In order to get the hash key with the keytool command, 
you need the "Key alias" and "Key password" values.


keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore | openssl sha1 -binary | openssl base64
(command for mac)