close

還記得 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
    全站熱搜
    創作者介紹
    創作者 縹緲 的頭像
    縹緲

    縹緲's blog

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