Android Tutorial Simple Push Framework

Discussion in 'Tutorials & Examples' started by Erel, Dec 12, 2013.

  1. Erel

    Erel Administrator Staff Member Licensed User

    It is recommended to use Firebase for new projects: FirebaseNotifications - Push messages / Firebase Cloud Messaging (FCM)

    This solution allows you to use the standard GCM push framework without an online server.

    [​IMG]

    You should first be familiar with GCM and get an API Key and Project id as explained here:
    Android push notification (GCM) framework and tutorial

    The desktop solution is based on this B4J project: Building a mini "Email based server"

    When a user registers the device, an email is sent to the desktop tool. The desktop tool then adds the device to an internal store. If the desktop tool is not online then nothing bad happens. The mail will wait until it the tool is started.

    The emails are only used for the registration process.

    Note that you can send to multiple targets at once with this solution (unlike the other solution).
    As it is written in B4J it should be simple to extend it as needed.

    In order to use it you should set the ApiKey variable in the B4J project as well as the mailbox parameters.

    You also need to set the mailbox parameters on the device (PushService) and set the SenderId in the Main module.

    Tips / Notes

    - The B4J project depends on jMsgboxes library (and other internal libraries). It also requires B4J v1.05+.
    - If you plan to distribute your app on many devices then you should probably not use a free mail service such as Gmail for the devices. You can use the default email client instead. However in that case it is better to "obfuscate" the message before sending it as the user will see the mail content.
     

    Attached Files:

    Last edited: Dec 12, 2016
    Husam, koaunglay, lemonisdead and 3 others like this.
  2. defillo

    defillo Member Licensed User

    nice work, Erel. works perfectly
    easy to send pushes from the desktop but what about pushes from device "A" to device "B" ?
     
  3. Erel

    Erel Administrator Staff Member Licensed User

    Once you have the other device registration id then it should be simple to send messages. You can use the same code as in this example to send the messages.
     
  4. pesquera

    pesquera Active Member Licensed User

    Yes! the same code works like a charm! :)
     
  5. qsrtech

    qsrtech Active Member Licensed User

    Hi I'm running into issues with GCM. I need this code converted to b4a
    Code:
    /**
    * Gets the current registration 
    ID for application on GCM service.
    * <p>
    If result is empty, the app needs to register.
    *
    * @
    return registration IDor empty string if there is no existing
    *        registration 
    ID.
    */
    private String getRegistrationId(Context context) {
        final SharedPreferences prefs = getGCMPreferences(context);
        
    String registrationId = prefs.getString(PROPERTY_REG_ID, "");
        
    if (registrationId.isEmpty()) {
            
    Log.i(TAG, "Registration not found.");
            
    return "";
        
    }
        // Check if app was updated; if so, it must clear the registration ID
        // since the existing regID is not guaranteed to work with the new
        // app version.
        int registeredVersion = prefs.getInt(PROPERTY_APP_VERSION, Integer.MIN_VALUE);
        int currentVersion = getAppVersion(context);
        if (registeredVersion != currentVersion) {
            Log.i(TAG, "App version changed.");
            return "";
        }
        return registrationId;
    }
    ...
    /**
    * @return Application's {@code SharedPreferences}.
    */
    private SharedPreferences getGCMPreferences(Context context) {
        // This sample app persists the registration ID in shared preferences, but
        // how you store the regID in your app is up to you.
        return getSharedPreferences(DemoActivity.class.getSimpleName(),
                Context.MODE_PRIVATE);
    }
     
  6. Erel

    Erel Administrator Staff Member Licensed User

    Please start a new thread for this question / issue. Also explain which issue did you encounter.
     
  7. qsrtech

    qsrtech Active Member Licensed User

    Hi, after further evaluation of the "code" I realized it just uses the "PreferenceManager". At first I thought there was a way to access the GCM framework to return the regid assigned to my app/projectid. I've ported it as needed to work for me. The issue I was having was that my regid's no longer worked all the time after the app was updated. This should resolve it. Thanks anyways.

    For those interested here's the code I used:
    Code:
    'global code module
    Sub Process_Globals
        
    'These global variables will be declared once when the application starts.
        'These variables can be accessed from all modules.
        Dim PROPERTY_REG_ID As String"registration_id"
        
    Dim PROPERTY_APP_VERSION As String"appVersion"
        
    Dim AppVersion As String
    End Sub

    Sub getRegistrationID(SenderID As StringAs Boolean
        
    Dim regid As String
        
    Dim pm As PreferenceManager
        regid=pm.GetString(SenderID)
        
    If regid="" OR AppVersion<>QSRGlobals.GetVersionname Then
            
    Log("getRegistrationID=false")
            
    Return False
        
    Else
            
    Log("getRegistrationID=true")
            
    Return True
        
    End If
    End Sub

    Sub storeRegistrationID(SenderID As String,regID As String)
        
    Dim pm As PreferenceManager
        pm.SetString(SenderID,regID)
    End Sub

    'in main activity i need to set the global appversion to the existing one stored cause I use several different GCM ProjectID's within one app so I can't update the appversion after any of them are registered cause it will affect any other potential registrations
        If FirstTime Then
            
    Dim pm As PreferenceManager
            Globals.AppVersion=pm.GetString(Globals.PROPERTY_APP_VERSION)
            
    'update with current version so next time app is started we get the last version used
            pm.SetString(Globals.PROPERTY_APP_VERSION,QSRGlobals.GetVersionname)
        
    End If

    'this is called in an activity that needs to use the push service, i.e. Activity_Create
            If Globals.getRegistrationID(ProjectID)=False Then
                CallSubDelayed3(PushService, 
    "RegisterDevice"False,ProjectID)
            
    End If

    'call this in the pushservice's HandleRegistration
                Globals.storeRegistrationID(ProjectID,rid) 'note since I use multiple projectID's this global ProjectID is set in the pushservice's 
    Sub RegisterDevice (Unregister As Boolean,pid As String)
            ProjectID=pid 
    'need this set globally cause the GCM framework doesn't return which projectid the regid that comes back is associated with
    Hope that helps someone one day...
     
    Last edited: Jan 16, 2014
  8. walterf25

    walterf25 Well-Known Member Licensed User

    Hi Thanks for this tutorial, i actually have a few questions, i can't seem to get this to work, i mean in runs fine, but when i click on the check now button, i don't see any devices, on the POP3 example, there's a string called API key where do I get that key from, i've added my gmail address along with my password, but i can't seem to get it to work, i've also installed the push program on my android device, and that works fine when i run it but i can't seem to understand the other part, can you please shed some light on this issue?

    Thanks,
    Walter
     
  9. Erel

    Erel Administrator Staff Member Licensed User

  10. walterf25

    walterf25 Well-Known Member Licensed User

    Thanks for the reply Erel, i'am actually registering my app first, but i still don't see the device name with the b4j example you're providing, am I missing something?
     
  11. Uitenhage

    Uitenhage Member Licensed User

    Love this sample. Love having a B4J app to play with.

    In addition to Server-to-Device and Device-to-Device messages can GCM be used for more than registration in a Device-to-Server scenario. I'm looking at replacing a Web Service 'polling' scheme with a push scheme where the Device has data to deliver (currently to a Web Service) as well as the Server having data for the Device. If this is possible I'd appreciate some sample code for D-to-D and D-to-S messages or links to relevant sites.
     
  12. Erel

    Erel Administrator Staff Member Licensed User

    What happens when you run the Android app and register the device? Is the registration successful? Have you set the correct mail settings in the devive app?

    @Uitenhage I'm not sure that I understand. How is the server polling the device?
     
  13. walterf25

    walterf25 Well-Known Member Licensed User

    Erel, yes the registration is succesful, i've added a log(RID) line to see the registration ID Number, so yes the registration is succesful. And yes i have set up my e-mail address and password correctly too, i'm not sure what else i could be doing wrong?
     
  14. Erel

    Erel Administrator Staff Member Licensed User

    I guess that Success variable in SMTP_MessageSent is True, right?

    It seems like the email is lost somewhere. Make sure that there isn't any other mail client that reads the mails from the server.
     
  15. SueHale

    SueHale Member Licensed User

    Hi Erel,

    Wonder if you might be able to provide some assistance with what would be an issue.

    Using two Android devices, works very well if I create two different user names. All registered via email and functions great. If use the same name on both devices can only send to one device, as in the other name is not shown (which would of course be the same in this instance)

    This could be tested by using your first name entered exactly the same on two test devices.

    Thank-you for the work put in on B4J and this interesting tutorial and any insight you can provide.

    Sue.
     
  16. Erel

    Erel Administrator Staff Member Licensed User

    In this implementation the name is the device identifier. It will not work if two devices use the same name.

    You can add the device id to the name or something like this.
     
  17. deantangNYP

    deantangNYP Member Licensed User

    Need your expertise.
    I manage to setup the following:
    Project ID: xxxx
    Project Number: yyyy
    Android API Key: zzzz or should I be generating server key for this desktop app?

    Unfortunately, just could not register my device. I will receive "INVALID_SENDER" or "Error Sending Request" message when I select "Register". May I know what is wrong?
    SenderId = Project ID or Project Number?
    Thanks
     
    Last edited: Feb 10, 2014
  18. Erel

    Erel Administrator Staff Member Licensed User

    The error you get is not related to the server. Only to the client.

    Seems like you didn't configure the SenderId value in the device app.
     
  19. deantangNYP

    deantangNYP Member Licensed User

    I think I configured the SenderId correctly, SenderID = Project ID as shown in the attachment.
    Both the PushDevice and PushDesktop need to run concurrent?
    Thanks.

     

    Attached Files:

  20. Erel

    Erel Administrator Staff Member Licensed User

    As I wrote above the error you are getting is not related to the server at all. It fails to register your Android app with Google service.

    Make sure that you are correctly following the steps here: http://developer.android.com/google/gcm/gs.html

    If it doesn't work then please start a new thread.
     
Loading...