Search code examples
flutterdartdebuggingsetstaterelease-apk

Flutter released apk is not working but debug apk is working fine


The _getMessages() function is used to fetch SMS messages from the phone and stores them in _messages. Also, in the UI part, I have a reload button (floatingActionButton), which calls _getMessages().Now, the expected behavior is that as soon as the app is opened, the existing messages should be fetched and displayed, and for new messages which arrive later, to view them on-screen, the user can press the reload button which calls _getMessages() again and the new messages are displayed.

This code works in the debug apk, but the released apk when installed on other devices (not in debugging mode), the application doesn't work. Also, I have used Telephony to fetch messages. Is it due to the way the function and variable is defined inside the _HomeState? So, I am not sure if the error is with the code or with the package. Thanks in advance.

import 'package:OffQuiz/home/Quiz/quizCard.dart';
import 'package:OffQuiz/shared/appBar.dart';
import 'package:flutter/material.dart';
import 'package:telephony/telephony.dart';

class Home extends StatefulWidget {
  Home({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  final telephony = Telephony.instance;
  List<SmsMessage> _messages = [];

  @override
  void initState() {
    super.initState();
    _getMessages();
  }

  Future<void> _getMessages() async {
    List<SmsMessage> temp;
    temp = await telephony
        .getInboxSms(columns: [SmsColumn.ADDRESS, SmsColumn.BODY]);
    setState(() {
      _messages = temp;
    });
  }

  @override
  Widget build(BuildContext context) {
    // getMessages();

    return Scaffold(
      appBar: appBar("OffQuiz"),
      body: _messages.length != 0
          ? ListView(
              children: _messages
                  .map((quiz) => QuizCard(
                        quiz: quiz,
                      ))
                  .toList(),
            )
          : Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  Text(
                    "Please reload to fetch the latest messages",
                    style: TextStyle(
                        fontSize: 20,
                        fontWeight: FontWeight.w400,
                        color: Colors.grey),
                  ),
                ],
              ),
            ),
      floatingActionButton: FloatingActionButton(
        onPressed: _getMessages,
        child: Icon(
          Icons.refresh,
          color: Colors.white,
        ),
      ),
    );
  }
}


Solution

  • The following worked for me but you can try the following, it will most probably work in most cases.

    1. Add android/app/proguard-rules.pro
    #Flutter Wrapper
    -keep class io.flutter.app.** { *; }
    -keep class io.flutter.plugin.**  { *; }
    -keep class io.flutter.util.**  { *; }
    -keep class io.flutter.view.**  { *; }
    -keep class io.flutter.**  { *; }
    -keep class io.flutter.plugins.**  { *; }
    -keep class androidx.lifecycle.** { *; } 
    -keep @interface com.google.gson.annotations.SerializedName
    -keep @interface com.google.gson.annotations.Expose
    -keepattributes *Annotation*
     #https://github.com/flutter/flutter/issues/58479
     #https://medium.com/@swav.kulinski/flutter-and-android-obfuscation-8768ac544421
    
    1. add proguard to buildTypes in app level build.gradle
    buildTypes {
    release {
        profile {
            matchingFallbacks = ['debug', 'release']
        }
    minifyEnabled true
    useProguard true
    proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    signingConfig signingConfigs.release
    }
    }
    lintOptions {
      disable 'InvalidPackage'
      checkReleaseBuilds false
    }
    
    1. edit MainActivity.kt (the main activity kotlin file):
    import androidx.annotation.NonNull;
    import io.flutter.embedding.android.FlutterActivity
    import io.flutter.embedding.engine.FlutterEngine
    import io.flutter.plugins.GeneratedPluginRegistrant
    
    class MainActivity: FlutterActivity() {
         override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
          GeneratedPluginRegistrant.registerWith(flutterEngine);
      }
    }