alexbirukov

[Статья] PHP сервер для рассылки Push на Android и iOS

В теме 46 сообщений

В статья я максимально подробно попытался описать работу с PHP скриптом для рассылки Push сообщений из любой программы вне зависимости от платформы. Затрагивается вопроса от экспорта скриптов до кода программы: отправка и получение Push, регистрация устройств.

 

Надеюсь кому-нибудь пригодится. Буду рад комментариям, обоснованной критике и доработкам.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

чорт, я всю неделю провел, раскапывая эту тему, и то до конца не достал ))

а надо было просто немного подождать ))))

огромное спасибо за статью

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Добрый день.Статья хорошая,все подробно написано и в принципе понятно.Решил попробовать,в PHP не силен.Все сделал,регистрация устройства проходит,в таблицу заносится.Но при попытке отправки ругается вот на что:

function SendAndroid($tokens, $text, $config)
	{
		# Создаём поток для отправки с использование API ключа
		$sender = new /CodeMonkeysRu/GCM/Sender/ ($config['gcm']['apikey']);
		# Создаём сообщение для указаных токенов
		$message = new /CodeMonkeysRu/GCM/Message/ ($tokens (array("message" => $text))); 

На строке:

$sender = new /CodeMonkeysRu/GCM/Sender/ ($config['gcm']['apikey']); 

Выдает ошибку:

 

Parse error: syntax error, unexpected '/' in /public_html/push.php on line 235

 

Я вижу что ему не нравится символ '/'.Но никак не могу понять в чем подвох.

 

Изменено пользователем dante333

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Странно, у меня код всё несколько другой:

 

# Создаём поток для отправки с использование API ключа
$sender = new \CodeMonkeysRu\GCM\Sender($config['gcm']['apikey']);
# Создаём сообщение для указаных токенов
$message = new \CodeMonkeysRu\GCM\Message($tokens, array("message" => $text));

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо,теперь ошибок нет.Теперь загвоздка в другом.Я проверял регистрацию устройств через браузер,скопировал ссылку из статьи,прописал токен и id устроиства,все отлично.В БД все записывается.Теперь набросал в Delphi приложение,опять же по статье.Все скомпилировалось и установилось без ошибок,но при запуске регистрация не проходит.Манифест правил,разрешения проставил.У меня уже есть приложение с пушами через kinvey,оно работает,пуши приходят.Но хотелось бы уйти от kinvey,собственно ради этого и затеял все.

 

UPD.Пока писал,приложение компилилось еще раз и о чудо,все заработало.Спасибо за помощь.

Изменено пользователем dante333

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо,теперь ошибок нет.Теперь загвоздка в другом.Я проверял регистрацию устройств через браузер,скопировал ссылку из статьи,прописал токен и id устроиства,все отлично.В БД все записывается.Теперь набросал в Delphi приложение,опять же по статье.Все скомпилировалось и установилось без ошибок,но при запуске регистрация не проходит.Манифест правил,разрешения проставил.У меня уже есть приложение с пушами через kinvey,оно работает,пуши приходят.Но хотелось бы уйти от kinvey,собственно ради этого и затеял все.

 

UPD.Пока писал,приложение компилилось еще раз и о чудо,все заработало.Спасибо за помощь.

Собственно, от кинвей и парсе на XE10 пришлось уйти, т.к. запустить их на iOS их на новой версии не вышло. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Подскажите, пожалуйста, в чем может быть проблема?

На строке:

APushService->AppProps[TPushService_TAppPropNames_GCMAppID] = FAndroidServerKey;

Ошибка: segmentation fault 11

 

TForm1 *Form1;
const String FAndroidServerKey = L"875940064719";

void __fastcall TForm1::FormShow(TObject *Sender)
{
  APushService = nullptr;
  AServiceConnection = nullptr;

  String ADeviceID = "";
  String ADeviceToken = "";
  #if defined(__ANDROID__)
  APushService = TPushServiceManager::Instance->GetServiceByName(TPushService_TServiceNames_GCM);
  APushService->AppProps[TPushService_TAppPropNames_GCMAppID] = FAndroidServerKey;
  #endif
  #if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__))
  APushService = TPushServiceManager::Instance->GetServiceByName(TPushService_TServiceNames_APS);
  #endif

  if (APushService)
    {
		AServiceConnection = new TPushServiceConnection(APushService);
		AServiceConnection->OnChange = &OnServiceConnectionChange;
		AServiceConnection->OnReceiveNotification = &OnReceiveNotificationEvent;
		AServiceConnection->Active = true;

		ADeviceID  = APushService->DeviceIDValue[TPushService_TDeviceIDNames_DeviceID];
		ADeviceToken = APushService->DeviceTokenValue[TPushService_TDeviceTokenNames_DeviceToken];

		if(ADeviceID != "" && ADeviceToken != "")
		  {
		   RegisterDevice(ADeviceID, ADeviceToken); //global.hpp
		  }
	}

}

Весь код:


    void __fastcall OnReceiveNotificationEvent(TObject *Sender, TPushServiceNotification* const ANotification);
    void __fastcall OnServiceConnectionChange(TObject *Sender, TPushService::TChanges AChange);


private:	// User declarations
     TPushService * APushService;
	 TPushServiceConnection * AServiceConnection;

//cpp
void __fastcall TForm1::FormShow(TObject *Sender)
{
  APushService = nullptr;
  AServiceConnection = nullptr;

  String ADeviceID = "";
  String ADeviceToken = "";
  #if defined(__ANDROID__)
  APushService = TPushServiceManager::Instance->GetServiceByName(TPushService_TServiceNames_GCM);
  APushService->AppProps[TPushService_TAppPropNames_GCMAppID] = FAndroidServerKey;
  #endif
  #if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__))
  APushService = TPushServiceManager::Instance->GetServiceByName(TPushService_TServiceNames_APS);
  #endif

  if (APushService)
    {
		AServiceConnection = new TPushServiceConnection(APushService);
		AServiceConnection->OnChange = &OnServiceConnectionChange;
		AServiceConnection->OnReceiveNotification = &OnReceiveNotificationEvent;
		AServiceConnection->Active = true;

		ADeviceID  = APushService->DeviceIDValue[TPushService_TDeviceIDNames_DeviceID];
		ADeviceToken = APushService->DeviceTokenValue[TPushService_TDeviceTokenNames_DeviceToken];

		if(ADeviceID != "" && ADeviceToken != "")
		  {
		   RegisterDevice(ADeviceID, ADeviceToken); //global.hpp
		  }
	}

}
//---------------------------------------------------------------------------

void __fastcall TForm1::OnServiceConnectionChange(TObject *Sender, TPushService::TChanges AChange)
{
	if (AChange.Contains(TPushService::TChange::DeviceToken) && (AServiceConnection))
    {
        String ADeviceID = "";
        String ADeviceToken = "";
		ADeviceID = APushService->DeviceIDValue[TPushService_TDeviceIDNames_DeviceID];
		ADeviceToken = APushService->DeviceTokenValue[TPushService_TDeviceTokenNames_DeviceToken];

		if(ADeviceID != "" && ADeviceToken != "")
		  {
		   RegisterDevice(ADeviceID, ADeviceToken); //global.hpp
		  }

	}

}
//---------------------------------------------------------------------------

void __fastcall TForm1::OnReceiveNotificationEvent(TObject *Sender, TPushServiceNotification* const ANotification)
{
    //ShowMessage(ANotification->Json->ToString());

	String MessageText = "";
	//Получаем текст сообщения в зависимости ль платформы
	#if defined(__ANDROID__)
	MessageText = ANotification->DataObject->GetValue("message")->Value();
	#endif
	#if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__))
	MessageText = ANotification->DataObject->GetValue("alert")->Value();
	#endif
	if(MessageText != "")
		ShowNotification(MessageText, 0);

}

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

незнаю как на плюсах будет, в uses добавлены?

System.PushNotification
{$IFDEF ANDROID}, FMX.PushNotification.Android {$ENDIF}
{$IFDEF IOS}, FMX.PushNotification.iOS{$ENDIF}

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
//h
#include <System.PushNotification.hpp>

//cpp
#if defined(__ANDROID__)
#include <FMX.PushNotification.Android.hpp>
#endif
#if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__))
#include <FMX.PushNotification.IOS.hpp>
#endif

segmentation fault 11

и попадаем в файл System.PushNotification на строки

procedure TPushService.SetAppProp(const AName, AValue: string);
begin
  FAppProps.AddOrSetValue(AName, AValue);
end;

Что можно еще посоветовать?

Спасибо.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

в статье описано как нужно настраивать проект

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

segmentation fault 11

Ничего не помогает, все настроено так как в статье... :)

