How can app use earset as a PTT button?

In ProPTT2, ear-set controll is in app-side. So developer need to add codes to control earset. Ear-set's play button can be used as a PTT button on screen on and off both. But some device don't support it at screend off.
And ProPTT2 has dedicated ear-sets. They can support hold and press PTT button. But internally it is same event toggle mode PTT button. So if developer already support toggle mode PTT button with ear-set, that can also support press-and-hold mode.
But there is one check point. If app is using TOT in PTT channel, in press-and-hold, after TOT expired, developer need to ignore one play button event.

Android

If App in on foreground, app need to process key event

onKeyDown, onKeyUp method must br overrided at Acitivity. (keyCode == KeyEvent.KEYCODE_HEADSETHOOK)

    Ex:)

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_HEADSETHOOK) {
            if (channel != null) {
                int lockState = channel.getLockState();
                if (lockState == PTTConst.LOCK_STATE_UNLOCKED) {
                    channel.lock();
                } else if (lockState == PTTConst.LOCK_STATE_REQUEST_LOCK 
                    || lockState == PTTConst.LOCK_STATE_LOCKED_BY_ME) {
                    channel.unlock();
                }
            }
            return true;
        }
    }

If App in on background, app need to process broadcast event.(The broadcast event action is depend on Android device)

You can refer to Android dev. https://developer.android.com/training/managing-audio/volume-playback.html

1.2.1 Add intent action "android.intent.action.MEDIA_BUTTON" to AndroidManifest.xml

         <receiver android:name="your package name" >
             <intent-filter>
                 <action android:name="android.intent.action.MEDIA_BUTTON" />
             </intent-filter>
         </receiver>

1.2.2 To Register MediaButton Event

    AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
    ComponentName pttbroadcastReceiver = new ComponentName(getPackageName(), "Your Broadcast Class Name");
    audioManager.registerMediaButtonEventReceiver(pttbroadcastReceiver);

1.2.3 To UnRegister MediaButton Event

    AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
    audioManager.unregisterMediaButtonEventReceiver(pttbroadcastReceiver);

iOS

iOS has 2 way to control earset

iOS 7.1 and earlier

ProPTT2 client is using this way.

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [self playMusic];
    [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
    [self becomeFirstResponder];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    [[UIApplication sharedApplication] endReceivingRemoteControlEvents];
    [self resignFirstResponder];
}

- (void)remoteControlReceivedWithEvent:(UIEvent *)event
{
    if (event.type == UIEventTypeRemoteControl) {
        if (event.subtype == UIEventSubtypeRemoteControlPlay) {
            if(channel.lockState == LOCK_STATE_UNLOCKED){
                    [channel lock];
            }
        } else if (event.subtype == UIEventSubtypeRemoteControlPause) {
            if(channel.lockState == LOCK_STATE_LOCKED_BY_ME || channel.lockState == LOCK_STATE_REQUEST_LOCK){
                [channel unlock];
            }
        } else if (event.subtype == UIEventSubtypeRemoteControlTogglePlayPause) {
            if(channel != nil)
            {
                if(channel.lockState == LOCK_STATE_UNLOCKED){
                    [channel lock];
                }
                else if(channel.lockState == LOCK_STATE_LOCKED_BY_ME || channel.lockState == LOCK_STATE_REQUEST_LOCK){
                    [channel unlock];
                }
            }
        }
    }
}

-(void) playMusic
{
    NSString* effectSound = "Your Sound file Path"; 
    NSURL* url=[NSURL fileURLWithPath:effectSound];
    _player=[[AVAudioPlayer alloc]initWithContentsOfURL:url error:nil];
    [_player setNumberOfLoops:0];
    [_player play];
}

ios 7.1 and over

https://developer.apple.com/reference/uikit/uiapplication/1623126-beginreceivingremotecontrolevent#discussion
https://developer.apple.com/library/ios/documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/Remote-ControlEvents/Remote-ControlEvents.html