簡體   English   中英

如何在后台保持振動設備

[英]How to keep vibrate device in the background

我正在做一個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但是當靜音開關打開時此類別不會使聲音靜音,這可以克服。

我看到其他應用程序

  • (在應用程序中接收傳入)他們可以在最小化之后繼續振動設備,直到達到呼叫超時(沒有人應答)大約一分鍾而沒有通知顯示在停止之前(接收呼叫結束通知)。
  • (當應用程序關閉時接收傳入)他們也會這樣做,因為當我解除通知時,設備仍然可以振動相同的持續時間。

Facebook Messenger

  • (在應用程序中接收傳入)他們會顯示一個很長的通知以保持設備振動。 如果我駁回該通知,它將立即停止。

  • (當應用程序關閉時接收傳入)如果我關閉通知,設備會再振動2-3次並顯示長通知(與在應用程序中接收傳入時相同)

ViberSkype

  • (在應用程序中接收傳入)我不確定skype,但對於viber最小化應用程序時它會立即停止振動。

  • (當應用程序關閉時接收傳入)我認為他們的行為與facebook相同(不確定)

在最小化應用程序時,如何在不通知Line情況下使設備振動?

如果我設法找到一種方法並讓它像Line一樣工作,當應用程序不在前台時,我需要使用Voip push來實現該方法嗎? (正常推送通知會起作用嗎?)

您必須使用pushkit(靜默推送通知)。

適用於后台或殺戮狀態。

Skype,whatsapp,viber等基於VOIP的應用程序就像下面的架構一樣。

獲得有效負載后,您必須安排本地通知。 您可以在本地通知中設置聲音文件。 聲音文件最長播放30秒。 如果您想要重復聲音文件,直到最終用戶不接收或拒絕呼叫,您也可以使用標記管理和重新分配本地通知。

使用以下結構來完成您的任務。

使用這個simplepush.php文件

<?php

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


      $deviceToken = '1234567890123456789';
//


// 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位置和fire命令 - > php simplepush.php

這樣您就可以測試推送工具包通知設置架構。

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

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

下載

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架構。 然后Socket用於廣播數據,例如哪些用戶在線/離線,你需要知道沒有調用API然后你可以使用套接字,服務器上的套接字架構將在線/離線用戶的數據發送到設備而無需從設備請求。

如果我可以幫助你,請告訴我。

有一個快樂的編碼。

經過一些測試后,我發現了Line如何做到這一點。

在應用程序中接收來電

他們使用

[[UIApplication sharedApplication] beginBackgroundTaskWithName:expirationHandler:]

即使你已經最小化它,保持應用程序振動。 此方法將使應用程序保持運行,並且在它們到期之前具有180秒的持續時間。

應用程序關閉時接收來電

這需要使用PushKit作為@Hasya提及使應用程序喚醒,並調用與上述方案相同的方法(保持設備振動)

[[UIApplication sharedApplication] beginBackgroundTaskWithName:expirationHandler:]

這次它將在40而不是180秒到期。 此外,您無法通過AVAudioPlayer播放帶有Ambient類別的傳入聲音。

所以你需要在UILocalNotification上附加一個聲音(需要一個擴展版本,因為沒有重復功能),我已經在某處讀過你可以播放聲音長達30秒的聲音。

使用PushKit時有些擔憂

如果您的舊系統使用APNS ,則需要在服務器端維護令牌(APNS和VOIP)。 因為您無法使用VOIP證書發送APNS令牌。 需要使用正確的證書類型發送令牌。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM