Android App Consent Form Using Google's Consent SDK not Showing at All - gdprconsentform

My Android app is ready to publish, but it currently doesn't ask for user consent before loading personalized ads through a consent form. It does have a privacy and cookie policy. I downloaded the Consent SDK and imported it in the Main Activity of my app. The consentform.html doesn't show after showing the splash activity. Then the app runs normally with test ads. The Main Activity code is shown below:
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.content.Context;
import androidx.appcompat.app.AppCompatActivity;
import com.google.ads.consent.*;
import com.google.ads.consent.ConsentForm;
import com.google.ads.consent.ConsentFormListener;
import com.google.ads.consent.ConsentInfoUpdateListener;
import com.google.ads.consent.ConsentInformation;
import com.google.ads.consent.ConsentStatus;
import com.google.ads.mediation.admob.AdMobAdapter;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdView;
import com.google.android.gms.ads.MobileAds;
import com.google.android.gms.ads.initialization.InitializationStatus;
import com.google.android.gms.ads.initialization.OnInitializationCompleteListener;
import java.net.MalformedURLException;
import java.net.URL;
import static com.facebook.FacebookSdk.setAdvertiserIDCollectionEnabled;
import static com.facebook.FacebookSdk.setAutoLogAppEventsEnabled;
public class MainActivity extends AppCompatActivity {
private AdView mAdView;
private ConsentForm form;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
displayConsentForm();
ConsentInformation consentInformation = ConsentInformation.getInstance(this);
String[] publisherIDs = {"pub-8757875504565304", "173696027825328"};
consentInformation.addTestDevice(AdRequest.DEVICE_ID_EMULATOR);
// Geography appears as in EEA for test devices.
ConsentInformation.getInstance(this).
setDebugGeography(DebugGeography.DEBUG_GEOGRAPHY_EEA);
// Geography appears as not in EEA for debug devices.
ConsentInformation.getInstance(this).
setDebugGeography(DebugGeography.DEBUG_GEOGRAPHY_NOT_EEA);
consentInformation.requestConsentInfoUpdate(publisherIDs, new ConsentInfoUpdateListener() {
#Override
public void onConsentInfoUpdated(ConsentStatus consentStatus) {
// User's consent status successfully updated.
}
#Override
public void onFailedToUpdateConsentInfo(String errorDescription) {
// User's consent status failed to update.
}
});
MobileAds.initialize(this, new OnInitializationCompleteListener() {
#Override
public void onInitializationComplete(InitializationStatus initializationStatus) {
mAdView = findViewById(R.id.adviewBanner);
AdRequest adRequest = new AdRequest.Builder().build();
mAdView.loadAd(adRequest);
}
});
}
private void displayConsentForm() {
URL privacyUrl = null;
try {
privacyUrl = new URL("https://www.iubenda.com/privacy-policy/57789951");
} catch (MalformedURLException e) {
e.printStackTrace();
// Handle error.
}
// Consent form loaded successfully.
// Consent form was displayed.
// Consent form was closed.
// Consent form error.
form = new ConsentForm.Builder(MainActivity.this, privacyUrl)
.withListener(new ConsentFormListener() {
#Override
public void onConsentFormLoaded() {
// Consent form loaded successfully.
}
#Override
public void onConsentFormOpened() {
// Consent form was displayed.
}
#Override
public void onConsentFormClosed(
ConsentStatus consentStatus, Boolean userPrefersAdFree) {
// Consent form was closed.
}
#Override
public void onConsentFormError(String errorDescription) {
// Consent form error.
}
})
.withPersonalizedAdsOption()
.withNonPersonalizedAdsOption()
.withAdFreeOption()
.build();
form.load();
form.show();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.app_options, menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
//Handle item selection
int itemId = item.getItemId();
if (itemId == R.id.home) {
return true;
} else if (itemId == R.id.Paperboard) {
Intent intentPaperboard = new Intent(this, PaperboardActivity.class);
startActivity(intentPaperboard);
return true;
} else if (itemId == R.id.Cardboard) {
Intent intentCardboard = new Intent(this, CardboardActivity.class);
startActivity(intentCardboard);
return true;
} else if (itemId == R.id.stencils) {
Intent stencilIntent = new Intent(this, EmailStencilsExterior.class);
startActivity(stencilIntent);
return true;
}
return super.onOptionsItemSelected(item);
}
}```
I've imported the consent sdk 'com.google.android.ads.consent:consent-library:1.0.8'
I have a mediation group set up with just Facebook Audience Network as the only other ad source. Here is my AndroidManifest.xml file:
```<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:allowBackup="true"
android:grantUriPermissions="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme"
>
<activity
android:name=".SplashActivity"
android:theme="#style/SplashTheme">
<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.AutoLogAppEventsEnabled"
android:value="false"/>
<meta-data android:name="com.facebook.sdk.AdvertiserIDCollectionEnabled"
android:value="false"/>
<!-- Delay app measurement until MobileAds.initialize() is called. -->
<meta-data
android:name="com.google.android.gms.ads.DELAY_APP_MEASUREMENT_INIT"
android:value="true"/>
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="ca-app-pub-8757875504565304~1889665505" />
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="#string/facebook_app_id"/>
<activity android:name=".MediaPlayerActivity" />
<activity android:name=".CardboardActivity" />
<activity android:name=".PaperboardActivity" />
<activity android:name=".EmailStencilsExterior">
<intent-filter>
<action android:name="android.intent.action.SEND_MULTIPLE" />
<data android:mimeType="application/*" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>```
The logcat shows the following message after running the app:
2021-06-27 14:35:21.509 23977-23977/com.gcps.classicsplitlevel I/ConsentInformation: This request is sent from a test device.
I don't know why the consent form doesn't show after app launch. I hope I've provided enough info to assess the problem. Thanks.

Move form.show() under public void onConsentFormLoaded() like this:
#Override
public void onConsentFormLoaded() {
// Consent form loaded successfully.
form.show();
}

Related

Branch io link +clicked_branch_link is always false

I'm trying to implement Branch io links to my android app but I cant get them to work correctly. Using this guide: https://help.branch.io/developers-hub/docs/react-native
Dashboard configuration:
Android URI Scheme
https://com.example.host://
Android App links are enabled, app is selected from the play store and I have the SHA256 Cert Fingerprints entered.
Android manifest
<!-- Branch URI Scheme -->
<intent-filter>
<data android:scheme="example.scheme" android:host="open" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
<!-- Branch App Links -->
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" android:host="com.example.host"/>
<data android:scheme="https" android:host="com.example.host"/>
</intent-filter>
<!-- Branch keys -->
<!-- (Omit if setting keys in branch.json) -->
<meta-data android:name="io.branch.sdk.BranchKey" android:value="key_live_mykey"/>
<meta-data android:name="io.branch.sdk.BranchKey.test" android:value="key_test_mykey"/>
MainActivity
package com.efri_mobile;
import com.facebook.react.ReactActivity;
import com.facebook.react.ReactActivityDelegate;
import com.zoontek.rnbootsplash.RNBootSplash;
import io.branch.rnbranch.*;
import android.content.Intent;
public class MainActivity extends ReactActivity {
/**
* Returns the name of the main component registered from JavaScript. This is used to schedule
* rendering of the component.
*/
#Override
protected String getMainComponentName() {
return "efrimobile";
}
#Override
protected void onStart() {
super.onStart();
RNBranchModule.initSession(getIntent().getData(), this);
}
#Override
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
RNBranchModule.onNewIntent(intent);
}
#Override
protected ReactActivityDelegate createReactActivityDelegate() {
return new ReactActivityDelegate(this, getMainComponentName()) {
#Override
protected void loadApp(String appKey) {
RNBootSplash.init(MainActivity.this); // <- initialize the splash screen
super.loadApp(appKey);
}
};
}
}
MainApplication
package com.efri_mobile;
import android.app.Application;
import android.content.Context;
import com.facebook.react.PackageList;
import com.facebook.react.ReactApplication;
import com.oblador.vectoricons.VectorIconsPackage;
import com.oblador.vectoricons.VectorIconsPackage;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.soloader.SoLoader;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import io.branch.rnbranch.RNBranchModule;
public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost =
new ReactNativeHost(this) {
#Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
#Override
protected List<ReactPackage> getPackages() {
#SuppressWarnings("UnnecessaryLocalVariable")
List<ReactPackage> packages = new PackageList(this).getPackages();
// Packages that cannot be autolinked yet can be added manually here, for example:
// packages.add(new MyReactNativePackage());
return packages;
}
#Override
protected String getJSMainModuleName() {
return "index";
}
};
#Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
#Override
public void onCreate() {
super.onCreate();
RNBranchModule.getAutoInstance(this);
SoLoader.init(this, /* native exopackage */ false);
initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
}
/**
* Loads Flipper in React Native templates. Call this in the onCreate method with something like
* initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
*
* #param context
* #param reactInstanceManager
*/
private static void initializeFlipper(
Context context, ReactInstanceManager reactInstanceManager) {
if (BuildConfig.DEBUG) {
try {
/*
We use reflection here to pick up the class that initializes Flipper,
since Flipper library is not available in release mode
*/
Class<?> aClass = Class.forName("com.efri_mobile.ReactNativeFlipper");
aClass
.getMethod("initializeFlipper", Context.class, ReactInstanceManager.class)
.invoke(null, context, reactInstanceManager);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
App.tsx
//Read branch link
useEffect(() => {
const unsubscribe = branch.subscribe(({ error, params, uri }) => {
if (error) {
console.error('Error from Branch: ' + error);
return;
}
console.log('PARAMS: ', params, uri);
});
return () => unsubscribe();
});
I am opening the link (example.app.link) from my dashboard app by clicking on a button. App opens correctly but +clicked_branch_link is always false.
I'm Not using the test link. The live key is correctly set in my android manifest.
This is my third attempt at implementing branch links in a year, and I always had problems with this part. What am I missing? Do I need to have Branch URI scheme if I want to use App links?
After a long time, I finally found a solution that somewhat works. The branch guide is quite misleading and following it doesn't work at all.
I followed this guide: https://dev.to/chakrihacker/integrating-branch-in-react-native-0-60-3lfj
If you follow the main branch guide, make sure you change parts of that to match the ones below:
info.plist
use the following for adding keys and URL schemas
<key>branch_key</key>
<string>key_live_******</string>
<key>branch_app_domain</key>
<string>9jzhz.app.link</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>branchapp</string>
</array>
</dict>
</array>
AppDelegate
There are some different things here and in the main guide
#import <RNBranch/RNBranch.h>
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Branch
[RNBranch initSessionWithLaunchOptions:launchOptions isReferrable:YES];
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
moduleName:#"BranchExample"
initialProperties:nil];
rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
return YES;
}
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
if (![RNBranch.branch application:app openURL:url options:options]) {
// do other deep link routing for the Facebook SDK, Pinterest SDK, etc
}
return YES;
}
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray *restorableObjects))restorationHandler {
return [RNBranch continueUserActivity:userActivity];
}
Make sure you update the key, branch_app_domain and branchapp url scheme with your values
And the most important thing: USE THE QUICK LINKS!
Using the main link does not work! You must create the quick link in the branch dashboard, and use that instead!
I got it to work for IOS and android.

Users of android app are not showing up in Firebase

I made an android app and in that I just created login and registration page using firebase but when I sign up with a new account then that respective account should be recorded or it should be displayed in the user section of my Firebase But in the user section "No users are added yet" this message is displayed. Why is it so?
This is my AndroidManifest.xml.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.easylearn">
<application
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/AppTheme">
<activity android:name=".HomeActivity"></activity>
<activity android:name=".LoginActivity" />
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
This is my MainActivity.java
package com.example.easylearn;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.FirebaseAuth;
public class MainActivity extends AppCompatActivity {
EditText emailId,password;
Button btnSignUp;
TextView tvSignIn;
FirebaseAuth mFirebaseAuth;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mFirebaseAuth = FirebaseAuth.getInstance();
emailId = findViewById(R.id.editText);
password = findViewById(R.id.editText2);
btnSignUp = findViewById(R.id.button2);
tvSignIn = findViewById(R.id.textView);
btnSignUp.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String email = emailId.getText().toString();
String pwd = password.getText().toString();
if(email.isEmpty())
{
emailId.setError("Please enter email id");
emailId.requestFocus();
}
else if(pwd.isEmpty())
{
password.setError("Please enter password");
password.requestFocus();
}
else if(email.isEmpty() && pwd.isEmpty())
{
Toast.makeText(MainActivity.this,"Fiels are Empty!",Toast.LENGTH_SHORT).show();
}
else if(!(email.isEmpty() && pwd.isEmpty()))
{
mFirebaseAuth.createUserWithEmailAndPassword(email,pwd).addOnCompleteListener(MainActivity.this,
new OnCompleteListener<com.google.firebase.auth.AuthResult>() {
#Override
public void onComplete(#NonNull Task<com.google.firebase.auth.AuthResult> task)
{
if(task.isSuccessful())
{
Toast.makeText(MainActivity.this,"SignUp Unsuccessful,Please Try
Again..",Toast.LENGTH_SHORT).show();
}
else {
startActivity(new Intent(MainActivity.this,HomeActivity.class));
}
}
});
}
else
{
Toast.makeText(MainActivity.this,"Error Occured!",Toast.LENGTH_SHORT).show();
}
}
});
tvSignIn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(MainActivity.this,LoginActivity.class);
startActivity(i);
}
});
}
}
This is my LoginActivity.java
package com.example.easylearn;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.google.firebase.auth.FirebaseUser;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.FirebaseAuth;
public class LoginActivity extends AppCompatActivity {
EditText emailId,password;
Button btnSignIn;
TextView tvSignUp;
FirebaseAuth mFirebaseAuth;
private FirebaseAuth.AuthStateListener mAuthStateListener;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
mFirebaseAuth = FirebaseAuth.getInstance();
emailId = findViewById(R.id.editText);
password = findViewById(R.id.editText2);
btnSignIn = findViewById(R.id.button2);
tvSignUp = findViewById(R.id.textView);
mAuthStateListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser mFirebaseUser = mFirebaseAuth.getCurrentUser();
if(mFirebaseUser != null){
Toast.makeText(LoginActivity.this,"You are logged in",Toast.LENGTH_SHORT).show();
Intent i = new Intent(LoginActivity.this,HomeActivity.class);
startActivity(i);
}
else{
Toast.makeText(LoginActivity.this,"Please login",Toast.LENGTH_SHORT).show();
}
}
};
btnSignIn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String email = emailId.getText().toString();
String pwd = password.getText().toString();
if(email.isEmpty())
{
emailId.setError("Please enter email id");
emailId.requestFocus();
}
else if(pwd.isEmpty())
{
password.setError("Please enter password");
password.requestFocus();
}
else if(email.isEmpty() && pwd.isEmpty())
{
Toast.makeText(LoginActivity.this,"Fiels are Empty!",Toast.LENGTH_SHORT).show();
}
else if(!(email.isEmpty() && pwd.isEmpty()))
{
mFirebaseAuth.signInWithEmailAndPassword(email,pwd).addOnCompleteListener(LoginActivity.this, new
OnCompleteListener<com.google.firebase.auth.AuthResult>() {
#Override
public void onComplete(#NonNull Task<com.google.firebase.auth.AuthResult> task)
{
if(!task.isSuccessful()){
Toast.makeText(LoginActivity.this,"Login Error,Please Login
again..",Toast.LENGTH_SHORT).show();
}
else{
Intent inToHome = new Intent(LoginActivity.this,HomeActivity.class);
startActivity(inToHome);
}
}
});
}
else
{
Toast.makeText(LoginActivity.this,"Error Occured!",Toast.LENGTH_SHORT).show();
}
}
});
tvSignUp.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intSignUp = new Intent(LoginActivity.this,MainActivity.class);
startActivity(intSignUp);
}
});
}
#Override
protected void onStart() {
super.onStart();
mFirebaseAuth.addAuthStateListener(mAuthStateListener);
}
}`

Android Studio intent.getParcelableExtra is null in BroadcastReceiver

I want to send notification after reboot.
AlarmInitReceiver is normal for receiving.
But intent.getParcelableExtra can't get notification object in AlarmInitReceiver class.
I use try/catch and Toast object to describe exception message.
Thanks for everyone.
enter image description here
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.hp.test">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application
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/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name="Main2Activity"></receiver>
<receiver android:name="AlarmInitReceiver"
android:enabled="true"
android:exported="true"
android:label="StartMyServiceAtBootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
<service android:name="NofyService"/>
</application>
</manifest>
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
scheduleNotification(getNotification("123"));
}
private void scheduleNotification(Notification notification) {
final Intent notificationIntent = new Intent(this, AlarmInitReceiver.class);
notificationIntent.putExtra(AlarmInitReceiver.NOTIFICATION_ID, 1);
notificationIntent.putExtra(AlarmInitReceiver.NOTIFICATION, notification);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
//set time
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 12);
calendar.set(Calendar.MINUTE, 03);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
}
private Notification getNotification(String content) {
NotificationChannel channelMsg = new NotificationChannel(
"msg",
"Channel msg",
NotificationManager.IMPORTANCE_HIGH);
channelMsg.setDescription("socketMsg");
channelMsg.enableLights(true);
channelMsg.enableVibration(true);
NotificationManager notificationManager=(NotificationManager)getSystemService(NOTIFICATION_SERVICE);
notificationManager.createNotificationChannel(channelMsg);
Notification.Builder builder =
new Notification.Builder(this)
.setSmallIcon(android.R.drawable.ic_notification_clear_all)
.setContentTitle("TeamGoGoal")
.setContentText(content)
.setChannelId("msg");
return builder.build();
}}
AlarmInitReceiver.java
public class AlarmInitReceiver extends BroadcastReceiver {
public static String NOTIFICATION_ID = "notification-id";
public static String NOTIFICATION = "notification";
#Override
public void onReceive(Context context, Intent intent) {
try{
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = intent.getParcelableExtra(NOTIFICATION);
int id = intent.getIntExtra(NOTIFICATION_ID, 0);
notificationManager.notify(id, notification);
}
}catch(Exception e){
Toast.makeText(context,e.toString(),Toast.LENGTH_LONG).show();
}
}}

NullPointerException: Attempt to invoke virtual method 'void io.realm.Realm.beginTransaction()' on a null object reference

So I am making an app where I use an activity to introduce data about cities using Realm. I want to save the data when the floating action button is pressed but I keep getting a NullPointerExeption and when I debbug the app I see that realm in realm.beginTransaction() is null..
Can someone give an advice on why this happens? Thank you!
City class:
package com.android.bianca.cityworld2.models;
import com.android.bianca.cityworld2.app.MyApplication;
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
import io.realm.annotations.Required;
/**
* Created by Bianca on 25/01/2017.
*/
public class City extends RealmObject {
#PrimaryKey
private int id;
#Required
private String nombre;
#Required
private String description;
#Required
private String imagen;
public City(){
};
public City(String nombre, String description, String imagen) {
this.id = MyApplication.CityID.incrementAndGet();
this.nombre = nombre;
this.description = description;
this.imagen = imagen;
}
public int getID(){ return id;}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getImagen() {
return imagen;
}
public void setImagen(String imagen) {
this.imagen = imagen;
}
}
AddEditActivity:
package com.android.bianca.cityworld2.activities;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.android.bianca.cityworld2.R;
import com.android.bianca.cityworld2.models.City;
import com.squareup.picasso.Picasso;
import io.realm.Realm;
public class AddEditActivity extends AppCompatActivity {
private FloatingActionButton fabSave;
private Realm realm;
private TextView textViewNombre;
private TextView textViewDescription;
private ImageView imageViewImagen;
private TextView textViewUrlFoto;
private ImageView imageViewPreview;
private City ciudadNueva;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_edit);
Realm.init(getApplicationContext());
Realm realm = Realm.getDefaultInstance();
bindReferences();
imageViewPreview.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String imageURL = textViewUrlFoto.getText().toString();
if(imageURL.equals("")) {
Toast.makeText(AddEditActivity.this, "No has introducido ningun url", Toast.LENGTH_SHORT).show();
}else {
Picasso.with(AddEditActivity.this).load(imageURL).error(R.mipmap.ic_star).fit().into(imageViewImagen);
}
}
});
fabSave.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
crearNuevaCiudad();
}
});
}
private void crearNuevaCiudad(){
String nombre = textViewNombre.getText().toString().trim();
String desc = textViewDescription.getText().toString().trim();
String img = textViewUrlFoto.getText().toString().trim();
ciudadNueva = new City(nombre,desc,img);
realm.beginTransaction();
realm.copyToRealm(ciudadNueva);
realm.commitTransaction();
//<Toast.makeText(AddEditActivity.this, nombre + "|"+description+"|"+img, Toast.LENGTH_SHORT).show();
}
private void bindReferences(){
fabSave = (FloatingActionButton) findViewById(R.id.fabSave);
textViewNombre =(TextView) findViewById(R.id.editTextEditAddNombre);
textViewDescription =(TextView) findViewById(R.id.editTextAddEditDescription);
textViewUrlFoto =(TextView) findViewById(R.id.editTextEditAddUrl);
imageViewImagen = (ImageView) findViewById(R.id.imageViewEditAddBackground);
imageViewPreview = (ImageView) findViewById(R.id.imageViewEditAddPreview);
}
}
MyApplication:
package com.android.bianca.cityworld2.app;
import android.app.Application;
import com.android.bianca.cityworld2.models.City;
import java.util.concurrent.atomic.AtomicInteger;
import io.realm.Realm;
import io.realm.RealmConfiguration;
import io.realm.RealmObject;
import io.realm.RealmResults;
/**
* Created by Bianca on 26/01/2017.
*/
public class MyApplication extends Application {
public static AtomicInteger CityID = new AtomicInteger();
#Override
public void onCreate() {
setUpRealmConfig();
Realm realm = Realm.getDefaultInstance();
CityID = getIdByTable(realm, City.class);
realm.close();
}
private void setUpRealmConfig() {
Realm.init(this);
RealmConfiguration config = new RealmConfiguration.Builder().deleteRealmIfMigrationNeeded().build();
Realm.setDefaultConfiguration(config);
}
private <T extends RealmObject> AtomicInteger getIdByTable(Realm realm, Class<T> anyClass) {
RealmResults<T> results = realm.where(anyClass).findAll();
return (results.size() > 0) ? new AtomicInteger(results.max("id").intValue()) : new AtomicInteger();
}
}
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.bianca.cityworld2">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".activities.MainActivity">
</activity>
<activity android:name=".activities.AddEditActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

