Implementing Call recording in React Native - android

I am working on creating something to record call in my react native App.
For this I have used ReactNative Headless task to get the status of phone and react-native-audio-recorder-player for recording the call but at the end I am getting a file with no sound .
react-native-audio-recorder-player its working fine separetly when I am using this not on call but its saving a file with no sound during call.
Here is my index.js
import { AppRegistry } from 'react-native';
import App from './App';
import { name as appName } from './app.json';
import { AudioRecorder, AudioUtils } from 'react-native-audio'
import AudioRecorderPlayer from 'react-native-audio-recorder-player';
const audioRecorderPlayer = new AudioRecorderPlayer();
// const audioPath = AudioUtils.DocumentDirectoryPath + '/record.aac'
const Rec = async (data) => {
console.log(data.state)
try{
if (data.state === 'extra_state_offhook') {
const result= await audioRecorderPlayer.startRecorder().then(result=>console.log("started")).catch(err=>console.log(err))
audioRecorderPlayer.addRecordBackListener((e) => {
console.log('Recording . . . ', e.current_position);
return;
});
console.log(result);
} else if (data.state === 'extra_state_idle') {
const result = await audioRecorderPlayer.stopRecorder();
audioRecorderPlayer.removeRecordBackListener()
console.log(result);
console.log('Stopped')
}
}catch(err ){
console.log(err)
}
}
AppRegistry.registerHeadlessTask('Rec', () => Rec)
AppRegistry.registerComponent(appName, () => App);
Here is my AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.cadric">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.STORAGE"/>
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.READ_CALL_LOG"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<application android:requestLegacyExternalStorage="true" android:name=".MainApplication" android:label="#string/app_name" android:icon="#mipmap/ic_launcher" android:roundIcon="#mipmap/ic_launcher_round" android:allowBackup="false" android:usesCleartextTraffic="true" android:theme="#style/AppTheme">
<activity android:name=".MainActivity" android:label="#string/app_name" android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode" android:launchMode="singleTask" android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<action android:name="android.intent.action.DOWNLOAD_COMPLETE"/>
</intent-filter>
<intent-filter>
<action android:name="com.google.android.gms.auth.api.phone.SMS_RETRIEVED" />
</intent-filter>
</activity>
<service android:name="com.cadric.service.RecService" android:enabled="true" android:exported="true" />
<receiver android:name="com.cadric.receiver.RecReceiver" android:enabled="true" android:exported="true" android:permission="android.permission.BIND_DEVICE_ADMIN">
<intent-filter android:priority="0">
<action android:name="android.intent.action.PHONE_STATE" />
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
</application>
</manifest>
Here is my RecReciever.java file
package com.cadric.receiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.TelephonyManager;
import com.cadric.service.RecService;
import com.facebook.react.HeadlessJsTaskService;
public final class RecReceiver extends BroadcastReceiver {
public final void onReceive(Context context, Intent intent) {
Boolean incomingCall=false;
Intent recIntent = new Intent(context, RecService.class);
if (intent.getAction().equals("android.intent.action.PHONE_STATE")) {
recIntent.putExtra("action", "phone_state");
String phoneState = intent.getStringExtra("state");
if (phoneState.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
String phoneNumber = intent.getStringExtra("incoming_number");
System.out.println(phoneNumber);
incomingCall = true;
recIntent.putExtra("state", "extra_state_ringing");
recIntent.putExtra("incoming_call", true);
recIntent.putExtra("number", phoneNumber);
} else if (phoneState.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
if (incomingCall) {
incomingCall = false;
}
recIntent.putExtra("state", "extra_state_offhook");
recIntent.putExtra("incoming_call", false);
} else if (phoneState.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
if (incomingCall) {
incomingCall = false;
}
recIntent.putExtra("state", "extra_state_idle");
recIntent.putExtra("incoming_call", false);
}
} else {
recIntent.putExtra("action", "new_outgoing_call");
}
context.startService(recIntent);
HeadlessJsTaskService.acquireWakeLockNow(context);
}
}
Here is my RecService.java file
package com.cadric.service;
import android.content.Intent;
import android.os.Bundle;
import com.facebook.react.HeadlessJsTaskService;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.jstasks.HeadlessJsTaskConfig;
import javax.annotation.Nullable;
public class RecService extends HeadlessJsTaskService {
#Nullable
protected HeadlessJsTaskConfig getTaskConfig(Intent intent) {
Bundle extras = intent.getExtras();
return new HeadlessJsTaskConfig(
"Rec",
extras != null ? Arguments.fromBundle(extras) : null,
5000);
}
}
Please help me I am stucked , invested more than 20 hours in that already.