Изменено пользователем Kitty

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А в опциях проекта в окне разрешений какие галочки должны стоять? У меня там все галочки сброшены.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
1 час назад, Равиль Зарипов (ZuBy) сказал:

READ_PHONE_STATE вроде нужно

Добавила. Видимо еще какая-то настройка мною упущена. APushService = 0х0...

 

 

null1.jpg

Изменено пользователем Kitty

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вроде тут похожая проблема:

APushService is always nil

только не поняла, а что же надо сделать?...

Мой манифест в общей папке проекта 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%"
        android:installLocation="%installLocation%">

    <!-- This is the platform API where NativeActivity was introduced. -->
    <uses-sdk android:minSdkVersion="%minSdkVersion%" android:targetSdkVersion="%targetSdkVersion%" />
<%uses-permission%>

    <uses-feature android:glEsVersion="0x00020000" android:required="True"/>
    <application android:persistent="%persistent%" 
        android:restoreAnyVersion="%restoreAnyVersion%" 
        android:label="%label%" 
        android:debuggable="%debuggable%" 
        android:largeHeap="%largeHeap%"
        android:icon="%icon%"
        android:theme="%theme%"
        android:hardwareAccelerated="%hardwareAccelerated%">

<%application-meta-data%>
		<%services%>
        <!-- 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|keyboard|keyboardHidden|screenSize"
                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" /> 
        <%receivers%>
		
    </application>
</manifest>
<!-- END_INCLUDE(manifest) -->

А такой манифест AndroidManifest.xml в паке релиз:

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

    <!-- This is the platform API where NativeActivity was introduced. -->
    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="14" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <permission android:name="ua.com.mikros.Promo.permission.C2D_MESSAGE" android:protectionLevel="signature" />
    <uses-permission android:name="ua.com.mikros.Promo.permission.C2D_MESSAGE" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />


    <uses-feature android:glEsVersion="0x00020000" android:required="True"/>
    <application android:persistent="False" 
        android:restoreAnyVersion="False" 
        android:label="Promo" 
        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="Promo"
                android:configChanges="orientation|keyboard|keyboardHidden|screenSize"
                android:launchMode="singleTask">
            <!-- Tell NativeActivity the name of our .so -->
            <meta-data android:name="android.app.lib_name"
                android:value="Promo" />
            <intent-filter>  
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter> 
        </activity>
        
		<service android:name="com.embarcadero.gcm.notifications.GCMIntentService" /> 
        <receiver android:name="com.embarcadero.rtl.notifications.NotificationAlarm" />
<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="ua.com.mikros.Promo" />
</intent-filter>
</receiver>

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
2 часа назад, Kitty сказал:

Вроде тут похожая проблема:

APushService is always nil

только не поняла, а что же надо сделать?...

Мой манифест в общей папке проекта 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%"
        android:installLocation="%installLocation%">

    <!-- This is the platform API where NativeActivity was introduced. -->
    <uses-sdk android:minSdkVersion="%minSdkVersion%" android:targetSdkVersion="%targetSdkVersion%" />
<%uses-permission%>

    <uses-feature android:glEsVersion="0x00020000" android:required="True"/>
    <application android:persistent="%persistent%" 
        android:restoreAnyVersion="%restoreAnyVersion%" 
        android:label="%label%" 
        android:debuggable="%debuggable%" 
        android:largeHeap="%largeHeap%"
        android:icon="%icon%"
        android:theme="%theme%"
        android:hardwareAccelerated="%hardwareAccelerated%">

<%application-meta-data%>
		<%services%>
        <!-- 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|keyboard|keyboardHidden|screenSize"
                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" /> 
        <%receivers%>
		
    </application>
</manifest>
<!-- END_INCLUDE(manifest) -->

