I have tried different solutions like giving INTERNET PERMISION in manifest file && Turning off PROGUARD by useProguard false
My app name: SMS_VOICE_NOTIFICATION
My app description: so whenever my phone receive an SMS it reads out the smsbody using Text-to-Speech, For this im using foreground service because if i use background service my system kills it after some Time.
In debug mode everything is working great, but when I start generating signed apk the broadcast receiver is not working just the UI part is working
I have registered the Broadcast Receiver like this.
public class MainActivity extends AppCompatActivity {
private MyReceiver receiver;
@Override
protected void onStart() {
IntentFilter intentFilter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
receiver = new MyReceiver();
registerReceiver(receiver,intentFilter);
super.onStart();
}
build.gradle(app)
defaultConfig {
applicationId "com.example.smsassistsigiri"
minSdkVersion 23
targetSdkVersion 30
multiDexEnabled true
versionCode 1
versionName "1.0.1"
resConfigs "en"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
useProguard false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
My build.gradle file
defaultConfig {
applicationId "com.example.smsassistsigiri"
minSdkVersion 23
targetSdkVersion 30
multiDexEnabled true
versionCode 1
versionName "1.0.1"
resConfigs "en"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
useProguard false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
My Broadcast receiver class
public class MyReceiver extends BroadcastReceiver {
private static final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
//TODO:Implement whats app text to speech
public static final String WHATS_APP_RECEIVED = "";
private static final String TAG = "SmsBroadcastReceiver";
String msg,PhoneNo = "";
@Override
public void onReceive(Context context, Intent intent) {
Log.i(TAG,"INTENT RECEIVED:"+intent.getAction());
//if(intent.getAction()==SMS_RECEIVED){
if(intent.getAction().equals(SMS_RECEIVED)){
//Retrieve a map of extended data from the intent
Bundle dataBundle = intent.getExtras();
if(dataBundle!=null){
//creating a PDU (PROTOCOL DATA UNIT)
Object[] mypdu = (Object[]) dataBundle.get("pdus");
final SmsMessage[] message = new SmsMessage[mypdu.length];
for(int i=0;i<mypdu.length;i++){
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){
//API leve > than 23
String format = dataBundle.getString("format");
message[i] = SmsMessage.createFromPdu((byte[])mypdu[i],format);
}
else{
message[i] = SmsMessage.createFromPdu((byte[])mypdu[i]);
}
msg = message[i].getMessageBody();
PhoneNo = message[i].getOriginatingAddress();
}
SmsService instance = SmsService.getInstance();
//if startservice button is not pressed then if we get a message then instance will be null so that's why we need to check for null
if(instance!=null){
instance.speak(msg);
}
Toast.makeText(context, "Message: "+msg+" nNumber: "+PhoneNo, Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(context, "Data bundle is null", Toast.LENGTH_SHORT).show();
}
}
else {
Log.e("SMSNOTRECEIVED","SMSNOTRECEIVED");
}
}
}
MainifestFile
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<application
android:name=".App"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.SMSAssist">
<receiver android:name=".MyReceiver" android:enabled="true" android:exported="true">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" ></action>
</intent-filter>
</receiver>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".SmsService"/>
</application>
2
Answers
While making signed android build obfuscation is applied which sometimes removes the necessary parts of your application code. So, attach the test device in case you are not working with an emulator and carefully watch the logcat where you can see the issue where application code is breaking.
Now you need to add exceptional cases where you don’t want to obfuscate your code. For this :
Open proguard-rules.pro file which is under your app directory somewhere below build.gradle file.
Now add exceptional cases by adding classes causing crashes like this:
-keep public class com.app.YourActivtyOrFragment { public <methods>; public <fields>; }
Is your app registered as the device’s default SMS or assistant handler? You’re no longer able to use permissions like READ_SMS unless your app is the default handler:
https://support.google.com/googleplay/android-developer/answer/10208820?visit_id=637627208051926352-3034324628&rd=1#zippy=%2Cpermitted-uses-of-the-sms-and-call-log-permissions