Android has strict protection on call recording. see here
Voice call + ordinary app A voice call is active if the audio mode
returned by AudioManager.getMode() is MODE_IN_CALL or
MODE_IN_COMMUNICATION.
Android shares the input audio according to these rules:
The call always receives audio. The app can capture audio if it is an
accessibility service. The app can capture the voice call if it is a
privileged (pre-installed) app with permission CAPTURE_AUDIO_OUTPUT.
To capture the voice call's uplink (TX), downlink (RX), or both, the
app must specify the audio sources
MediaRecorder.AudioSource.VOICE_UPLINK or
MediaRecorder.AudioSource.VOICE_DOWNLINK, and/or the device
AudioDeviceInfo.TYPE_TELEPHONY.
try using accessibility service. I am also trying using Native Android Kotlin but am yet unseccessful

Related

app shows "NFC services" as my program when launching from a nfc tag

Good day, actually im having trouble with my code, when i aproach a nfc tag to a nfc enabled cellphone it displays an "NFC services" instead of my app.
I have reached to the conclusion that it might be the AndroidManifest.xml, but i already modified it to get mime events from an intent-filter, here are the code:
app.component.ts
import firebase from 'firebase';
import { Component, ViewChild } from '#angular/core';
import {Keyboard} from '#ionic-native/keyboard';
import { Platform, Nav, App, AlertController} from 'ionic-angular';
import { StatusBar } from '#ionic-native/status-bar';
import { SplashScreen } from '#ionic-native/splash-screen';
import { WelcomePage } from '../pages/welcome/welcome';
import { LoginPage } from '../pages/login/login';
import { PpPage } from '../pages/menu/pago/pp/pp';
import { NosotrosPage } from '../pages/menu/nosotros/nosotros';
import { ConfigPage } from '../pages/menu/config/pp/config';
import { SavlistPage } from '../pages/savlist/savlist';
import { AuthService } from '../services/auth';
import { MenuController } from 'ionic-angular';
import { InicioPage } from '../pages/inicio/inicio';
import { Observable } from 'rxjs';
import { AngularFireDatabase } from 'angularfire2/database';
import { Toast } from '#ionic-native/toast';
import { NFC } from '#ionic-native/nfc';
import { window } from 'rxjs/operator/window';
import { Message } from '#angular/compiler/src/i18n/i18n_ast';
#Component({
templateUrl: 'app.html'
})
export class MyApp {
#ViewChild(Nav) nav:Nav;
rootPage: any = WelcomePage;
rootPageParams: any;
loginPage: LoginPage;
users: Observable<any>;
usdata: any = "npc";
name: string;
showSplash = true;
isAthenticated = false;
constructor(platform: Platform, statusBar: StatusBar,
splashScreen: SplashScreen,
private menuCtrl: MenuController,
private authService: AuthService,
private af: AngularFireDatabase,
private app: App,
private alrtCtrl: AlertController,
private toast: Toast,
public keyboard: Keyboard,
public nfc: NFC)
{
if (!firebase.apps.length)
{
firebase.initializeApp({
apiKey: "XXXXXX",
authDomain: "XXXXXXXX",
databaseURL: "XXXXXXXX",
projectId: "XXXXXX",
storageBucket: "XXXXXX",
messagingSenderId: "XXXXXXXX"
});
}
firebase.auth().onAuthStateChanged( user => {
if(user)
{
this.isAthenticated = true;
this.rootPage = InicioPage;
this.nfc.addNdefListener().subscribe((data)=>{
console.log(data)
});
this.nfc.addMimeTypeListener('text/plain').subscribe((data)=>{
console.log(data)
});
try
{
this.usdata = firebase.auth().currentUser.email;
}
catch(e)
{
console.log("No ha iniciado sesion");
}
this.users = this.af.object("/users").valueChanges();
this.users.subscribe(data => {
for (let p in data)
{
let value = data[p];
if (value.correo_u == this.usdata)
{
this.name = value.name_u;
}
}
});
}
else
{
this.nfc.addNdefListener().subscribe((data)=>{
let payload = data.tag.ndefMessage[0].payload;
let tagContent = this.nfc.bytesToString(payload).substring(3);
console.log(data)
this.alrtCtrl.create({
message: tagContent,
}).present();
});
this.nfc.addMimeTypeListener('text/plain').subscribe((data)=>{
console.log(data)
this.alrtCtrl.create({
message: data,
}).present();
});
this.isAthenticated = false;
this.rootPage = WelcomePage;
}
});
platform.ready().then(() => {
statusBar.styleDefault();
splashScreen.hide();
this.keyboard.disableScroll(true);
});
platform.registerBackButtonAction(() => {
// Catches the active view
let nav = app.getActiveNav();
let activeView = nav.getActive();
// Checks if can go back before show up the alert
if (activeView.name == 'InicioPage')
{
platform.exitApp();
}
if (activeView.name == 'WelcomePage')
{
platform.exitApp();
}
if(activeView.name == 'ListsPage')
{
activeView.instance.volver();
}
else
{
activeView.dismiss();
}
});
}
AndroidManifest.xml
<?xml version='1.0' encoding='utf-8'?> <manifest android:hardwareAccelerated="true" android:versionCode="1" android:versionName="0.0.1" package="XXXXXXXXXX" xmlns:android="http://schemas.android.com/apk/res/android">
<supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:resizeable="true" android:smallScreens="true" android:xlargeScreens="true" />
<uses-permission android:name="android.permission.INTERNET" />
<application android:hardwareAccelerated="true" android:icon="#mipmap/icon" android:label="#string/app_name" android:supportsRtl="true">
<activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale" android:label="#string/activity_name" android:launchMode="singleTop" android:name="MainActivity" android:theme="#android:style/Theme.DeviceDefault.NoActionBar" android:windowSoftInputMode="adjustResize">
<intent-filter android:label="#string/launcher_name">
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<data android:mimeType="text/plain" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<provider android:authorities="${applicationId}.provider" android:exported="false" android:grantUriPermissions="true" android:name="org.apache.cordova.camera.FileProvider">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="#xml/camera_provider_paths" />
</provider>
<activity android:clearTaskOnLaunch="true" android:configChanges="orientation|keyboardHidden|screenSize" android:exported="false" android:name="com.google.zxing.client.android.CaptureActivity" android:theme="#android:style/Theme.NoTitleBar.Fullscreen" android:windowSoftInputMode="stateAlwaysHidden" />
<activity android:label="Share" android:name="com.google.zxing.client.android.encode.EncodeActivity" />
<meta-data android:name="com.google.android.geo.API_KEY" android:value="XXXXXXXXXXXXXXX" />
<meta-data android:name="com.google.android.gms.version" android:value="#integer/google_play_services_version" />
<uses-library android:name="org.apache.http.legacy" android:required="false" />
<service android:enabled="true" android:exported="false" android:name="com.google.android.gms.measurement.AppMeasurementService" />
<service android:name="org.apache.cordova.firebase.FirebasePluginMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service android:name="org.apache.cordova.firebase.FirebasePluginInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
<receiver android:name="org.apache.cordova.firebase.OnNotificationOpenReceiver" />
</application>
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="27" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-feature android:name="android.hardware.camera" android:required="true" />
<uses-permission android:name="android.permission.NFC" />
<uses-feature android:name="android.hardware.nfc" android:required="false" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-feature android:name="android.hardware.location.gps" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
<uses-feature android:name="android.hardware.location" />
<uses-permission android:name="android.permission.WAKE_LOCK" /> </manifest>
and this is what it shows:
services
I alredy searched from this sources:
App called "NFC services" replacing my own app
Launching app from NFC tag reading
https://github.com/don/nfc-launch/blob/master/README.md
https://github.com/chariotsolutions/phonegap-nfc/issues/57
Ionic:
ionic (Ionic CLI) : 4.10.2
System:
NodeJS : v10.14.2 npm : 6.7.0 OS : Linux 4.15
phonegap-nfc 1.0.3 "NFC"
Cordova version: 8.1.1

Android FCM Push Notification not received when app is closed

I implemented FCM Push Notifications. The main problem is when app is closed, notifications not arrive when this happen on device.
I tried a lot of thigs for that works; when notification sent the server response with "success", but I never received.
This is full code. Android, Manifiest and server.
Android:
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.BitmapDrawable;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import com.accionait.canje365.R;
import com.accionait.canje365.activities.ChatActivity;
import com.accionait.canje365.activities.HomeActivity;
import com.accionait.canje365.constants.Constants;
import com.google.firebase.messaging.RemoteMessage;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
public class FirebaseMessagingService extends com.google.firebase.messaging.FirebaseMessagingService {
private static final String TAG = "FCM Service";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
showNotification(remoteMessage);
}
private void showNotification(RemoteMessage remoteMessage) {
Uri uriDefaultSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext())
.setSmallIcon(R.mipmap.ic_notification)
.setLargeIcon((((BitmapDrawable)getResources().getDrawable(R.mipmap.ic_notification)).getBitmap()))
.setContentTitle("TITLE")
.setContentText("MESSAGE")
.setContentInfo("0")
.setAutoCancel(true)
.setTicker("Canje365")
.setSound(uriDefaultSound);
Intent home = new Intent(this, HomeActivity.class);
home.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent intent = PendingIntent.getActivity(this, 0, home, PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(intent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(1, builder.build());
}
}
Server:
var message = {
to: token,
data: {valor: 'test'}
};
fcm.send(message, function(err, response){
if(err) {
console.log('Error: ' + err);
}
else {
console.log('Notificacion enviada: ', response);
}
});
Manifiest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.accionait.canje365">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<service android:name=".sync.RunIntentService" />
<service android:name=".sync.FirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service android:name=".sync.FirebaseIdService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="MY_API_KEY" />
<activity
android:name=".activities.MainActivity"
android:theme="#style/SplashScreenTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".activities.HomeActivity"
android:label="#string/title_activity_login"
android:screenOrientation="portrait">
</activity>
</application>
</manifest>
What to do with this?
In my case I have a Huawei P8 Lite and to allow to be run on the background.
This is the link where You can to find detail abount this case.
Solution on Huawei devices
I faced the same problem. Its a problem in many phone models. I'm just writing this so that out there if anyone faces the same problem can waste a little less time searching for this problem because I wasted a lot!
Android M and above devices have battery optimization enabled by default for all apps, which usually stops the background services of our apps. We just have to ask user to disable them, if user choose not to disable them, then I'm sorry..i don't think user is really happy with your app functionality. In order to ask user to enable that--->
Intent intent = new Intent();
String packageName = getPackageName();
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (pm != null && pm.isIgnoringBatteryOptimizations(packageName))
intent.setAction(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
else {
intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + packageName));
}
}
startActivity(intent);

GCM message sent from node-gcm server but not received

this is the result in node-gcm server
**
{ multicast_id: 5309930915296650000,
success: 1,
failure: 0,
canonical_ids: 0,
results: [ { message_id: '0:1410197314824005%31e4cc17f9fd7ecd' } ] }
**
and my server code in which i retrieve reg_ids from my mongoDb and store them in a string array and pass it to the send method
exports.create = function ( req, res ){
new Comment({
// username : req.body.username,
content : req.body.comment,
created : Date.now()
}).save( function( err, comment, count ){
res.redirect( '/' );
});
reg_ids=[];
User.find({},'gcm_id',function(err,res)
{
for(i=0;i<res.length;i++)
{
reg_ids.push(res[i].gcm_id);
console.log(i+'th entry is '+res[i].gcm_id+'\n');
}
// reg_ids=res.toArray();
var message = new gcm.Message();
message.delay_while_idle = 1;
message.addDataWithKeyValue('message',req.body.comment);
sender.send(message, reg_ids, 4, function (err, result) {
console.log(result);
});
});
};
everything in the server seems fine
and my receiver
here i placed a Log.D to check if receiver is triggered
but it was not
package com.javapapers.android;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.support.v4.content.WakefulBroadcastReceiver;
import android.util.Log;
public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("receiver", "received");
ComponentName comp = new ComponentName(context.getPackageName(),
GCMNotificationIntentService.class.getName());
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}
and finally my manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.javapapers.android"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<permission
android:name="com.javapapers.android.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.javapapers.android.permission.C2D_MESSAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-sdk
android:minSdkVersion="9"
android:targetSdkVersion="16" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
>
<activity
android:name=".RegisterActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.javapapers.android.MainActivity"
android:configChanges="orientation|keyboardHidden"
android:label="#string/app_name" >
</activity>
<receiver
android:name=".GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<action android:name="com.google.android.c2dm.intent.GCM_RECEIVED_ACTION"/>
<category android:name="com.javapapers.android" />
</intent-filter>
</receiver>
<service android:name=".GCMNotificationIntentService" />
</application>
</manifest>
i've been struck with this from a long time
I would be thankful if someone could help
You have to add the message key and value in order for the message to send.
Like so:
message.addData('message', 'push notification worked');

GCM doesn't receive messages in android 2.3.6 but works in android 4.1.2

I don't know where is the problem with my manifest, the problem is only with android 2.3.6. In my tablet with android 4.1.2 it's receiving the messages. I have received the registration ID with 2.3.6 but the messages are never received. Please,someone could help me?:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ciqtech.quicky.mobile.passenger"
android:versionCode="1"
android:versionName="1.0"
android:installLocation="preferExternal">
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<permission
android:name="com.ciqtech.quicky.mobile.passenger.permission.MAPS_RECEIVE"
android:protectionLevel="signature" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="com.ciqtech.quicky.mobile.passenger.permission.MAPS_RECEIVE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!--
GCM CONFIGURATION
-->
<permission android:name="com.ciqtech.quicky.mobile.passenger.permission.C2D_MESSAGE"
android:protectionLevel="signature"/>
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="com.ciqtech.quicky.mobile.passenger.permission.C2D_MESSAGE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_GPS"/>
<uses-permission android:name="android.permission.ACCESS_LOCATION"/>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/Theme.Sherlock" >
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="..." />
<activity
android:name="com.ciqtech.quicky.mobile.passenger.activities.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="#string/app_id" />
<activity android:name="com.facebook.LoginActivity" >
</activity>
<activity
android:name="com.ciqtech.quicky.mobile.passenger.activities.PassengerActivity"
android:label="#string/title_activity_passenger" >
</activity>
<activity
android:name="com.ciqtech.quicky.mobile.passenger.activities.LoginActivity"
android:label="#string/title_activity_login" >
</activity>
<!-- GCM
RECEIVER
-->
<receiver
android:name="com.ciqtech.quicky.mobile.passenger.broadcast_receivers.QuickyGCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.ciqtech.quicky.mobile.passenger" />
</intent-filter>
</receiver>
<service android:name=".services.GCMIntentService" android:enabled="true" />
</application>
</manifest>
UPDATE
QuickyGCMBroadcastReceiver
package com.ciqtech.quicky.mobile.passenger.broadcast_receivers;
import com.ciqtech.quicky.mobile.passenger.services.GCMIntentService;
import com.google.android.gcm.GCMBroadcastReceiver;
import android.content.Context;
import android.util.Log;
public class QuickyGCMBroadcastReceiver extends GCMBroadcastReceiver {
final String TAG = "QuickyGCMBroadcastReceiver";
#Override
protected String getGCMIntentServiceClassName(Context context) {
Log.d(TAG, "GET GCM INTENT SERVICE CLASS NAME");
return GCMIntentService.class.getName();
}
}
GCMIntentService. The device register correctly in android 2.3.x but it doesn't receive the messages, my message log on onMessage isn't never called, while in android 4.1.x it works perfectly. Thanks for your help.
package com.ciqtech.quicky.mobile.passenger.services;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Vibrator;
import android.provider.Settings.Secure;
import android.support.v4.app.NotificationCompat;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import com.ciqtech.quicky.mobile.passenger.R;
import com.ciqtech.quicky.mobile.passenger.activities.LoginActivity;
import com.ciqtech.quicky.mobile.passenger.activities.PassengerActivity;
import com.ciqtech.quicky.mobile.passenger.broadcast_receivers.Device;
import com.ciqtech.quicky.mobile.passenger.configs.GCMSettings;
import com.ciqtech.quicky.mobile.passenger.dto.NotificationDTO;
import com.ciqtech.quicky.mobile.passenger.utils.SessionManager;
import com.google.android.gcm.GCMBaseIntentService;
import com.google.android.gms.gcm.GoogleCloudMessaging;
public class GCMIntentService extends GCMBaseIntentService {
Context ctx;
SharedPreferences prefs;
final String TAG = "GCMIntentService";
NotificationCompat.Builder builder;
public GCMIntentService() {
super(GCMSettings.GCM_SENDER);
}
#Override
public void onError(Context context, String errorId) {
Log.d(TAG + " - onError", "Messaging registration error: " + errorId);
}
#Override
protected boolean onRecoverableError(Context context, String errorId) {
Log.d(TAG + "- onRecoverableError", "Received recoverable error: " + errorId);
return super.onRecoverableError(context, errorId);
}
#Override
protected void onMessage(Context context, Intent intent) {
String msg = intent.getExtras().getString( "msg" );
Log.d(TAG, " - onMessage: " + msg);
// [more code]
}
// Put the GCM message into a notification and post it.
private void sendNotification(String msg) {
}
#Override
public void onRegistered(Context context, String registrationId) {
Log.d(TAG + " - onRegistered", "onRegistered()");
prefs = context.getSharedPreferences("Quickytaxi-Notifications",0);
String deviceID = Secure.getString(context.getContentResolver(), Secure.ANDROID_ID);
SessionManager session = new SessionManager(context);
String uid = session.getUserDetails().get("id");
Log.d(TAG, deviceID + " " + registrationId + " " + uid);
Device.register(deviceID, registrationId, uid);
}
#Override
protected void onUnregistered(Context context, String s) {
Log.d(TAG + "- onUnregistered", "onUnregistered()");
String deviceID = Secure.getString(context.getContentResolver(), Secure.ANDROID_ID);
Device.unregister(deviceID);
}
public void notify(NotificationDTO notificationDTO, Intent intent){
}
}
Try following workaround not using (so far as I know) any deprecated classes. Add the action "com.google.android.c2dm.intent.REGISTRATION" to the GCMBroadcastReceiver in your manifest. This will enable to receive the registration_id at your GCMBroadcastReceiver.
<receiver
android:name="YOUR_PACKAGE_NAME.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="YOUR_PACKAGE_NAME" />
</intent-filter>
</receiver>
After that your GCMBroadcastReceiver is able to receive the registration_id:
public void onReceive(Context context, Intent intent)
{
String regId = intent.getExtras().getString("registration_id");
if(regId != null && !regId.equals(""))
{
/* Do what ever you want with the regId eg. send it to your server */
}
}
Although I still get a SERVICE_NOT_AVAILABLE error, I can handle the registration_id in my GCMBroadcastReceiver and I am able to send messages to my smartphone. Quite weird, but it works for me.
I was facing same problem from last one week but simple solutions is Android.Manifest File Changes.You have added only two permissions for C2D_MESSAGE but it required three.
<permission android:name="com.ciqtech.quicky.mobile.passenger.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="com.ciqtech.quicky.mobile.passenger.permission.C2D_MESSAGE" />
<uses-permission android:name="android.permission.C2D_MESSAGE" />
It will work for all android versions.
Ensure that your package name specified in the manifest matches the category name specified in the GCM receiver configuration. According to the manifest provided Your package name should look as below :
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ciqtech.quicky.mobile.passenger"
android:versionCode="1"
android:versionName="1.0" >
Similar question can be found here GCM Push RECEIVE category Name on Android OS < 4.1. Hope that helps.

Android checking Wifi on every onRestart

I want my app to check whether the device is connecting to a specific Wifi and auto connect to the Wifi whenever the app is navigated to. I know that I can do it in onRestart(). But it only handles one activity's state.
My question is if there any method to handle the state of the app instead of adding onRestart() on every activity to do what i want?
try the following code:
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
public class AutostartService extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
System.out.println("in broad....");
ConnectivityManager manager = (ConnectivityManager)context.getSystemService(context.CONNECTIVITY_SERVICE);
boolean is3g = manager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).isConnectedOrConnecting();
boolean isWifi = manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI).isConnectedOrConnecting();
if(!is3g && !isWifi){
}else{
if ((intent.getAction() != null) && (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")))
{
System.out.println("in broadcast receiver.....");
Intent i = new Intent(context, Splash.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
}
}
dont forget to add this in your manifest file:
<receiver android:name=".AutostartService" android:enabled="true" android:exported="true">
- <intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
and the following permissions in manifest file:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

Categories

Resources