А такой манифест AndroidManifest.xml в паке релиз:


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

    <!-- This is the platform API where NativeActivity was introduced. -->
    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="14" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <permission android:name="ua.com.mikros.Promo.permission.C2D_MESSAGE" android:protectionLevel="signature" />
    <uses-permission android:name="ua.com.mikros.Promo.permission.C2D_MESSAGE" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />


    <uses-feature android:glEsVersion="0x00020000" android:required="True"/>
    <application android:persistent="False" 
        android:restoreAnyVersion="False" 
        android:label="Promo" 
        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="Promo"
                android:configChanges="orientation|keyboard|keyboardHidden|screenSize"
                android:launchMode="singleTask">
            <!-- Tell NativeActivity the name of our .so -->
            <meta-data android:name="android.app.lib_name"
                android:value="Promo" />
            <intent-filter>  
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter> 
        </activity>
        
		<service android:name="com.embarcadero.gcm.notifications.GCMIntentService" /> 
        <receiver android:name="com.embarcadero.rtl.notifications.NotificationAlarm" />
<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="ua.com.mikros.Promo" />
</intent-filter>
</receiver>

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

 

В чем различия?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Проблема с билдером решена и он может теперь работать с пушами. Источник: как исправить баг

У меня вопрос по статье. Вот в статье есть код:

const
  // Доменное имя сайта 
  DOMAIN: string = '193.106.248.115';

implementation


procedure RegisterDevice(DeviceID : string; DeviceToken : string);
var
  // Данные для передачи скрипту
  postdata: TStringList;
  // Подключение для передачи данных
  httpconnect : TIdHTTP;
begin

  try
    // Создаём подключение
    httpconnect := TIdHTTP.Create;
    // Указываем данные для отправки
    postdata := TStringList.Create;
    postdata.Add('action=register-device');
    postdata.Add('did=' + DeviceID);
    postdata.Add('token=' + DeviceToken);
    {$ifdef ANDROID}
      postdata.Add('platform=android');
    {$else}
      postdata.Add('platform=ios');
    {$endif}

    // Отправляем запрос
    httpconnect.Post(DOMAIN + 'push.php', postdata);
  finally
    // Отключаемся и освобождаем память
    httpconnect.Disconnect;
    httpconnect.DisposeOf;
  end;
end;

Два вопроса:

У меня, к примеру, весь PHP сервер скопирован в корень 193.106.248.115 в папку Push_Server.

1. Мне надо объявить константу так? ->

const
  // Доменное имя сайта
  DOMAIN: string = '193.106.248.115/Push_Server';

или как?

2. Не знаю паскаль. Почему нет освобождения памяти для postdata?

postdata := TStringList.Create;

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В паскале если сам создал, то и уничтожать надо самому

   IF Assigned( postdata  ) THEN BEGIN
      postdata.DisposeOf;
      postdata := Nil;
   END;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Скажите вот так будет правильно?

procedure RegisterDevice(DeviceID : string; DeviceToken : string);
var
  // Данные для передачи скрипту
  postdata: TStringList;
  // Подключение для передачи данных
  httpconnect : TIdHTTP;
begin

  try
    // Создаём подключение
    httpconnect := TIdHTTP.Create;
    // Указываем данные для отправки
    postdata := TStringList.Create;
    postdata.Add('action=register-device');
    postdata.Add('did=' + DeviceID);
    postdata.Add('token=' + DeviceToken);
    {$ifdef ANDROID}
      postdata.Add('platform=android');
    {$else}
      postdata.Add('platform=ios');
    {$endif}

    // Отправляем запрос
    httpconnect.Post(DOMAIN + 'push.php', postdata);
  finally
    // Отключаемся и освобождаем память
    httpconnect.Disconnect;
    httpconnect.DisposeOf;
    IF Assigned( postdata  ) THEN BEGIN
      postdata.DisposeOf;
      postdata := Nil;
   END; 

  end;
end;

Просто в С++ я использую при объявлении умный указатель unique_ptr и меня не волнует освобождение памяти т.к. этот указатель сам все делает и за всем следит когда освобождать правильно память.

И остаеться вопрос, как в моем случае правильно объявить

