Showing posts with label Android. Show all posts
Showing posts with label Android. Show all posts

Wednesday, March 19, 2025

Take Geospatial files on the go with the Shapefiler App

 Easily load and visualize multiple GeoJSON and Shapefiles with this powerful mapping tool. The app automatically assigns overlay colors, but you have full control over the styling—customize icons, colors, and opacity through the layer properties menu. Tap on polygons, lines, and markers to view detailed feature attributes. Quickly find specific locations with the built-in free text search, making navigation effortless. Whether you're a GIS professional or a mapping enthusiast, this app provides an intuitive way to explore spatial data on your device. 


Key features

Load multiple Geospatial files: Overlay GeoJSON and Shapefiles over a choice of base map tiles.

Integrated tabular and map views: Tap on a data table record to locate the corresponding feature on the map

Multiple coordinate reference systems: Source Geospatial GeoJSON and Shapefiles in various coordinate reference systems can be reprojected to the standard World Mercator projection for display.

Free text search: Easily search features by text and locate on the map. 

For more detailed information, visit https://dominoc925.blogspot.com/p/shapefiler-help.html

Download and try out the Shapefiler app from the following stores:

Get it on Google Play

Monday, November 27, 2023

How I fixed the Android Studio current target and jvm target compatibility error

I encountered the following compilation error in Android Studio of one of my Android project about current target JVM compatibility (or incompatibility), as shown in the screenshot message listing below:

 

Execution failed for task ':app:compileDebugKotlin'.
> 'compileDebugJavaWithJavac' task (current target is 1.8) and 'compileDebugKotlin' task (current target is 17) jvm target compatibility should be set to the same Java version.
  Consider using JVM toolchain: https://kotl.in/gradle/jvm/toolchain

* 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.

I managed to fix the problem by ensuring the source and target are compatible, i.e. having the same Java version.

To fix the issue:

  1. In Android Studio, select File | Project Structure.

    The Project Structure dialog box appears.


  2. Click Gradle Settings.

    The Gradle dialog box appears.


  3. In the Use Gradle from combo box, choose 'gradle-wrapper.properties' file.

  4. In the Gradle JDK combo box, choose jbr-17 JetBrains Runtime version 17.

  5. Click OK to close all dialog boxes.

  6. In Android Studio, open the app's build.gradle file in the editor.


  7. Within the android construct, add in the compileOptions as shown in the listing below.

android {
    compileSdk 33

// ...etc...

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_17
        targetCompatibility JavaVersion.VERSION_17
    }
}

From this point on, compiling the app should not throw upany  JVM target compatibility errors.

Monday, April 22, 2019

Migrating Android support library Renderscript code to AndroidX

Android is deprecating the Support compatibility libraries  and replacing them with the new AndroidX libraries. To aid in the migration of Android projects using the deprecated support libraries, Android Studio has a Refactor to AndroidX tool. I used that to migrate an old Android project and while it works for the most part, it did not manage to migrate the files using the support renderscript classes; I presume that is because the AndroidX namespace does not have the equivalent renderscript classes.

To complete the migration to AndroidX, I had to do the following by hand:

  1. In all the code files using the android.support.v8.renderscript.* classes, replace them to android.renderscript.* as shown below.

  2. In the app's build.gradle file, upgrade the renderscriptTargetApi level to 17 and turn off the renderscript support mode (renderscriptSupportModeEnabled to false) as shown below.


  3. Save all the files and rebuild the project.

    The project should manage to sync and build successfully.
Note: At the time of writing, Android can only compile android.renderscript.* classes into 32 bit *.bc files. This may be a problem in future as Google Play is moving to apks that support 64 bit files. 

Monday, April 15, 2019

Speed up Android Studio startup by disabling unnecessary plugins

Android Studio loads a relatively large number of plugins on start up. Depending on your workflow, some of them may not be needed. For instance, if you don't use Subversion as your source code repository, then the Subversion plugin may not need to be loaded especially if your machine is slow or RAM is limited.

To disable plugins, do the following:

  1. Start Android Studio.


  2. In the Configure drop down menu at the bottom right, choose Plugins.

    The Plugins dialog box appears.

  3. Scroll down the list and toggle off the unneeded plugins e.g. CVS Integration. Click OK.

    The Prompt appears.

  4. Click Restart.

    Android Studio is restarted without the disabled plugins.

Monday, August 13, 2018

How to find the cause of a lint error while generating a signed Android APK

Sometimes when generating a signed APK of an Android App from Android Studio, I would encounter a cryptic lint error message:

Lint found fatal errors while assembling a release target.

To proceed, either fix the issues identified by lint, or modify your build script as follows:
...
android {
    lintOptions {
        checkReleaseBuilds false
        // Or, if you prefer, you can continue to check for errors in release builds,
        // but continue the build even when errors are found:
        abortOnError false
    }
}
...




The message suggests to disable the lint checking but it would probably not be to your benefit to ignore the error.

After some digging around, I found that lint checking outputs a report which you can read to identify the source of the problem. The report can be found in the application's source build directory e.g. /your/Android/app/build/reports/ and named as lint-results-release-fatal.html




If you open up the report in a browser, the cause of the lint error can be easily seen. In this example, the reason for the compilation error is a missing language translation.
 

Monday, August 7, 2017

Android Studio Emulator: How I resolved a Google Maps SupportMapFragment GLThread exception

While attempting to open up a Google Maps SupportMapFragment in the Android Studio Emulator, the Activity crashed with the following error messages:

[ 08-07 00:50:44.423  3266: 3523 W/         ]
                                                                     Unrecognized GLES max version string in extensions: ANDROID_EMU_CHECKSUM_HELPER_v1 ANDROID_EMU_dma_v1 
08-07 00:50:44.429 3266-3523/com.dom925.volcamr.nz E/EGL_emulation: rcCreateContext returned 0
08-07 00:50:44.429 3266-3523/com.dom925.volcamr.nz E/EGL_emulation: tid 3523: eglCreateContext(1434): error 0x3003 (EGL_BAD_ALLOC)
                                                                    
                                                                    --------- beginning of crash
08-07 00:50:44.429 3266-3523/com.dom925.volcamr.nz E/AndroidRuntime: FATAL EXCEPTION: GLThread 276
                                                                     Process: com.dom925.volcamr.nz, PID: 3266
                                                                     java.lang.RuntimeException: createContext failed: 12291
                                                                         at com.google.maps.api.android.lib6.gmm6.vector.az.a(:com.google.android.gms.DynamiteModulesB:29)
                                                                         at com.google.maps.api.android.lib6.gmm6.vector.ba.f(:com.google.android.gms.DynamiteModulesB:158)
                                                                         at com.google.maps.api.android.lib6.gmm6.vector.ba.run(:com.google.android.gms.DynamiteModulesB:11)

The same Android app has no issue running on a real handset.

After some fiddling around with the emulator settings, the problem was resolved by changing the emulator's graphics emulated performance from automatic to either Hardware GLES 2.0 or Software GLES 2.0 as shown below.

Tuesday, August 30, 2016

Identifying deprecated classes and methods in Android Studio with "Recompile with -Xlink:deprecation"

When upgrading an Android project to a newer Android version, Google may deprecate some of the previously used Android classes and methods. By default, the gradle compilation process will only print out a summary message "Some input files use or override a deprecated API", as shown in the Android Studio screenshot below:

To enable the compilation process to print out a verbose message of the deprecated API, one or more of the build.gradle file may need to be edited to add in the -Xlint:deprecation option. In the example, the top most or project level build.gradle file was edited.


  1. In Android Studio, open up the project build.gradle file. Scroll to the allprojects section.


  2. Add in the gradle.projectsEvaluated sub section with the -Xlint:deprecation option as shown below.

  3. Save. Now when building the Android project, the deprecated API will be printed in the console.


Monday, August 1, 2016

Resolving com.android.build.api.transform.TransformException for task transformClassesWithDexForDebug

I encountered an Android Studio build exception while compiling an Android application to run on a device. The error message is shown in the screen shot below:


The message about classes and Dex gave a huge clue about the cause of the exception; I came across somewhere that there is a limit to the number of classes in a Dex file and Google Play Services use a lot of classes. My app's build.gradle has the dependency to the full com.google.android.gms:play-services:x:x:x file, as shown below.



So one method to reduce the number of classes is to use subsets of the Google Play Services library. Instead of the full com.google.android.gms:play-services dependency, my build.gradle file now has the following dependency line:
compile 'com.google.android.gms:play-services-maps:x.x.x'

Following this change, the application builds successfully, as shown in the console screen shot below.


Monday, May 30, 2016

Using Android XML layout tabs without ViewPager and Fragments

In Android, the TabLayout widget is typically used together with a ViewPager and fragments; when a user touch a tab, a fragment associated with the tab is displayed in the activity. But sometimes, I do not want or need fragments for each tab; I just want to execute some code. This post illustrates an example of using the TabLayout without a ViewPager and Fragments and setting a tab selected listener to the TabLayout.



