2016-11-22 4 views
3

Я делаю приложение VOIP, когда поступает входящий звонок, и приложение находится на переднем плане. Я играю Рингера с кодом нижеКак сохранить вибрацию устройства в фоновом режиме

self.ringTimer = [[TimerService sharedInstance] createIntervalTimerWithInterval:2500 queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) andBlock:^{ 
    AudioServicesPlayAlertSound(kSystemSoundID_Vibrate); 
}]; 

NSString *ringingPath = [[NSBundle mainBundle] pathForResource:@"incoming_sound" ofType:@"mp3"]; 

AVAudioSession *audioSession = [AVAudioSession sharedInstance]; 
[audioSession setCategory:AVAudioSessionCategoryAmbient withOptions:AVAudioSessionCategoryOptionAllowBluetooth | AVAudioSessionCategoryOptionMixWithOthers error:nil]; 

// for normal phone receiver route it to speaker 
if ([[audioSession audioRoute] isEqualToString:kAudioSessionDevice_Phone]) { 
    [audioSession overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:nil]; 
} 

NSURL *soundUrl = [NSURL fileURLWithPath:ringingPath]; 
NSError *error; 
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:soundUrl error:&error]; 

self.audioPlayer.numberOfLoops = -1; 
[self.audioPlayer play]; 

Приведенный выше код работает хорошо, и он также уважать кнопку бесшумный переключатель при воспроизведении звука.

Однако, если я скрою приложение, устройство перестанет вибрировать и воспроизводит входящий звук. Это можно преодолеть, если я установил AVAudioSession категории в AVAudioSessionCategoryPlayback, но эта категория не будет молчать звук при включенном тихом переключателе.

Я вижу другие приложения, такие как

Line

  • (прием входящего в приложение), они могут держать вибрировать устройство после того, как минимизировать до тайм-аута вызова не будет достигнут (ни одного ответа) об одном минута без уведомления перед остановкой уведомления (получение уведомления о завершении вызова).
  • (Получать входящие, когда приложение закрыто), они также делают то же самое, потому что, когда я отклоняю уведомление, устройство все еще может вибрировать в течение одной и той же продолжительности.

Facebook Messenger

  • (Прием входящих в приложении) они показывают длинное уведомление, чтобы сохранить вибросигнал. Если я отклоню это уведомление, он сразу же остановится.

  • (прием входящего, когда приложение закрыто), если я отклонить уведомление, вибрации устройства для более 2-3 раз и показать длинное уведомление (то же самое, как если принимать входящие в приложение)

Viber , Skype

  • (Прием входящего в приложение) Я не уверен в скайпе, но для Viber, когда минимизировать приложение его остановить вибрировать мгновенно.

  • (прием входящего, когда приложение закрыто), я думаю, что они сделали так же, как facebook (не уверен)

Как я могу сделать вибросигнал без уведомления, как Line при минимизации приложения?

Если мне удастся найти способ и заставить его работать как Line мне нужно использовать Voip push, когда приложение не находится на переднем плане для реализации этого метода? (Будет ли работать обычное push-уведомление?)

+0

Используете ли вы push-уведомление или Pushkit (Silent push notification)? – Hasya

+0

Это сработало? – Hasya

+0

@Hasya Извините, у вас нет времени изучить это. Мне удается заставить его работать без 'PushKit' для' Receive входящего в приложение' (Держите вибрировать устройство при минимизации). Но для того, что за пределами приложения, я думаю, что 'PushKit' требуется. Будут следовать вашему предложению и дать отзыв в выходные дни. – SaintTail

ответ

2

Вы должны использовать pushkit (молчащее push-уведомление).

Для применения в фоновом режиме или состоянии смерти.

Skype, whatsapp, viber etc Приложение на основе VOIP работает как архитектура ниже.

Когда вы получаете полезную нагрузку, вам необходимо запланировать локальное уведомление. вы можете установить звуковой файл в локальном уведомлении. этот звуковой файл воспроизводится в течение 30 секунд макс. Если вы хотите повторить звуковой файл до тех пор, пока конечные пользователи не получат или не отклонят вызов, который вы также можете сделать с управлением флагом и повторной локализацией уведомлений.

Используйте нижестоящую структуру для достижения своей задачи.

Используйте этот simplepush.php файл

<?php 

// Put your device token here (without spaces): 


     $deviceToken = '123456789'; 
// 


// Put your private key's passphrase here: 
$passphrase = 'ProjectName'; 

// Put your alert message here: 
$message = 'My first push notification!'; 



$ctx = stream_context_create(); 
stream_context_set_option($ctx, 'ssl', 'local_cert', 'PemFileName.pem'); 
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase); 

// Open a connection to the APNS server 
$fp = stream_socket_client(
// 'ssl://gateway.push.apple.com:2195', $err, 
    'ssl://gateway.sandbox.push.apple.com:2195', $err, 
    $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx); 

if (!$fp) 
    exit("Failed to connect: $err $errstr" . PHP_EOL); 

echo 'Connected to APNS' . PHP_EOL; 

// Create the payload body 

$body['aps'] = array(
        'content-available'=> 1, 
        'alert' => $message, 
        'sound' => 'default', 
        'badge' => 0, 
        ); 



// Encode the payload as JSON 

$payload = json_encode($body); 

// Build the binary notification 
$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload; 

// Send it to the server 
$result = fwrite($fp, $msg, strlen($msg)); 

if (!$result) 
    echo 'Message not delivered' . PHP_EOL; 
else 
    echo 'Message successfully delivered' . PHP_EOL; 

// Close the connection to the server 
fclose($fp); 

Использование ниже команды для создания файла PEM и использовать его в коде выше

$ openssl x509 -in aps_development.cer -inform der -out PushCert.pem 

# Convert .p12 to .pem. Enter your pass pharse which is the same pwd that you have given while creating the .p12 certificate. PEM pass phrase also same as .p12 cert. 
$ openssl pkcs12 -nocerts -out PushKey1.pem -in pushkey.p12 

Enter Import Password: 

MAC verified OK 

Enter PEM pass phrase: 

Verifying - Enter PEM pass phrase: 

# To remove passpharse for the key to access globally. This only solved my stream_socket_client() & certificate capath warnings. 
$ openssl rsa -in PushKey1.pem -out PushKey1_Rmv.pem 

Enter pass phrase for PushChatKey1.pem: 

writing RSA key 

# To join the two .pem file into one file: 
$ cat PushCert.pem PushKey1_Rmv.pem > ApnsDev.pem 

После этого перейдите на simplepush.php расположение и пожарной команды -> php simplepush.php

Таким образом, вы можете протестировать свою архитектуру установки уведомлений об установочном наборе.

https://zeropush.com/guide/guide-to-pushkit-and-voip

https://www.raywenderlich.com/123862/push-notifications-tutorial

Download

import UIKit 
import PushKit 


class AppDelegate: UIResponder, UIApplicationDelegate,PKPushRegistryDelegate{ 



func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 


    let types: UIRemoteNotificationType = [.Alert, .Badge, .Sound] 
    application.registerForRemoteNotificationTypes(types) 

    self. PushKitRegistration() 

    return true 
} 



//MARK: - PushKitRegistration 

func PushKitRegistration() 
{ 

    let mainQueue = dispatch_get_main_queue() 
    // Create a push registry object 
    if #available(iOS 8.0, *) { 

     let voipRegistry: PKPushRegistry = PKPushRegistry(queue: mainQueue) 

     // Set the registry's delegate to self 

     voipRegistry.delegate = self 

     // Set the push type to VoIP 

     voipRegistry.desiredPushTypes = [PKPushTypeVoIP] 

    } else { 
     // Fallback on earlier versions 
    } 


} 


@available(iOS 8.0, *) 
func pushRegistry(registry: PKPushRegistry!, didUpdatePushCredentials credentials: PKPushCredentials!, forType type: String!) { 
    // Register VoIP push token (a property of PKPushCredentials) with server 

    let hexString : String = UnsafeBufferPointer<UInt8>(start: UnsafePointer(credentials.token.bytes), 
     count: credentials.token.length).map { String(format: "%02x", $0) }.joinWithSeparator("") 

    print(hexString) 


} 


@available(iOS 8.0, *) 
func pushRegistry(registry: PKPushRegistry!, didReceiveIncomingPushWithPayload payload: PKPushPayload!, forType type: String!) { 
    // Process the received push 
    // From here you have to schedule your local notification 

} 

} 

Параллельно, если вы настроите Оправа архитектуры. Затем Socket используется для трансляции данных, например, пользователи в режиме онлайн/офлайн, и вам нужно знать, не вызывая API, тогда вы можете использовать сокет, архитектура сокетов на сервере будет отправлять данные на пользователя онлайн/оффлайн на устройства без запроса с устройства.

Сообщите мне, если я могу помочь вам где-нибудь.

Успешное кодирование.

+0

Я заставляю его работать и добавляю ответ, чтобы включить, как вибрировать устройство в фоновом режиме. Благодарю. – SaintTail

0

После некоторого теста я нашел способ, как это сделал Line.

Прием входящего вызова в приложении

Они используют

[[UIApplication sharedApplication] beginBackgroundTaskWithName:expirationHandler:]

держать приложение вибрировать, даже если вы уже свести его к минимуму. Этот метод будет поддерживать приложение и иметь продолжительность продолжительностью 180 секунд до истечения срока действия.

Прием входящего вызова, когда приложение закрыто

Это нужно использовать PushKit, как @Hasya упоминанием сделать приложение бодрствует, а также вызвать тот же метод, что и выше сценарии (держать вибросигнал)

[[UIApplication sharedApplication] beginBackgroundTaskWithName:expirationHandler:]

На этот раз он истечет через 40 вместо 180 секунд. Также вы не можете воспроизводить входящий звук через AVAudioPlayer с номером Ambient.

Поэтому вам необходимо прикрепить звук (требуется расширенная версия, так как для вас нет функции повторения) до UILocalNotification, который я где-то читал, чтобы вы могли воспроизводить звук до 30 секунд.

Некоторое беспокойство при использовании PushKit

Если у вас есть старые системы, которые используют APNS вам нужно сохранить как маркер (APN, и VOIP) на стороне сервера. Потому что вы не можете отправить токен APNS с сертификатом VOIP. Маркер должен быть отправлен с типом правильного сертификата.

Смежные вопросы