I added firebase inside my app to get some special events like when users open and close their app.
The problem is that every time I launch the app, it crashes right away. It started to happen when I added firebase and when I comment my Firebase code, it's working again, so now I'm pretty sure it's a problem with firebase.
The problem seems to be happening when the onForeground() is called. I tried to put it on a new Thread or call it in a Handler but it keeps crashing...
Here is the stack:
10-28 16:46:26.106 27724-27732/com.package.custom E/System: Uncaught exception thrown by finalizer
10-28 16:46:26.107 27724-27732/com.package.custom E/System: java.lang.IllegalStateException: The database '/data/user/0/com.package.custom/databases/google_app_measurement_local.db' is not open.
at android.database.sqlite.SQLiteDatabase.throwIfNotOpenLocked(SQLiteDatabase.java:2169)
at android.database.sqlite.SQLiteDatabase.createSession(SQLiteDatabase.java:365)
at android.database.sqlite.SQLiteDatabase$1.initialValue(SQLiteDatabase.java:84)
at android.database.sqlite.SQLiteDatabase$1.initialValue(SQLiteDatabase.java:83)
at java.lang.ThreadLocal$Values.getAfterMiss(ThreadLocal.java:430)
at java.lang.ThreadLocal.get(ThreadLocal.java:65)
at android.database.sqlite.SQLiteDatabase.getThreadSession(SQLiteDatabase.java:359)
at android.database.sqlite.SQLiteProgram.getSession(SQLiteProgram.java:101)
at android.database.sqlite.SQLiteQuery.setLastStmt(SQLiteQuery.java:96)
at android.database.sqlite.SQLiteQuery.close(SQLiteQuery.java:111)
at android.database.sqlite.SQLiteCursor.close(SQLiteCursor.java:300)
at android.database.sqlite.SQLiteCursor.finalize(SQLiteCursor.java:366)
at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:202)
at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:185)
at java.lang.Thread.run(Thread.java:818)
Here is a part of my AnalyticsHelper class:
public class AnalyticsHelper
{
//...
/**
* Hook called when the app switch to foreground mode
*/
public static void onForeground()
{
Log.d(TAG, "FOREGROUND");
Bundle bundle = new Bundle();
bundle.putString(KEY_TYPE, AnalyticsCategories.CATEGORY_LIFECYCLE_ACTION_FOREGROUND);
CustomApplication.getAnalytics().logEvent(AnalyticsCategories.CATEGORY_LIFECYCLE, bundle);
}
//...
}
Here is the call of the AnalyticsHelper in the activity:
public class MainActivity extends AppCompatActivity
{
#Override
protected void onResume()
{
super.onResume();
//...
AnalyticsHelper.onForeground();
}
}
And here is the part of the custom Application class:
public class CustomApplication extends Application
{
private static final String TAG = "CustomApplication";
private static CustomApplication sApplication;
public static CustomApplication get()
{
return sApplication;
}
public static FirebaseAnalytics getAnalytics()
{
return get().getFirebaseAnalytics();
}
#Override
public void onCreate()
{
super.onCreate();
mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);
sApplication = this;
}
/**
* Gets the default {#link Tracker} for this {#link Application}.
*
* #return tracker
*/
public FirebaseAnalytics getFirebaseAnalytics()
{
if (mFirebaseAnalytics == null)
{
mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);
}
return mFirebaseAnalytics;
}
}
I searched all the afternoon and nothing came out, please help..
Edit #1 (build.gradle):
apply plugin: 'com.android.application'
android {
signingConfigs {
release {
keyAlias '##########'
keyPassword '##########'
storeFile file('##########')
storePassword '##########'
}
}
compileSdkVersion 25
buildToolsVersion '24.0.2'
defaultConfig {
applicationId "com.custom.app"
minSdkVersion 18
targetSdkVersion 25
android.applicationVariants.all { variant ->
def versionPropsFile = file('src/main/res/raw/version.properties')
if (versionPropsFile.canRead())
{
def Properties versionProps = new Properties()
versionProps.load(new FileInputStream(versionPropsFile))
def code = versionProps['code'].toInteger() + 1
versionProps['code'] = code.toString()
def version = versionProps['version']
versionProps.store(versionPropsFile.newWriter(), null)
versionCode code
versionName version
}
else
{
throw new GradleScriptException('Cant access version.properties');
}
}
signingConfig signingConfigs.release
vectorDrawables.useSupportLibrary = true
multiDexEnabled true
}
buildTypes {
release {
minifyEnabled false
debuggable true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
buildConfigField "boolean", "EXPORT_EXTERNAL_STORAGE", "true"
}
debug {
debuggable true
buildConfigField "boolean", "EXPORT_EXTERNAL_STORAGE", "true"
}
}
productFlavors {
}
testOptions {
unitTests.returnDefaultValues = true
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile files('libs/commons-net-3.3.jar')
//Debug
compile files('libs/commons-lang3-3.5.jar')
compile files('libs/joda-time-2.9.5.jar')
compile project(':android-ble-module')
debugCompile project(path: ':android-log-module', configuration: 'debug')
releaseCompile project(path: ':android-log-module', configuration: 'release')
compile project(':android-location-module')
testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-core:1.9.5'
compile 'com.android.support:design:25.0.0'
compile 'com.android.support:multidex:1.0.1'
compile 'com.android.support:appcompat-v7:25.0.0'
compile 'com.android.support:preference-v14:25.0.0'
compile 'com.google.android.gms:play-services-gcm:9.8.0'
compile 'com.google.android.gms:play-services-maps:9.8.0'
compile 'com.google.android.gms:play-services-identity:9.8.0'
compile 'com.google.firebase:firebase-analytics:9.8.0'
}
apply plugin: 'com.google.gms.google-services'
Please move to latest version of firebase SDK. Firebase solved this memory leak issue in their updated sdk. In this case replace this line
compile 'com.google.firebase:firebase-analytics:9.8.0'
with below line.
compile 'com.google.firebase:firebase-analytics:11.0.1'
Related
Did anyone encounter the same issue? When using Dokka to document a data class
/**
* Data class for which we want documentation
*/
data class DokkaData(
/** A String value */
val aString: String,
/** An Integer value */
val anInt: Int,
/** Yes, a Boolean value. My favorite. */
val aBoolean: Boolean) {
/**
* Checks that all values are representation of `1`
*/
fun isOne() = aString == "1" && anInt == 1 && aBoolean
}
the documentation is correctly displayed in Android Studio
But then, when exporting library to mavenLocal using dokkaJavadoc:
plugins {
id 'com.android.library'
id 'kotlin-android'
id 'maven-publish'
id("org.jetbrains.dokka") version "1.6.10"
}
android {
compileSdk 31
defaultConfig {
minSdk 21
targetSdk 31
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles "consumer-rules.pro"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.4.0'
implementation 'com.google.android.material:material:1.4.0'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
task dokkaJavadocJar(type: Jar, dependsOn: dokkaJavadoc) {
archiveClassifier.set("javadoc")
from dokkaJavadoc.outputDirectory
}
publishing {
publications {
release(MavenPublication) {
groupId = "com.dokkatests.testlib"
artifactId = "lib"
version = "2.1-dataDoc"
artifact("$buildDir/outputs/aar/${project.getName()}-release.aar")
artifact(dokkaJavadocJar)
}
}
}
the generated library javadoc is correctly displayed for methods, but not for the data class level
Note: The html documentation is complete, the issue is only for the documentation displayed in Android Studio. I didn't find any other reference to this issue, which is strange because it looks like a blocker to me.
Any clue?
Move KDoc comments of property of data class to be at class level and use #property or #param
example
I already was using room database in my application. Now I have migrated my project to androidX, so dependencies are changed.
Now when I am adding a table and trying to run the project, I am getting an error for multiple files:
error: cannot find symbol class BR
Here is my model class:
#Keep
#Entity
public class Notification {
private String title;
private String body;
public Notification(String title, String body) {
this.title = title;
this.body = body;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
}
Here is my NotificationDao Class:
public abstract class NotificationDao {
#Insert(onConflict = REPLACE)
public abstract void insert(Notification notification);
#Query("DELETE FROM Notification")
public abstract void deleteAll();
}
Here is the code written for migration:
static final Migration MIGRATION_1_2 = new Migration(1, 2) {
#Override
public void migrate(SupportSQLiteDatabase database) {
database.execSQL("CREATE TABLE IF NOT EXISTS Notification (`title` TEXT, `body` TEXT)");
}
};
I have increased the version from 1 to 2.
I have added this in build as well.
Room.databaseBuilder(
application,
MyDatabase.class,
Configuration.DB_NAME
).addMigrations(MyDatabase.MIGRATION_1_2).build();
app.gradle is:
buildscript {
repositories {
maven { url 'https://maven.fabric.io/public' }
}
dependencies {
classpath 'io.fabric.tools:gradle:1.+'
}
}
apply plugin: 'com.android.application'
apply plugin: 'io.fabric'
repositories {
maven { url 'https://maven.fabric.io/public' }
}
android {
compileSdkVersion 29
defaultConfig {
minSdkVersion 21
targetSdkVersion 29
versionCode 211990017
versionName "2.1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
// Write out the current schema of Room
javaCompileOptions {
annotationProcessorOptions {
arguments = ["room.schemaLocation": "$projectDir/schemas".toString(),]
}
}
vectorDrawables.useSupportLibrary = true
project.archivesBaseName = "xxxx";
multiDexEnabled true
externalNativeBuild {
cmake {
cppFlags "-std=c++11 -fexceptions"
arguments "-DANDROID_TOOLCHAIN=clang",
"-DANDROID_STL=c++_shared",
"-DANDROID_PLATFORM=android-21"
}
}
}
sourceSets {
main {
jniLibs.srcDirs = ['src/main/jniLibs']
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
signingConfigs {
release {
storeFile file("keystores/xxxx")
storePassword "xxxx"
keyAlias "xxxx"
keyPassword "xxxx"
}
}
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
}
buildTypes {
release {
minifyEnabled false
shrinkResources false
proguardFiles fileTree(dir: "proguard", include: ["*.pro"]).asList().toArray()
proguardFiles getDefaultProguardFile('proguard-android.txt')
signingConfig signingConfigs.release
}
debug {
minifyEnabled false
shrinkResources false
proguardFiles fileTree(dir: "proguard", include: ["*.pro"]).asList().toArray()
proguardFiles getDefaultProguardFile('proguard-android.txt')
signingConfig signingConfigs.release
}
}
dataBinding {
enabled true
}
buildToolsVersion '28.0.3'
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
flavorDimensions "environment"
productFlavors {
development {
applicationId "com.emproto.xxxx"
resValue "string", "content_provider", "com.xxx.xxxx.fileprovider"
}
production {
applicationId "com.xxxx"
resValue "string", "content_provider", "com.xxxx.fileprovider"
}
}
splits {
// Configures multiple APKs based on ABI.
abi {
// Enables building multiple APKs per ABI.
enable true
// By default all ABIs are included, so use reset() and include to specify that we only
// want APKs for x86 and x86_64.
// Resets the list of ABIs that Gradle should create APKs for to none.
reset()
// Specifies a list of ABIs that Gradle should create APKs for.
include "x86", "x86_64", "arm64-v8a", "armeabi-v7a"
// Specifies that we do not want to also generate a universal APK that includes all ABIs.
universalApk true
}
}
}
ext.abiCodes = ['x86': 1, 'x86_64': 2, 'armeabi-v7a': 3, 'arm64-v8a': 4]
import com.android.build.OutputFile
android.applicationVariants.all { variant ->
variant.outputs.each { output ->
def baseVersionCode = project.ext.abiCodes.get(output.getFilter(OutputFile.ABI))
if (baseVersionCode != null) {
output.versionCodeOverride = Integer.valueOf(baseVersionCode + variant.versionCode)
}
}
}
ext {
retrofitVersion = '2.3.0'
daggerVersion = '2.11'
supportLibVersion = '28.0.0'
googleLibVersion = '16.0.1'
frescoLibVersion = '2.0.0'
moEngageVersion = '9.8.02'
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'androidx.appcompat:appcompat:1.0.0'
implementation 'com.google.android.material:material:1.0.0'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.legacy:legacy-support-v13:1.0.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.browser:browser:1.0.0'
implementation 'androidx.recyclerview:recyclerview:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.exifinterface:exifinterface:1.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'
/*Dagger 2 is a fully static and compile time dependency injection framework*/
implementation "com.google.dagger:dagger:$daggerVersion"
annotationProcessor "com.google.dagger:dagger-compiler:$daggerVersion"
implementation 'javax.annotation:jsr250-api:1.0'
/*LiveData and ViewModel*/
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
/*
annotationProcessor "android.arch.lifecycle:compiler:1.1.0"
*/
/*Room*/
implementation 'androidx.room:room-runtime:2.2.3'
annotationProcessor 'androidx.room:room-compiler:2.2.3'
// Java8 support for Lifecycles
implementation 'androidx.lifecycle:lifecycle-common-java8:2.2.0'
/*Retrofit*/
implementation "com.squareup.retrofit2:retrofit:$retrofitVersion"
implementation "com.squareup.retrofit2:converter-gson:$retrofitVersion"
/*For loading images from network*/
implementation "com.facebook.fresco:fresco:$frescoLibVersion"
implementation "com.facebook.fresco:imagepipeline-okhttp3:$frescoLibVersion"
/*For the left menu*/
implementation 'com.yarolegovich:sliding-root-nav:1.1.0'
/*For the typing indicator*/
implementation 'com.github.channguyen:adv:1.0.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.9.0'
/*For Graphs */
implementation 'com.github.PhilJay:MPAndroidChart:v3.0.3'
/*For firebase push notifications */
implementation "com.google.firebase:firebase-messaging:17.3.4"
implementation "com.google.firebase:firebase-core:16.0.6"
/*For Database debugging */
// debugImplementation 'com.amitshekhar.android:debug-db:1.0.4'
/*For S - Health */
implementation files('libs/s-health/samsung-health-data-v1.3.0.jar')
implementation files('libs/s-health/sdk-v1.0.0.jar')
/*For Google-Fit */
implementation "com.google.android.gms:play-services-fitness:$googleLibVersion"
implementation "com.google.android.gms:play-services-auth:$googleLibVersion"
/*Circular floating action bar*/
implementation 'com.oguzdev:CircularFloatingActionMenu:1.0.2'
// For animated GIF support
implementation "com.facebook.fresco:animated-gif:$frescoLibVersion"
/*Circular seekbar - Feelings*/
implementation 'com.github.JesusM:HoloCircleSeekBar:v2.2.2'
/*Circular Layout - Feelings*/
implementation 'com.github.andreilisun:circular-layout:1.0'
/*For offline log synchronization*/
implementation 'com.firebase:firebase-jobdispatcher:0.8.5'
/*Wheel picker - RecordCholesterol*/
implementation 'com.weigan:loopView:0.1.2'
implementation('com.crashlytics.sdk.android:crashlytics:2.9.3#aar') {
transitive = true;
}
/*Image Cropper - Profile Fragment*/
implementation 'com.theartofdev.edmodo:android-image-cropper:2.7.+'
/*PDF Viewer - Prescription/Report */
implementation 'com.github.barteksc:android-pdf-viewer:2.8.2'
api 'com.thedesigncycle.ui:views:0.3.1'
implementation 'com.ogaclejapan.smarttablayout:library:1.6.1#aar'
implementation 'com.getkeepsafe.taptargetview:taptargetview:1.11.0'
implementation files('libs/omron/jp.co.omron.healthcare.omoron_connect.wrapper-1.3.jar')
implementation 'com.appsee:appsee-android:+'
implementation 'com.github.florent37:viewtooltip:1.1.6'
implementation 'com.asksira.android:cameraviewplus:0.9.5'
implementation 'me.zhanghai.android.materialratingbar:library:1.3.1'
implementation 'com.priyankvex:smarttextview:1.0.1'
implementation 'com.github.flipkart-incubator:android-inline-youtube-view:1.0.3'
implementation 'com.github.varunest:sparkbutton:1.0.6'
implementation 'io.branch.sdk.android:library:3.2.0'
//foo transitions in trel home(doctor names)
implementation "com.andkulikov:transitionseverywhere:1.8.1"
//AppsFlyer
implementation 'com.appsflyer:af-android-sdk:4.10.3'
implementation 'com.android.installreferrer:installreferrer:1.0'
//picasso image loading lib
implementation 'com.squareup.picasso:picasso:2.5.2'
//Facebook analytics dependency
implementation 'com.facebook.android:facebook-android-sdk:[4,5)'
//Moengage dependency
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "com.moengage:moe-android-sdk:$moEngageVersion"
}
apply plugin: 'com.google.gms.google-services'
How can the error be fixed?
Not adding the primary key in model class was causing the problem. I think more specific error messages should be there from android studio's side regarding room database.
I have looked at this article
[INSTALL_FAILED_NO_MATCHING_ABIS: Failed to extract native libraries, res=-113]
But i was unable to get any resolution.
right now this is my code.
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
defaultConfig {
applicationId "com.example.testapp.testapp"
minSdkVersion 24
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
splits {
abi {
enable true
reset()
include 'arm64-v8a'
universalApk true
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation('me.dm7.barcodescanner:zxing:1.9') { exclude module: 'support-v4' }
implementation 'com.journeyapps:zxing-android-embedded:3.2.0#aar'
implementation 'org.bitcoinj:bitcoinj-core:0.14.7'
api 'org.slf4j:slf4j-api:1.7.25'
implementation 'org.slf4j:slf4j-simple:1.7.12'
}
And also my mainactivity
public class MainPage extends AppCompatActivity {
public static NetworkParameters BTCparams = TestNet3Params.get();
public static WalletAppKit BTCkit = new WalletAppKit(BTCparams,new File("."),"BTC-Test");
static String[] account;
static String[] server;
private Handler handler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tVBTCPer = (TextView)findViewById(R.id.tVBTCPer);
TextView tVNull = (TextView)findViewById(R.id.tVNull);
tVNull.setText(System.getProperty("os.arch"));
DownloadProgressTracker BTCListener = new DownloadProgressTracker() {
#Override
public void progress(double pct, int blocksSoFar, Date date) {
tVBTCPer.setText((int) pct+"%");
}
#Override
public void doneDownload() {
tVBTCPer.setText("100%");
}
};
BTCkit.setDownloadListener(BTCListener).setBlockingStartup(false).startAsync().awaitRunning();
}
I used this library to make java applications for pc/linux and it works fine. But when im trying to compile this for android to be usable it gets hung up trying to install the apk onto my device.
my os.arch is aarch64. I also have a previous post in stackoverflow to help give it some context.
Bitcoinj library on android hung on installing APK
I am not entirely sure what library i would need to help this apk install onto my device.
I have 6 apps that all use one main build to run off of. They all have 4 tab buttons but I'd like to switch one app to have 5 tab bar buttons.
So I've configured a main class that has 4 tab bar buttons, however for one app I'd like it to override that and use 5 tab bar buttons. I'm just not sure how to change out the classes.
Any help at all would be greatly appreciated
EDIT: also, if you downvote, please say why. If it's unclear what I'm asking or if it's a simple question etc.
Here's the class I'm trying to exchange
package com.android.stanby.app.domain;
import com.android.stanby.app.R;
/**
* Created by trevor.wood on 2018/05/01.
*/
public class BottomMenuButtons {
public static final int TAB_INDEX_JOB_LIST = 0;
public static final int TAB_INDEX_JOB_MAP = 1;
public static final int TAB_INDEX_WEB = 2;
public static final int TAB_INDEX_RECOMMEND = 3;
public static final int TAB_INDEX_CHAT = 4;
public static final int[] NAVI_ITEMS = {
R.id.bottom_navigation_job_list,
R.id.bottom_navigation_job_map,
R.id.bottom_navigation_keep,
R.id.bottom_navigation_recommend,
R.id.bottom_navigation_chat,
};
public static final int[] NAVI_ICONS = {
R.id.bottom_navigation_job_list_icon,
R.id.bottom_navigation_job_map_icon,
R.id.bottom_navigation_keep_icon,
R.id.bottom_navigation_recommend_icon,
R.id.bottom_navigation_chat_icon,
};
public static final int[] NAVI_OFF_ICONS = {
R.drawable.stanby_ic_bottom_tab_job_off,
R.drawable.stanby_ic_bottom_tab_job_map_off,
R.drawable.stanby_ic_bottom_tab_keep_off,
R.drawable.stanby_ic_bottom_tab_recommend_off,
R.drawable.stanby_ic_bottom_tab_chat_off,
};
public static final int[] NAVI_ON_ICONS = {
R.drawable.stanby_ic_bottom_tab_job_on,
R.drawable.stanby_ic_bottom_tab_job_map_on,
R.drawable.stanby_ic_bottom_tab_keep_on,
R.drawable.stanby_ic_bottom_tab_recommend_on,
R.drawable.stanby_ic_bottom_tab_chat_on,
};
}
And here are my build settings
def PACKAGE_NAME = "com.stanby.jp"
// VERSION_CODE及びVERSION_NAMEはgradle.propertiesに定義されている
def VERSION_CODE = APP_VERSION_CODE.toInteger()
def VERSION_NAME = APP_VERSION_NAME
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion "25.0.3"
defaultConfig {
minSdkVersion 16
targetSdkVersion 25
versionCode VERSION_CODE
versionName VERSION_NAME
multiDexEnabled true
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
signingConfigs {
release {
keyAlias STANBY_KEY_ALIAS
keyPassword STANBY_KEY_PASSWORD
storeFile file(System.getenv("HOME") + "/.android/" + STANBY_STORE_FILE)
storePassword STANBY_STORE_PASSWORD
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
// フレーバー
flavorDimensions "type", "env"
productFlavors {
// 全部入り
stanby {
dimension "type"
applicationId "${PACKAGE_NAME}"
}
// アルバイト・パート
part {
dimension "type"
applicationId "${PACKAGE_NAME}.part"
}
// 転職(正社員)
full {
dimension "type"
applicationId "${PACKAGE_NAME}.full"
}
// ハローワーク
hellowork {
dimension "type"
applicationId "${PACKAGE_NAME}.hellowork"
}
// 富山県
toyama {
dimension "type"
applicationId "${PACKAGE_NAME}.toyama"
}
// 福島県
fukushima {
dimension "type"
applicationId "${PACKAGE_NAME}.fukushima"
}
// 福岡県
fukuoka {
dimension "type"
applicationId "${PACKAGE_NAME}.fukuoka"
}
develop {
dimension "env"
}
product {
dimension "env"
}
}
// ビルドタイプ
buildTypes {
release {
signingConfig signingConfigs.release
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.txt'
buildConfigField "boolean", "USE_CRASHLYTICS", "true"
ext.enableCrashlytics = true
}
debug {
//signingConfig signingConfigs.release
buildConfigField "boolean", "USE_CRASHLYTICS", "false"
ext.enableCrashlytics = false
}
}
// ソース構成
sourceSets {
// 全部入り
stanby {
java.srcDirs = ['src/stanby/java', 'src/common/java']
res.srcDirs = ['src/stanby/res', 'src/common/res']
}
// アルバイト・パート
part {
java.srcDirs = ['src/part/java', 'src/common/java']
res.srcDirs = ['src/part/res', 'src/common/res']
}
// 転職(正社員)
full {
java.srcDirs = ['src/full/java', 'src/common/java']
res.srcDirs = ['src/full/res', 'src/common/res']
}
// ハローワーク
hellowork {
java.srcDirs = ['src/hellowork/java', 'src/common/java']
res.srcDirs = ['src/hellowork/res', 'src/common/res']
}
// 富山県
toyama {
java.srcDirs = ['src/toyama/java']
res.srcDirs = ['src/toyama/res']
}
// 福島県
fukushima {
java.srcDirs = ['src/fukushima/java']
res.srcDirs = ['src/fukushima/res']
}
// 福岡県
fukuoka {
java.srcDirs = ['src/fukuoka/java']
res.srcDirs = ['src/fukuoka/res']
}
// 検証環境
develop {
java.srcDirs = ['src/develop/java']
res.srcDirs = ['src/develop/res']
}
// 本番環境
product {
java.srcDirs = ['src/product/java']
res.srcDirs = ['src/product/res']
}
}
// google-services.json を develop/product からコピーする
gradle.taskGraph.beforeTask { Task task ->
if (task.name ==~ /process.*GoogleServices/) {
applicationVariants.all { variant ->
if (task.name ==~ /(?i)process${variant.name}GoogleServices/) {
String fromDir = "${variant.flavorName}";
if (fromDir.endsWith("Develop")) {
fromDir = "develop";
} else if (fromDir.endsWith("Product")) {
fromDir = "product";
}
print "\n#####################################################\n";
print "google-services.json fromDir=${fromDir}\n"
print "#####################################################\n\n";
copy {
from "src/" + fromDir
into "."
include "google-services.json"
}
}
}
}
}
}
apply plugin: 'com.neenbedankt.android-apt'
repositories {
flatDir {
dirs 'libs'
}
}
dependencies {
// https://developer.android.com/topic/libraries/support-library/revisions.html
def supportLibraryVersion = '25.3.1'
// https://developers.google.com/android/guides/releases
def playServiceVersion = '11.8.0'
// https://github.com/firebase/FirebaseUI-Android
def firebaseUiDatabaseVersion = '1.2.0'
def retrofitVersion = '2.1.0'
def okHttpVersion = '3.4.1'
def daggerVersion = '2.6'
def butterknifeVersion = '8.3.0'
def rxLifecycleVersion = '0.7.0'
compile fileTree(dir: 'libs', include: ['*.jar'])
// 計測
compile('com.crashlytics.sdk.android:crashlytics:2.8.0#aar') {
transitive = true;
}
compile 'com.adjust.sdk:adjust-android:4.2.1'
// support library
compile 'com.android.support:multidex:1.0.1'
compile "com.android.support:support-v4:${supportLibraryVersion}"
compile "com.android.support:appcompat-v7:${supportLibraryVersion}"
compile "com.android.support:design:${supportLibraryVersion}"
compile "com.android.support:recyclerview-v7:${supportLibraryVersion}"
compile "com.android.support:cardview-v7:${supportLibraryVersion}"
// Play service
compile "com.google.android.gms:play-services-analytics:${playServiceVersion}"
compile "com.google.android.gms:play-services-location:${playServiceVersion}"
compile "com.google.android.gms:play-services-maps:${playServiceVersion}"
compile 'com.google.maps.android:android-maps-utils:0.4.3'
// Firebase
compile "com.google.firebase:firebase-core:${playServiceVersion}"
compile "com.google.firebase:firebase-messaging:${playServiceVersion}"
compile "com.google.firebase:firebase-config:${playServiceVersion}"
compile "com.google.firebase:firebase-auth:${playServiceVersion}"
compile "com.google.firebase:firebase-database:${playServiceVersion}"
compile "com.google.firebase:firebase-invites:${playServiceVersion}"
compile "com.firebaseui:firebase-ui-database:${firebaseUiDatabaseVersion}"
// retrofit
compile "com.squareup.retrofit2:retrofit:${retrofitVersion}"
compile "com.squareup.retrofit2:adapter-rxjava:${retrofitVersion}"
compile "com.squareup.retrofit2:converter-gson:${retrofitVersion}"
// okHttp
compile "com.squareup.okhttp3:logging-interceptor:${okHttpVersion}"
// Glide
compile 'com.github.bumptech.glide:glide:3.7.0'
// Twillio
compile 'com.koushikdutta.ion:ion:2.1.7'
compile 'com.twilio:conversations-android:0.12.2'
// 求人詳細の WebView レイアウト
compile 'com.samskivert:jmustache:1.12'
// base framework
apt "com.google.dagger:dagger-compiler:$daggerVersion"
compile "com.google.dagger:dagger:$daggerVersion"
apt "com.jakewharton:butterknife-compiler:$butterknifeVersion"
compile "com.jakewharton:butterknife:$butterknifeVersion"
compile "com.trello:rxlifecycle:$rxLifecycleVersion"
compile "com.trello:rxlifecycle-android:$rxLifecycleVersion"
compile "com.trello:rxlifecycle-components:$rxLifecycleVersion"
compile 'io.reactivex:rxandroid:1.1.0'
// library
compile 'com.facebook.android:facebook-android-sdk:4.25.0'
compile 'com.viewpagerindicator:library:2.4.1#aar'
compile 'com.wefika:flowlayout:0.4.1'
compile 'com.ncapdevi:frag-nav:1.0.3'
compile 'com.github.ksoichiro:android-observablescrollview:1.6.0'
compile 'com.github.2359media:EasyAndroidAnimations:0.8'
compile 'commons-codec:commons-codec:1.10'
compile 'net.danlew:android.joda:2.9.2'
// test
testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-core:1.10.19'
testCompile 'org.hamcrest:hamcrest-library:1.3'
androidTestCompile "com.android.support:support-annotations:$supportLibraryVersion"
androidTestCompile 'com.android.support.test:runner:0.5'
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2') {
exclude group: 'com.google.code.findbugs', module: 'jsr305'
}
androidTestCompile("com.squareup.retrofit2:retrofit-mock:$retrofitVersion") {
exclude group: 'com.squareup.okio', module: 'okio'
exclude group: 'com.squareup.okhttp3', module: 'okhttp'
}
androidTestCompile('com.squareup.assertj:assertj-android:1.1.1') {
exclude group: 'com.squareup.okio', module: 'okio'
exclude group: 'com.squareup.okhttp3', module: 'okhttp'
}
}
apply plugin: 'com.google.gms.google-services'
apply plugin: 'me.tatarka.retrolambda'
apply plugin: 'io.fabric'
apply plugin: 'realm-android'
You need to create your flavor directory for it. For example, if you want to create specific class for fukusima flavor, you need to create the fukusima directory inside your src directory. Like this:
src/fukusima/java/your/package/name/bottommenu
then you create the BottomMenuButtons there. Change your/package/name/bottommenu to your BottomMenuButtons path.
The other way is using a flag for adding specific flag for your flavor. First, add a specific flag to your flavor. For example, we use USE_FIVE_TAB. Change the flavor by adding the flag:
productFlavors {
stanby {
buildConfigField "boolean", "USE_FIVE_TAB", "false"
dimension "type"
applicationId "${PACKAGE_NAME}"
}
part {
buildConfigField "boolean", "USE_FIVE_TAB", "false"
dimension "type"
applicationId "${PACKAGE_NAME}.part"
}
full {
buildConfigField "boolean", "USE_FIVE_TAB", "true"
dimension "type"
applicationId "${PACKAGE_NAME}.full"
}
// add the same flag to all of your flavors
...
Then, you can use it something like this:
if(BuildConfig.USE_FIVE_TAB) {
// set to use five tabs
} else {
// use four tabs
}
You can override classses per variant by creating the corresponding folder in the project with the same name for the flavor. Check this SO link that explains the directory structure needed. Then automatically when you compile that flavor the class will be overriden.
I want to send Messages from a handheld device to a smartwatch (Moto360) only when a message comes up.
I made sure that both modules have the same package name, debug.key and version number.
The listener gets added in onConnected() and the function is always called.
Here is my Handheld gradle.build:
apply plugin: 'com.android.application'
android {
compileSdkVersion 19
buildToolsVersion "22.0.0"
defaultConfig {
applicationId "de.bachelorthesis.important"
minSdkVersion 9
targetSdkVersion 19
versionCode 1
versionName "1.0"
}
signingConfigs {
debug {
storeFile file("../debug.keystore")
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
}
dependencies {
compile 'com.android.support:support-v4:19.1.0'
compile 'com.google.android.gms:play-services:7.0.0'
compile files('libs/commons-io-2.4.jar')
compile files('libs/mapquest-android-sdk-1.0.5.jar')
compile files('libs/osmdroid-android-4.2.jar')
compile files('libs/slf4j-android-1.7.7.jar')
wearApp project(':wear')
}
In my handheld Activity the message should be sent like this:
private void sendToSmartwatch(msg) {
final String msg_arg = msg;
new Thread(new Runnable() {
public void run() {
mGoogleApiClient = new GoogleApiClient.Builder(getBaseContext())
.addApi(Wearable.API)
.build();
ConnectionResult connectionResult =
mGoogleApiClient.blockingConnect(5, TimeUnit.SECONDS);
NodeApi.GetLocalNodeResult nodes =
Wearable.NodeApi.getLocalNode(mGoogleApiClient).await(3, TimeUnit.SECONDS);
com.google.android.gms.wearable.Node node = nodes.getNode();
MessageApi.SendMessageResult result = Wearable.MessageApi.sendMessage(
mGoogleApiClient, node.getId(), CONSTANT, msg_arg.getBytes()).await();
Log.d("node:result: ", "" + result.getStatus());
if (result.getStatus().isSuccess()) {
// Log success
}
else {
// Log an error
}
mGoogleApiClient.disconnect();
}
}).start();
}
The Wearable gradle.build file looks like this:
apply plugin: 'com.android.application'
android {
compileSdkVersion 22
buildToolsVersion "22.0.0"
defaultConfig {
applicationId "de.bachelorthesis.important"
minSdkVersion 20
targetSdkVersion 22
versionCode 1
versionName "1.0"
}
signingConfigs {
debug {
storeFile file("../debug.keystore")
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.google.android.support:wearable:1.1.0'
compile 'com.google.android.gms:play-services-wearable:+'
compile 'com.google.android.gms:play-services:+'
compile 'com.android.support:support-v4:22.0.0'
}
And eventually, the message should come up here on my watch:
public class MainActivity extends Activity implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
...
onCreate(){
mGoogleApiClient = new GoogleApiClient.Builder(getApplicationContext())
.addApi(Wearable.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mGoogleApiClient.connect();
}
mListener = new MessageApi.MessageListener() {
#Override
public void onMessageReceived(MessageEvent messageEvent) {
if (messageEvent.getPath().equals(CONSTANT)) {
//do stuff with the message
}
}
};
}
#Override
public void onConnected(Bundle bundle) {
Wearable.MessageApi.addListener(mGoogleApiClient, mListener);
}
I have tried several different Listeners like the ListenerService (also with the BIND_LISTENER in the manifest.xml)
Also I have tried the PhoneService Class from this answer.
Any suggestions what I am doing wrong?
EDIT: I forgot to mention that the message gets sent from the handheld successfully, but it is not received.
EDIT 2: Could it be an issue, that my handheld module has the name "app" instead of "mobile"?! Also it is a project that i migrated from eclipse, to add the wearable feature.
So, i figured it out myself:
This project was helping.
I think the Constants made the difference. It was no path, but a randomly set constant by me. Still not sure, tho.