showing the last one notification push, I need show all notifications push

I'm using MobileFirst Studio Platform, for send notifications push, in the App i receive the notification, but if sent multiple notifications to my app, this only sample last notification sending.
I need show all the notifications in list in the bar notifications the device, each that i receive the notification.
This is code for function the adapter for send notification:
var applicationId="ElUniversalAppAndroid";
function sendNotification(notificationText, tag,url){
var notification = {};
notification.message = {};
notification.message.alert = notificationText;
var tags = tag.split(",");
notification.target = {};
notification.target.tagNames = tags;
// set notification properties for GCM
notification.settings = {};
notification.settings.gcm = {};
notification.settings.gcm.payload = {"url":url};
notification.settings.gcm.sound = 'sinsajo.mp3';
var delay=WL.Server.sendMessage(applicationId, notification);
WL.Logger.error("Notificacion enviada exitosamente " + JSON.stringify(notification));
return { result: "Notification sent"};
}
and I am follow example in the IBM Knowledges and support the IBM.
I am using MobileFirst Platform Studio 7.0 and Android Native Push Notifications Tags Based.
I find the answer
[Other answer same][1]
but I don't working in MobileFirst Platform Studio
Next the code the class GCMIntentService:
package com.test.eluniversal.tagsuniversal;
import java.util.Iterator;
import java.util.Queue;
import org.json.JSONObject;
import com.worklight.nativeandroid.common.WLUtils;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;
public class GCMIntentService extends
com.worklight.wlclient.push.GCMIntentService {
private NotificationObject getNotification(Intent intent) {
NotificationObject notificationObject=new NotificationObject();
com.worklight.wlclient.push.GCMIntentService.Message message=
intent.getParcelableExtra("message");
notificationObject.setId((int)System.currentTimeMillis());
String title= "TagsUniversal";
JSONObject alertJsonObject=message.getProps();
String alert=alertJsonObject.optString("alert",null);
notificationObject.setTitle(title);
notificationObject.setAlert(alert);
JSONObject payload = message.getPayload();
String url = payload.optString("url", null);
notificationObject.setUrl(url);
return notificationObject;
}
#Override
public void notify(Context context, String alert, int badge, String
sound,Intent intent) {
createNotification(context, alert, getNotificationTitle(context),
alert, badge, sound, intent);
}
#Override
public void notify(Context context, String tickerText) {
createNotification(context, tickerText,
getNotificationTitle(context),tickerText, 0, "1", null);
}
private void createNotification(Context context, String ticker,
String title, String msg, int badge,String sound,
Intent intent) {
int icon = -1;
long when = System.currentTimeMillis();
try {
icon = WLUtils.getResourceId(getApplicationContext(), "drawable",
"push");
} catch (Exception e) {
// ERROR: add icon resource
}
NotificationObject notificationObject=getNotification(intent);
NotificationCompat.Builder mBuilder = new
NotificationCompat.Builder(
this).setSmallIcon(icon).setContentTitle(notificationObject.getTitle())
.setContentText(msg);
mBuilder.setAutoCancel(true);
mBuilder.setTicker(ticker);
mBuilder.setNumber(badge);
mBuilder.setWhen(when);
Intent viewIntent = new Intent(this, ActivityPrincipal.class);
viewIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent viewPendingIntent = PendingIntent.getActivity(this, 0,
viewIntent, 0);
mBuilder.setContentIntent(viewPendingIntent);
Notification myNotification = mBuilder.build();
NotificationManagerCompat nm = NotificationManagerCompat.from(this);
nm.notify(notificationObject.getId(), myNotification);
// play notification sound, vibrate, etc...
}
}
and using next class model:
package com.test.eluniversal.tagsuniversal;
public class NotificationObject {
private int id=0;
private String title=null;
private String alert=null;
private String sound=null;
private String url=null;
private String icon=null;
public NotificationObject(){
}
public NotificationObject(int id,String title, String alert, String url){
this.id=id;
this.title=title;
this.alert=alert;
this.url=url;
}
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle( String title ) {
this.title = title;
}
public String getAlert() {
return alert;
}
public void setAlert( String alert ) {
this.alert = alert;
}
public String getSound() {
return sound;
}
public void setSound( String sound ) {
this.sound = sound;
}
public String getUrl() {
return url;
}
public void setUrl( String url ) {
this.url = url;
}
public String getIcon() {
return icon;
}
public void setIcon( String icon ) {
this.icon = icon;
}
}
and the nex is Manifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<permission android:name="com.test.eluniversal.tagsuniversal.permission.C2D_MESSAGE" android:protectionLevel="signature"/>
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS"/>
<uses-permission android:name="com.test.eluniversal.tagsuniversal.permission.C2D_MESSAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme"
android:launchMode="singleTask">
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<activity
android:name=".ActivityPrincipal"
android:label="#string/app_name"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="com.test.eluniversal.tagsuniversal.tagsUniversal.NOTIFICATION" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<service android:name="com.test.eluniversal.tagsuniversal.GCMIntentService" />
<receiver android:name="com.worklight.wlclient.push.WLBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE"/>
<category android:name="com.test.eluniversal.tagsuniversal"/>
</intent-filter>
<intent-filter>
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.test.eluniversal.tagsuniversal" />
</intent-filter>
</receiver>
</application>
and next message the error:
"Your manifest is not allowed to work with push. Android Manifest Error: Missing intent service in manifest: com.worklight.wlclient.push.GCMIntentService
Worklight/MFP does not supply this functionality built-in.
That said, you can override the default implementation and do this on your own.
Review the following blog post by Yoel Nunez which explains how to do such override and implements similar functionality: InboxStyle Notifications in Android.