First, create an XML layout and add in the TabLayout code. Add in the TabItem widgets underneath the parent TabLayout node. You can simple use text or icons (in this example) for the TabItem labels.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.skyglob.insight.view.MainActivity">

    <android.support.design.widget.CoordinatorLayout
        android:id="@+id/coordinatorLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true">

        <android.support.design.widget.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/AppTheme.AppBarOverlay">

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                app:popupTheme="@style/AppTheme.PopupOverlay" />

            <android.support.design.widget.TabLayout
                android:id="@+id/tabs"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:tabGravity="fill"
                app:tabMode="fixed">

                <android.support.design.widget.TabItem
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:icon="@drawable/ic_action_call" />

                <android.support.design.widget.TabItem
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:icon="@drawable/ic_action_checkin" />

                <android.support.design.widget.TabItem
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:icon="@drawable/ic_action_contacts" />

                <android.support.design.widget.TabItem
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:icon="@drawable/ic_action_schedule" />

                <android.support.design.widget.TabItem
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:icon="@drawable/ic_action_logout" />

            </android.support.design.widget.TabLayout>

        </android.support.design.widget.AppBarLayout>

        <include layout="@layout/content_main" />

    </android.support.design.widget.CoordinatorLayout>

</LinearLayout>

In the activity Java code, add in the tab selected listener. The following is an example showing how to assign a tab selected listener to the TabLayout widget.


private void setupTabLayout() {
    TabLayout mTabLayout = (TabLayout) findViewById(R.id.tabs);
    mTabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            onTabTapped(tab.getPosition());
        }
        @Override
        public void onTabUnselected(TabLayout.Tab tab) {

        }
        @Override
        public void onTabReselected(TabLayout.Tab tab) {
            onTabTapped(tab.getPosition());
        }
    });
}

private void onTabTapped(int position) {
    switch (position) {
        case 0:
            // Do something when first tab is tapped here
            break;
        default:
            Toast.makeText(this, "Tapped " + position, Toast.LENGTH_SHORT);
    }
}

Monday, May 16, 2016

ProGuard exceptions for Retrofit in an Android project

If you are enabling ProGuard to minify an Android APK, then it will be necessary to tell ProGuard to leave the Retrofit and related JSON data classes as they are. Otherwise, you will get class not found errors when running the Android app.

In Android Studio, to add the exceptions to ProGuard, open up the file proguard-rules.pro in the editor. Add in the following lines.


# for Retrofit
-keepattributes Signature
-keepattributes Exceptions

-keep class com.squareup.** { *; }
-keep interface com.squareup.** { *; }
-keep interface retrofit.** { *;}
-keep class retrofit.** { *; }

-keepclasseswithmembers class * {
    @retrofit.http.* <methods>;
}

-dontwarn com.squareup.okhttp.**
-dontwarn rx.**
-dontwarn retrofit.**

# add your JSON classes here
-keep class com.dom.mypackage.myclass.** { *; }
Note: for the last line above, replace it with the path to your classes that correspond to the JSON classes you are using in Retrofit.

Monday, May 9, 2016

Fix Gradle errors when upgrading old Android projects to a new Android Studio version

After upgrading my Android Studio to the latest version, I encountered problems with the Gradle version of my old Android project. The error message is saying something like the following "Gradle version 2.10 is required. Current version is 2.8. Fix Gradle wrapper and re-import project Gradle settings." A screenshot of the error is shown below.

Sometimes, clicking on the Fix hyperlink will resolve the problem; but sometimes it does not. If it does not, then it is possible to fix the problem by editing the gradle-wrapper.properties file of your project in the editor as shown below.

Simply change the version number in the distributionUrl to the new required version e.g. https\://services.gralde.org/distributions/gradle-2.10-all.zip.

Monday, December 14, 2015

Android code snippet to create transparent bitmaps

To reduce the storage needed on a phone for images, I wanted to use a single image file and programmatically set the transparency based on some attribute, e.g. age. The Android BitmapDrawable class has a setAlpha method but it does not work as expected and the resultant icons displayed in views remain as opaque as the original because of how Android handles image resources to minimise resource usage. Eventually, I found a workaround by drawing the icon onto a canvas with the desired transparency, then creating a new icon from the canvas. The following code snippet shows how.


private static Bitmap makeTransparentBitmap(Bitmap bmp, int alpha) {
        Bitmap transBmp = Bitmap.createBitmap(bmp.getWidth(),
                bmp.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(transBmp);
        final Paint paint = new Paint();
        paint.setAlpha(alpha);
        canvas.drawBitmap(bmp, 0, 0, paint);
        return transBmp;
    }

By using this code snippet, I was able to change the transparency of an icon image as shown in the screenshot below.


Monday, September 28, 2015

How to create and use an Android Archive (*.aar) using Android Studio

Besides a plain old Java archive file (*.jar), Android Studio can be used to create an Android archive file (*.aar) that can contain classes and methods that make use of Android classes and related files. Like creating the Jar file, an Android project must be created first, then the Android library module can be created and added. The following steps illustrate the process in creating a Android archive file.

Generating the Android archive (*.aar) file

  1. Start up Android Studio.
  2.  Select Start a new Android Studio project.

    The Create New Project dialog box appears.
  3. Type in an Application name and a Company Domain. Select a Project location. Click Next.

    The Target Android Device page appears.
  4. Choose a Minimum SDK, e.g. API 14. Click Next.

    The Add an activity to Mobile page appears.
  5. Select Add No Activity. Click Finish.

    The Android project is created.
  6. Select File | New | New Module.

    The Create New Module dialog box appears.

  7. Select Android library. Click Next.

    The Configure your new module page appears.

  8. In the Application/Library name field, type in e.g. MyAarLibrary.
  9. In the Module name field, type in e.g. myaarlibrary.
  10. If necessary, edit the Package name and/or change the Minimum SDK.
  11. Click Next.

    The myaarlibrary library is created.
  12. In the newly created myaarlibrary module node, create the classes and methods of the library in the editor, e.g. LibraryClass class with a printLog method.

    Note: the example printLog uses the Android.Util.Log class to print a debug log message.




  13. In the Project tree view, select the newly created module node, e.g. myaarlibrary. Then open the Gradle projects pane on the right side. Expand the Tasks node, as shown below.


  14. Double click on assembleRelease.

    The Android archive file is generated, e.g. myaarlibrary-release.aar.

     
Using the Android archive (*.aar) file
  1. In Android Studio, create a new project or open up an existing project that you want to use the Android archive file library.
  2. In the Project view, expand the libs node of the app.
  3. Using the Mac Finder or Windows Explorer, select and copy the Android archive file (*.aar) e.g. myaarlibrary.aar. Paste the aar file into the libs node in Android Studio.

    The Copy dialog box appears.

  4.  If necessary, change the name. Click OK.

    The Aar file is added to the project.
  5. In Android Studio, open the app's build.gradle file in the editor.



  6. Add in the following line to the dependencies section.

    implementation files ( 'libs/myaarlibrary-release.aar')

    Now the classes and methods in the Android archive file can be used in your app, as shown in the example below.


Monday, September 21, 2015

How to create and use a Jar archive using Android Studio

I wanted to consolidate some Java classes into a common library so that it can be shared among Android projects. A Java archive file (*.jar) is a typical container for this purpose. Android Studio can generate and use a Java archive (Jar) file containing commonly used classes and resources. But since we are using Android Studio, an Android project must be created first, then a Jar module can then be created and added. The following steps illustrate the process in creating a Jar file.

Generating a Java archive (*.jar) file

  1. Start up Android Studio.


  2.  Select Start a new Android Studio project.

    The Create New Project dialog box appears.

  3. Type in an Application name and a Company Domain. Select a Project location. Click Next.

    The Target Android Devices page appears.

  4.  Choose a Minimum SDK, e.g. API 14. Click Next.

    The Add an activity to Mobile page appears.

  5. Select Add No Activity. Click Finish.

    The Android project is created.
  6. Select File | New | New Module.

    The Create New Module dialog box appears.

  7. Select Java library.

    The Customize the Activity page appears.

  8. In the Library name field, type in the name of the library e.g. libDijkstra. In the Java class name field, type in the name of the class e.g. MyClass. Press Enter.

    The library is created.
  9. Type in the classes and methods of the library in the editor e.g. printHello method in the MyClass.java file.
  10. In the Project tree view, select the newly created module node, e.g. libdijkstra. Then open the Gradle projects pane on the right side. Expand the Tasks node, as shown below.


  11. Double click on build.

    The Java archive file is generated, e.g. libdijkstra.jar.

Using the Java archive (*.jar) file
  1. In Android Studio, create a new project or open up an existing project e.g. MyApplication that you want to use the Java archive file library.
  2. In the Project view, expand the libs node of your app, as shown below.


  3. Using the Windows Explorer, select and copy the Java archive file (*.jar) e.g. libdijkstra.jar. In Android Studio, right click on the libs folder of the app. Paste the Jar file.

    The Copy dialog box appears.

  4. If necessary, change the name. Click OK.

    The Jar file is added to the project.
  5. Select File | Project Structure.

    The Project Structure dialog box appears.

  6. Select app. On the right side, click the plus +.

    The Select Path dialog box appears.

  7. Browse and select the Java archive file e.g. libdijkstra.jar. Click OK.

    Now the classes and methods in the Java archive file can be used in your app, as shown in the example below.