還記得 XE5/XE6 的時代嗎?透過 java code 解決了當時 delphi 尚不支援的 Splash Screen 與 GCM,那麼到了 XE7 的時代,這部分又變得如何了呢?

在 XE7 的 What's New 已經說的很清楚,「3.5 Splash Screen Support for Android

所以 XE7 是已經內建這個設定,只需要把 project 的 options 打開設定一下屬性就 ok 了,真是太方便啦...

那 GCM 呢?有沒有這麼好康的事?

話說從 XE6 開始,就支援 Baas 的後端(Kinvey and Parse),而 Baas 的後端都可以傳送 GCM/APNs 的訊息到 app,就李維大師的 demo 來看,,至少 GCM 應該沒問題才對,而且不需要修改 java code,但如果我不是用 Kinvey 或 Parse 的話呢?

就筆者對 GCM 的粗淺瞭解,既然 Kinvey 或 Parse 傳過來的 GCM 可以接收到(而且也是透過 GCM Server 發送,並非 Kinvey 或 Parse 直接發過來),那麼照理說就算不用 Kinvey 或 Parse 應該也可以收得到自建 Server 發給 GCM Server 的訊息才對,這樣的話,是不是就不用動用到 java code 了呢?

先說答案...是的,在 XE5/XE6 寫的 java code 可以丟掉了,如果沒有其他用途或是客製化需求的話

怎麼做呢?首先開啟你的 app 專案,在 project options 的部分,XE6 的時候左邊就有一個叫做「Entitlement List」的項目,但 XE6 只支援 iOS /Mac OS X 的設定,android 時,這個項目的右邊是空白一片,看看當時 wiki 的說明吧

http://docwiki.embarcadero.com/RADStudio/XE6/en/Entitlement_List

在 XE7 的時候,已經同時支援 android 的部分了,那這個是要用來做什麼的呢?看看畫面就知道

這個描述再白話不過了吧?沒錯,指的就是 app 要不要開啟接收 GCM 的設定,預設值是 false

那就把這個設定改為 true,重新編譯 apk ...立馬傳個訊息測試看看....什麼?等了半天都沒收到?

先瞧瞧 delphi 編譯時產生的 AndroidManifest.xml (注意,不是 AndroidManifest.template.xml)

<?xml version="1.0" encoding="utf-8"?>
<!-- BEGIN_INCLUDE(manifest) -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.embarcadero.pClient"
        android:versionCode="1"
        android:versionName="1.0.0">

    <!-- This is the platform API where NativeActivity was introduced. -->
    <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="11" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.CALL_PHONE" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_CALENDAR" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.WRITE_CALENDAR" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <permission android:name="com.embarcadero.pClient.permission.C2D_MESSAGE" android:protectionLevel="signature" />
    <uses-permission android:name="com.embarcadero.pClient.permission.C2D_MESSAGE" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

    <application android:persistent="False"
        android:restoreAnyVersion="False"
        android:label="pClient"
        android:installLocation="preferExternal"
        android:debuggable="True"
        android:largeHeap="False"
        android:icon="@drawable/ic_launcher"
        android:theme="@style/AppTheme"
        android:hardwareAccelerated="true">
        <!-- Our activity is a subclass of the built-in NativeActivity framework class.
             This will take care of integrating with our NDK code. -->
        <activity android:name="com.embarcadero.firemonkey.FMXNativeActivity"
                android:label="pClient"
                android:configChanges="orientation|keyboardHidden"
                android:launchMode="singleTask">
            <!-- Tell NativeActivity the name of our .so -->
            <meta-data android:name="android.app.lib_name"
                android:value="pClient" />
            <intent-filter>  
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        
        <receiver android:name="com.embarcadero.firemonkey.notifications.FMXNotificationAlarm" />
        <receiver android:exported="true"
                  android:name="com.embarcadero.gcm.notifications.GCMNotification"
                  android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.embarcadero.pClient" />
</intent-filter>
</receiver>

    </application>
</manifest>
<!-- END_INCLUDE(manifest) -->

之前文章中提到自行要修改 AndroidManifest.template.xml 的部分,XE7 都已經幫您完成嚕,只要你把上述的「Receive push notifications」設定為 true 即可!

那為啥訊息發送沒有收到呢?

經過筆者仔細比對跟推敲後,發現只要在 AndroidManifest.template.xml 增加一行即可解決此問題

<?xml version="1.0" encoding="utf-8"?>
<!-- BEGIN_INCLUDE(manifest) -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="%package%"
        android:versionCode="%versionCode%"
        android:versionName="%versionName%">

    <!-- This is the platform API where NativeActivity was introduced. -->
    <uses-sdk android:minSdkVersion="%minSdkVersion%" android:targetSdkVersion="%targetSdkVersion%" />
<%uses-permission%>
    <application android:persistent="%persistent%"
        android:restoreAnyVersion="%restoreAnyVersion%"
        android:label="%label%"
        android:installLocation="%installLocation%"
        android:debuggable="%debuggable%"
        android:largeHeap="%largeHeap%"
        android:icon="%icon%"
        android:theme="%theme%"
        android:hardwareAccelerated="%hardwareAccelerated%">
        <!-- Our activity is a subclass of the built-in NativeActivity framework class.
             This will take care of integrating with our NDK code. -->
        <activity android:name="com.embarcadero.firemonkey.FMXNativeActivity"
                android:label="%activityLabel%"
                android:configChanges="orientation|keyboardHidden"
                android:launchMode="singleTask">
            <!-- Tell NativeActivity the name of our .so -->
            <meta-data android:name="android.app.lib_name"
                android:value="%libNameValue%" />
            <intent-filter>  
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <%activity%>
        <service android:name="com.embarcadero.gcm.notifications.GCMIntentService" />
        <receiver android:name="com.embarcadero.firemonkey.notifications.FMXNotificationAlarm" />
        <%receivers%>
    </application>
</manifest>
<!-- END_INCLUDE(manifest) -->

只要加了這一行,重新編譯你的 apk 後,就可以收到訊息嚕

至於為什麼是加這行就可以解決,筆者也說不出來,畢竟這段邏輯運作應該寫在 classes.dex 裡,所以不得而知

不過 java code 真的可以丟掉嚕...

接下來繼續有什麼新發現或是 XE7 的功能再跟大家分享嚕

 

arrow
arrow
    文章標籤
    delphi XE7 GCM splash screen
    全站熱搜

    縹緲 發表在 痞客邦 留言(7) 人氣()