const
// Доменное имя сайта
DOMAIN: string = ?

Спасибо.

Изменено пользователем Kitty

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не используйте TIdHTTP, с ним будут проблемы. Post тоже не обязательно, вот простой работающий код :

Var AHTTPClient : THTTPClient;
	HTTPQuery : String;
begin
	HTTPQuery:=APIURL+'?DeviceID='+HDevicePushParams.DeviceID+'&DeviceToken='+HDevicePushParams.DeviceToken;
	AHTTPClient:=THTTPClient.Create;
	AHTTPClient.Get(HTTPQuery);
	AHTTPClient.Free;
end;
	

Вместо AHTTPClient.Get(HTTPQuery), можно использовать асинхронный запрос AHTTPClient.BeginGet(HTTPQuery), тогда приложение не будет записать при недоступности сервера или проблемах с связью.

Изменено пользователем Евгений Корепов

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я пытаюсь адаптировать статью этого топика. Т.е в статье присутствует .pas файл с нужным функционалом. Как этот файл будут выглядеть в окончательном виде с THTTPClient?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
В 09.04.2017 в 16:27, Kitty сказал:

const
  // Доменное имя сайта
  DOMAIN: string = '193.106.248.115/Push_Server';

Не знаю правильно ли указывать папку вместе с именем сайта, но обычно папки разделяют так

const
  // Доменное имя сайта
  DOMAIN = '193.106.248.115\Push_Server';

Изменено пользователем GASCHE

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти


  • Похожий контент

    • От Tumaso
      Подскажите, каким образом можно прочитать входящее СМС под iOS? Для Android на форуме есть работающий пример, а вот под iOS найти не удалось.
    • От YPOK5C
      Добрый день ! Кто подсказки почему при компиляции приложения под Андроид через USB выдаёт такие ошибки, при этом все apk файлы создаётся все они рабочие.  Unable to crete process unable to install Failure install failed update incompatible

    • От zekelive
      Добрый день, товарищи. Если кто сталкивался, подскажите) в потоке создаются картинкив виде плиток и прочие компоненты и падают на scrollbox.  Но в runtime пролистывание лагает, да в целом вся программа подлагивает. Можно ли как то реализовать подгрузка в фоне без ущерба? Или может ещё какой способ есть?
    • От Tumaso
      Столкнулся с неожиданной проблемой в iOS при работе с файлами: любые попытки чтения существующих файлов из System.IOUtils.TPath.GetDocumentsPath и любые попытки чтения/записи файлов в System.IOUtils.TPath.GetHomePath вызывают ошибку access denied. Где что нужно прописать, чтобы решить проблему работы с файлами?
    • От Виталий Иванов
      Ошибка при запуске программы на отладку:
       
      "
      Can't open socket: Permission denied 
      Exiting
      .
      "
       
      кто знает как побороть ? 
       
      Отладку запускаю на OnePlus3 с Android 8.0.0, драйвера Google USB переустанавливал. 

    • От Виталий Иванов
      Есть ли возможность отследить сильное нажатие на элемент ? Долгое нажатие отлавливается, а вот сильное нажатие никак может есть какие-то уловки или это в принципе не возможно ?
    • От Вольдемар
      Пользуюсь в своем Android приложении этим компонентом, вроде всё работает. Но хотелось бы асинхронности. Помогите пожалуйста с примером, как сделать асинхронность и получать результат после Post. Спасибо
    • От Barbanel
      Доброго времени!
      Есть разработанное под Андроид приложение. Начальство поставило задачу выложить это же приложение в Apple AppStore.
      Было озвучено мнение что для этого необходимо купить Макбук или что-то аналогичное эппла.
      У меня нет опыта работы с эппловскими девайсами и операционками вообще, в связи с чем вопрос:
      - какое железо необходимо для нормальной и желательно комфортной разработки под iOS?
      "Свежесть" железа играет роль (год выпуска или еще чего-нить)?
      Всем спасибо!
    • От Aptyp
      На моём Samsung Note 5 вокруг букв проглядываются линии. Причём пробовал 3 различных разрешения экрана, ничего не меняется. У друга на Xiaomi Redmi 4x такого не наблюдается.
      Что это может быть?
       


  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу