initial version
This commit is contained in:
commit
a0d3e184f9
9
.gitignore
vendored
Normal file
9
.gitignore
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
*.iml
|
||||||
|
.gradle
|
||||||
|
/local.properties
|
||||||
|
/.idea/workspace.xml
|
||||||
|
/.idea/libraries
|
||||||
|
.DS_Store
|
||||||
|
/build
|
||||||
|
/captures
|
||||||
|
.externalNativeBuild
|
6
.idea/vcs.xml
Normal file
6
.idea/vcs.xml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
BIN
android_antlib_4-14-0/android_antlib_4-14-0.jar
Normal file
BIN
android_antlib_4-14-0/android_antlib_4-14-0.jar
Normal file
Binary file not shown.
2
android_antlib_4-14-0/build.gradle
Normal file
2
android_antlib_4-14-0/build.gradle
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
configurations.maybeCreate("default")
|
||||||
|
artifacts.add("default", file('android_antlib_4-14-0.jar'))
|
1
app/.gitignore
vendored
Normal file
1
app/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/build
|
32
app/build.gradle
Normal file
32
app/build.gradle
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion 24
|
||||||
|
buildToolsVersion "25.0.0"
|
||||||
|
defaultConfig {
|
||||||
|
applicationId "xyz.hoyer.iconsole"
|
||||||
|
minSdkVersion 15
|
||||||
|
targetSdkVersion 24
|
||||||
|
versionCode 1
|
||||||
|
versionName "1.0"
|
||||||
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
|
}
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
minifyEnabled false
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile fileTree(include: ['*.jar'], dir: 'libs')
|
||||||
|
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
|
||||||
|
exclude group: 'com.android.support', module: 'support-annotations'
|
||||||
|
})
|
||||||
|
compile 'com.android.support:appcompat-v7:24.2.1'
|
||||||
|
compile 'com.android.support:support-v4:24.2.1'
|
||||||
|
testCompile 'junit:junit:4.12'
|
||||||
|
compile 'com.android.support.constraint:constraint-layout:1.0.2'
|
||||||
|
provided project(':android_antlib_4-14-0')
|
||||||
|
}
|
25
app/proguard-rules.pro
vendored
Normal file
25
app/proguard-rules.pro
vendored
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
# Add project specific ProGuard rules here.
|
||||||
|
# By default, the flags in this file are appended to flags specified
|
||||||
|
# in /home/harald/Android/Sdk/tools/proguard/proguard-android.txt
|
||||||
|
# You can edit the include path and order by changing the proguardFiles
|
||||||
|
# directive in build.gradle.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||||
|
|
||||||
|
# Add any project specific keep options here:
|
||||||
|
|
||||||
|
# If your project uses WebView with JS, uncomment the following
|
||||||
|
# and specify the fully qualified class name to the JavaScript interface
|
||||||
|
# class:
|
||||||
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||||
|
# public *;
|
||||||
|
#}
|
||||||
|
|
||||||
|
# Uncomment this to preserve the line number information for
|
||||||
|
# debugging stack traces.
|
||||||
|
#-keepattributes SourceFile,LineNumberTable
|
||||||
|
|
||||||
|
# If you keep the line number information, uncomment this to
|
||||||
|
# hide the original source file name.
|
||||||
|
#-renamesourcefileattribute SourceFile
|
25
app/src/main/AndroidManifest.xml
Normal file
25
app/src/main/AndroidManifest.xml
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="xyz.hoyer.iconsole">
|
||||||
|
|
||||||
|
<application
|
||||||
|
android:allowBackup="true"
|
||||||
|
android:icon="@mipmap/ic_launcher"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:supportsRtl="true"
|
||||||
|
android:theme="@style/AppTheme">
|
||||||
|
<activity
|
||||||
|
android:name=".ChannelList"
|
||||||
|
android:configChanges="orientation|keyboardHidden|screenSize"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:theme="@style/FullscreenTheme">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
<service android:name=".ChannelService"></service>
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
40
app/src/main/java/com/dsi/ant/channel/PredefinedNetwork.java
Normal file
40
app/src/main/java/com/dsi/ant/channel/PredefinedNetwork.java
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
package com.dsi.ant.channel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by harald on 24.04.17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public enum PredefinedNetwork {
|
||||||
|
INVALID(-1),
|
||||||
|
PUBLIC(0),
|
||||||
|
ANT_PLUS1(1), //
|
||||||
|
ANT_FS(2);
|
||||||
|
|
||||||
|
private final int mRawValue;
|
||||||
|
private static final PredefinedNetwork[] sValues = values();
|
||||||
|
|
||||||
|
private PredefinedNetwork(int rawValue) {
|
||||||
|
this.mRawValue = rawValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getRawValue() {
|
||||||
|
return this.mRawValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean equals(int rawValue) {
|
||||||
|
return rawValue == this.mRawValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PredefinedNetwork create(int rawValue) {
|
||||||
|
PredefinedNetwork code = INVALID;
|
||||||
|
|
||||||
|
for(int i = 0; i < sValues.length; ++i) {
|
||||||
|
if(sValues[i].equals(rawValue)) {
|
||||||
|
code = sValues[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
}
|
296
app/src/main/java/xyz/hoyer/iconsole/ChannelController.java
Normal file
296
app/src/main/java/xyz/hoyer/iconsole/ChannelController.java
Normal file
|
@ -0,0 +1,296 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012 Dynastream Innovations Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
|
* use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
* the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations under
|
||||||
|
* the License.
|
||||||
|
*/
|
||||||
|
package xyz.hoyer.iconsole;
|
||||||
|
|
||||||
|
import android.os.RemoteException;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.dsi.ant.channel.AntChannel;
|
||||||
|
import com.dsi.ant.channel.AntCommandFailedException;
|
||||||
|
import com.dsi.ant.channel.IAntChannelEventHandler;
|
||||||
|
import com.dsi.ant.message.ChannelId;
|
||||||
|
import com.dsi.ant.message.ChannelType;
|
||||||
|
import com.dsi.ant.message.fromant.AcknowledgedDataMessage;
|
||||||
|
import com.dsi.ant.message.fromant.BroadcastDataMessage;
|
||||||
|
import com.dsi.ant.message.fromant.ChannelEventMessage;
|
||||||
|
import com.dsi.ant.message.fromant.MessageFromAntType;
|
||||||
|
import com.dsi.ant.message.ipc.AntMessageParcel;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class ChannelController
|
||||||
|
{
|
||||||
|
// The device type and transmission type to be part of the channel ID message
|
||||||
|
private static final int CHANNEL_PROOF_DEVICE_TYPE = 0x08;
|
||||||
|
private static final int CHANNEL_PROOF_TRANSMISSION_TYPE = 1;
|
||||||
|
|
||||||
|
// The period and frequency values the channel will be configured to
|
||||||
|
private static final int CHANNEL_PROOF_PERIOD = 32768; // 1 Hz
|
||||||
|
private static final int CHANNEL_PROOF_FREQUENCY = 77;
|
||||||
|
|
||||||
|
private static final String TAG = ChannelController.class.getSimpleName();
|
||||||
|
|
||||||
|
private static Random randGen = new Random();
|
||||||
|
|
||||||
|
private AntChannel mAntChannel;
|
||||||
|
private ChannelBroadcastListener mChannelBroadcastListener;
|
||||||
|
|
||||||
|
private ChannelEventCallback mChannelEventCallback = new ChannelEventCallback();
|
||||||
|
|
||||||
|
private ChannelInfo mChannelInfo;
|
||||||
|
|
||||||
|
private boolean mIsOpen;
|
||||||
|
|
||||||
|
static public abstract class ChannelBroadcastListener
|
||||||
|
{
|
||||||
|
public abstract void onBroadcastChanged(ChannelInfo newInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChannelController(AntChannel antChannel, boolean isMaster, int deviceId,
|
||||||
|
ChannelBroadcastListener broadcastListener)
|
||||||
|
{
|
||||||
|
mAntChannel = antChannel;
|
||||||
|
mChannelInfo = new ChannelInfo(deviceId, isMaster, randGen.nextInt(256));
|
||||||
|
mChannelBroadcastListener = broadcastListener;
|
||||||
|
|
||||||
|
openChannel();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
boolean openChannel()
|
||||||
|
{
|
||||||
|
if(null != mAntChannel)
|
||||||
|
{
|
||||||
|
if(mIsOpen)
|
||||||
|
{
|
||||||
|
Log.w(TAG, "Channel was already open");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Although this reference code sets ChannelType to either a transmitting master or a receiving slave,
|
||||||
|
* the standard for ANT is that channels communication is bidirectional. The use of single-direction
|
||||||
|
* communication in this app is for ease of understanding as reference code. For more information and
|
||||||
|
* any additional features on ANT channel communication, refer to the ANT Protocol Doc found at:
|
||||||
|
* http://www.thisisant.com/resources/ant-message-protocol-and-usage/
|
||||||
|
*/
|
||||||
|
ChannelType channelType = (mChannelInfo.isMaster ?
|
||||||
|
ChannelType.BIDIRECTIONAL_MASTER : ChannelType.BIDIRECTIONAL_SLAVE);
|
||||||
|
|
||||||
|
// Channel ID message contains device number, type and transmission type. In
|
||||||
|
// order for master (TX) channels and slave (RX) channels to connect, they
|
||||||
|
// must have the same channel ID, or wildcard (0) is used.
|
||||||
|
ChannelId channelId = new ChannelId(mChannelInfo.deviceNumber,
|
||||||
|
CHANNEL_PROOF_DEVICE_TYPE, CHANNEL_PROOF_TRANSMISSION_TYPE);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Setting the channel event handler so that we can receive messages from ANT
|
||||||
|
mAntChannel.setChannelEventHandler(mChannelEventCallback);
|
||||||
|
|
||||||
|
// Performs channel assignment by assigning the type to the channel. Additional
|
||||||
|
// features (such as, background scanning and frequency agility) can be enabled
|
||||||
|
// by passing an ExtendedAssignment object to assign(ChannelType, ExtendedAssignment).
|
||||||
|
mAntChannel.assign(channelType);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Configures the channel ID, messaging period and rf frequency after assigning,
|
||||||
|
* then opening the channel.
|
||||||
|
*
|
||||||
|
* For any additional ANT features such as proximity search or background scanning, refer to
|
||||||
|
* the ANT Protocol Doc found at:
|
||||||
|
* http://www.thisisant.com/resources/ant-message-protocol-and-usage/
|
||||||
|
*/
|
||||||
|
mAntChannel.setChannelId(channelId);
|
||||||
|
mAntChannel.setPeriod(CHANNEL_PROOF_PERIOD);
|
||||||
|
mAntChannel.setRfFrequency(CHANNEL_PROOF_FREQUENCY);
|
||||||
|
mAntChannel.open();
|
||||||
|
mIsOpen = true;
|
||||||
|
|
||||||
|
Log.d(TAG, "Opened channel with device number: " + mChannelInfo.deviceNumber);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
channelError(e);
|
||||||
|
} catch (AntCommandFailedException e) {
|
||||||
|
// This will release, and therefore unassign if required
|
||||||
|
channelError("Open failed", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.w(TAG, "No channel available");
|
||||||
|
}
|
||||||
|
|
||||||
|
return mIsOpen;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements the Channel Event Handler Interface so that messages can be
|
||||||
|
* received and channel death events can be handled.
|
||||||
|
*/
|
||||||
|
public class ChannelEventCallback implements IAntChannelEventHandler
|
||||||
|
{
|
||||||
|
private void updateData(byte[] data) {
|
||||||
|
mChannelInfo.broadcastData = data;
|
||||||
|
|
||||||
|
mChannelBroadcastListener.onBroadcastChanged(mChannelInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onChannelDeath()
|
||||||
|
{
|
||||||
|
// Display channel death message when channel dies
|
||||||
|
displayChannelError("Channel Death");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReceiveMessage(MessageFromAntType messageType, AntMessageParcel antParcel) {
|
||||||
|
Log.d(TAG, "Rx: "+ antParcel);
|
||||||
|
|
||||||
|
// Switching on message type to handle different types of messages
|
||||||
|
switch(messageType)
|
||||||
|
{
|
||||||
|
// If data message, construct from parcel and update channel data
|
||||||
|
case BROADCAST_DATA:
|
||||||
|
// Rx Data
|
||||||
|
updateData(new BroadcastDataMessage(antParcel).getPayload());
|
||||||
|
break;
|
||||||
|
case ACKNOWLEDGED_DATA:
|
||||||
|
// Rx Data
|
||||||
|
updateData(new AcknowledgedDataMessage(antParcel).getPayload());
|
||||||
|
break;
|
||||||
|
case CHANNEL_EVENT:
|
||||||
|
// Constructing channel event message from parcel
|
||||||
|
ChannelEventMessage eventMessage = new ChannelEventMessage(antParcel);
|
||||||
|
|
||||||
|
// Switching on event code to handle the different types of channel events
|
||||||
|
switch(eventMessage.getEventCode())
|
||||||
|
{
|
||||||
|
case TX:
|
||||||
|
// Use old info as this is what remote device has just received
|
||||||
|
mChannelBroadcastListener.onBroadcastChanged(mChannelInfo);
|
||||||
|
|
||||||
|
mChannelInfo.broadcastData[0]++;
|
||||||
|
|
||||||
|
if(mIsOpen)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// Setting the data to be broadcast on the next channel period
|
||||||
|
mAntChannel.setBroadcastData(mChannelInfo.broadcastData);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
channelError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case RX_SEARCH_TIMEOUT:
|
||||||
|
// TODO May want to keep searching
|
||||||
|
displayChannelError("No Device Found");
|
||||||
|
break;
|
||||||
|
case CHANNEL_CLOSED:
|
||||||
|
case CHANNEL_COLLISION:
|
||||||
|
case RX_FAIL:
|
||||||
|
case RX_FAIL_GO_TO_SEARCH:
|
||||||
|
case TRANSFER_RX_FAILED:
|
||||||
|
case TRANSFER_TX_COMPLETED:
|
||||||
|
case TRANSFER_TX_FAILED:
|
||||||
|
case TRANSFER_TX_START:
|
||||||
|
case UNKNOWN:
|
||||||
|
// TODO More complex communication will need to handle these events
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ANT_VERSION:
|
||||||
|
case BURST_TRANSFER_DATA:
|
||||||
|
case CAPABILITIES:
|
||||||
|
case CHANNEL_ID:
|
||||||
|
case CHANNEL_RESPONSE:
|
||||||
|
case CHANNEL_STATUS:
|
||||||
|
case SERIAL_NUMBER:
|
||||||
|
case OTHER:
|
||||||
|
// TODO More complex communication will need to handle these message types
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChannelInfo getCurrentInfo()
|
||||||
|
{
|
||||||
|
return mChannelInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
void displayChannelError(String displayText)
|
||||||
|
{
|
||||||
|
mChannelInfo.die(displayText);
|
||||||
|
mChannelBroadcastListener.onBroadcastChanged(mChannelInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void channelError(RemoteException e) {
|
||||||
|
String logString = "Remote service communication failed.";
|
||||||
|
|
||||||
|
Log.e(TAG, logString);
|
||||||
|
|
||||||
|
displayChannelError(logString);
|
||||||
|
}
|
||||||
|
|
||||||
|
void channelError(String error, AntCommandFailedException e) {
|
||||||
|
StringBuilder logString;
|
||||||
|
|
||||||
|
if(e.getResponseMessage() != null) {
|
||||||
|
String initiatingMessageId = "0x"+ Integer.toHexString(
|
||||||
|
e.getResponseMessage().getInitiatingMessageId());
|
||||||
|
String rawResponseCode = "0x"+ Integer.toHexString(
|
||||||
|
e.getResponseMessage().getRawResponseCode());
|
||||||
|
|
||||||
|
logString = new StringBuilder(error)
|
||||||
|
.append(". Command ")
|
||||||
|
.append(initiatingMessageId)
|
||||||
|
.append(" failed with code ")
|
||||||
|
.append(rawResponseCode);
|
||||||
|
} else {
|
||||||
|
String attemptedMessageId = "0x"+ Integer.toHexString(
|
||||||
|
e.getAttemptedMessageType().getMessageId());
|
||||||
|
String failureReason = e.getFailureReason().toString();
|
||||||
|
|
||||||
|
logString = new StringBuilder(error)
|
||||||
|
.append(". Command ")
|
||||||
|
.append(attemptedMessageId)
|
||||||
|
.append(" failed with reason ")
|
||||||
|
.append(failureReason);
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.e(TAG, logString.toString());
|
||||||
|
|
||||||
|
mAntChannel.release();
|
||||||
|
|
||||||
|
displayChannelError("ANT Command Failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close()
|
||||||
|
{
|
||||||
|
// TODO kill all our resources
|
||||||
|
if (null != mAntChannel)
|
||||||
|
{
|
||||||
|
mIsOpen = false;
|
||||||
|
|
||||||
|
// Releasing the channel to make it available for others.
|
||||||
|
// After releasing, the AntChannel instance cannot be reused.
|
||||||
|
mAntChannel.release();
|
||||||
|
mAntChannel = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
displayChannelError("Channel Closed");
|
||||||
|
}
|
||||||
|
}
|
54
app/src/main/java/xyz/hoyer/iconsole/ChannelInfo.java
Normal file
54
app/src/main/java/xyz/hoyer/iconsole/ChannelInfo.java
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012 Dynastream Innovations Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
|
* use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
* the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations under
|
||||||
|
* the License.
|
||||||
|
*/
|
||||||
|
package xyz.hoyer.iconsole;
|
||||||
|
|
||||||
|
import com.dsi.ant.message.fromant.DataMessage;
|
||||||
|
|
||||||
|
public class ChannelInfo
|
||||||
|
{
|
||||||
|
public final int deviceNumber;
|
||||||
|
|
||||||
|
/** Master / Slave */
|
||||||
|
public final boolean isMaster;
|
||||||
|
|
||||||
|
public byte[] broadcastData = new byte[DataMessage.LENGTH_STANDARD_PAYLOAD];
|
||||||
|
|
||||||
|
public boolean error;
|
||||||
|
private String mErrorMessage;
|
||||||
|
|
||||||
|
public ChannelInfo(int deviceNumber, boolean isMaster, int initialBroadcastValue)
|
||||||
|
{
|
||||||
|
this.deviceNumber = deviceNumber;
|
||||||
|
this.isMaster = isMaster;
|
||||||
|
|
||||||
|
// Not actually concerned with this value, so can cast to byte and lose data without issues
|
||||||
|
broadcastData[0] = (byte)initialBroadcastValue;
|
||||||
|
|
||||||
|
error = false;
|
||||||
|
mErrorMessage = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void die(String errorMessage)
|
||||||
|
{
|
||||||
|
error = true;
|
||||||
|
mErrorMessage = errorMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getErrorString()
|
||||||
|
{
|
||||||
|
return mErrorMessage;
|
||||||
|
}
|
||||||
|
}
|
387
app/src/main/java/xyz/hoyer/iconsole/ChannelList.java
Normal file
387
app/src/main/java/xyz/hoyer/iconsole/ChannelList.java
Normal file
|
@ -0,0 +1,387 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012 Dynastream Innovations Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
|
* use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
* the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations under
|
||||||
|
* the License.
|
||||||
|
*/
|
||||||
|
package xyz.hoyer.iconsole;
|
||||||
|
|
||||||
|
import com.dsi.ant.channel.ChannelNotAvailableException;
|
||||||
|
import xyz.hoyer.iconsole.ChannelService.ChannelChangedListener;
|
||||||
|
import xyz.hoyer.iconsole.ChannelService.ChannelServiceComm;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.ComponentName;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.ServiceConnection;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.IBinder;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.util.SparseArray;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.View.OnClickListener;
|
||||||
|
import android.widget.ArrayAdapter;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.CompoundButton;
|
||||||
|
import android.widget.ListView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
import android.widget.ToggleButton;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class ChannelList extends Activity {
|
||||||
|
private static final String TAG = ChannelList.class.getSimpleName();
|
||||||
|
|
||||||
|
private final String PREF_TX_BUTTON_CHECKED_KEY = "ChannelList.TX_BUTTON_CHECKED";
|
||||||
|
private boolean mCreateChannelAsMaster;
|
||||||
|
|
||||||
|
private ChannelServiceComm mChannelService;
|
||||||
|
|
||||||
|
private ArrayList<String> mChannelDisplayList = new ArrayList<String>();
|
||||||
|
private ArrayAdapter<String> mChannelListAdapter;
|
||||||
|
private SparseArray<Integer> mIdChannelListIndexMap = new SparseArray<Integer>();
|
||||||
|
|
||||||
|
private boolean mChannelServiceBound = false;
|
||||||
|
|
||||||
|
private void initButtons()
|
||||||
|
{
|
||||||
|
Log.v(TAG, "initButtons...");
|
||||||
|
|
||||||
|
//Register Master/Slave Toggle handler
|
||||||
|
ToggleButton toggleButton_MasterSlave = (ToggleButton)findViewById(R.id.toggleButton_MasterSlave);
|
||||||
|
toggleButton_MasterSlave.setEnabled(mChannelServiceBound);
|
||||||
|
toggleButton_MasterSlave.setChecked(mCreateChannelAsMaster);
|
||||||
|
toggleButton_MasterSlave.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onCheckedChanged(CompoundButton arg0, boolean enabled)
|
||||||
|
{
|
||||||
|
mCreateChannelAsMaster = enabled;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Register Add Channel Button handler
|
||||||
|
Button button_addChannel = (Button)findViewById(R.id.button_AddChannel);
|
||||||
|
button_addChannel.setEnabled(mChannelServiceBound);
|
||||||
|
button_addChannel.setOnClickListener(new OnClickListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onClick(View v)
|
||||||
|
{
|
||||||
|
addNewChannel(mCreateChannelAsMaster);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Register Clear Channels Button handler
|
||||||
|
Button button_clearChannels = (Button)findViewById(R.id.button_ClearChannels);
|
||||||
|
button_clearChannels.setEnabled(mChannelServiceBound);
|
||||||
|
button_clearChannels.setOnClickListener(new OnClickListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onClick(View v)
|
||||||
|
{
|
||||||
|
clearAllChannels();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Log.v(TAG, "...initButtons");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initPrefs()
|
||||||
|
{
|
||||||
|
Log.v(TAG, "initPrefs...");
|
||||||
|
|
||||||
|
// Retrieves the app's current state of channel transmission mode
|
||||||
|
// from preferences to handle app resuming.
|
||||||
|
SharedPreferences preferences = getPreferences(MODE_PRIVATE);
|
||||||
|
|
||||||
|
mCreateChannelAsMaster = preferences.getBoolean(PREF_TX_BUTTON_CHECKED_KEY, true);
|
||||||
|
|
||||||
|
Log.v(TAG, "...initPrefs");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void savePrefs()
|
||||||
|
{
|
||||||
|
Log.v(TAG, "savePrefs...");
|
||||||
|
|
||||||
|
// Saves the app's current state of channel transmission mode to preferences
|
||||||
|
SharedPreferences preferences = getPreferences(MODE_PRIVATE);
|
||||||
|
SharedPreferences.Editor editor = preferences.edit();
|
||||||
|
|
||||||
|
editor.putBoolean(PREF_TX_BUTTON_CHECKED_KEY, mCreateChannelAsMaster);
|
||||||
|
|
||||||
|
editor.commit();
|
||||||
|
|
||||||
|
Log.v(TAG, "...savePrefs");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doBindChannelService()
|
||||||
|
{
|
||||||
|
Log.v(TAG, "doBindChannelService...");
|
||||||
|
|
||||||
|
// Binds to ChannelService. ChannelService binds and manages connection between the
|
||||||
|
// app and the ANT Radio Service
|
||||||
|
Intent bindIntent = new Intent(this, ChannelService.class);
|
||||||
|
startService(bindIntent);
|
||||||
|
mChannelServiceBound = bindService(bindIntent, mChannelServiceConnection, Context.BIND_AUTO_CREATE);
|
||||||
|
|
||||||
|
if(!mChannelServiceBound) //If the bind returns false, run the unbind method to update the GUI
|
||||||
|
doUnbindChannelService();
|
||||||
|
|
||||||
|
Log.i(TAG, " Channel Service binding = "+ mChannelServiceBound);
|
||||||
|
|
||||||
|
Log.v(TAG, "...doBindChannelService");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doUnbindChannelService()
|
||||||
|
{
|
||||||
|
Log.v(TAG, "doUnbindChannelService...");
|
||||||
|
|
||||||
|
if(mChannelServiceBound)
|
||||||
|
{
|
||||||
|
unbindService(mChannelServiceConnection);
|
||||||
|
|
||||||
|
mChannelServiceBound = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
((Button)findViewById(R.id.button_ClearChannels)).setEnabled(false);
|
||||||
|
((Button)findViewById(R.id.button_AddChannel)).setEnabled(false);
|
||||||
|
((Button)findViewById(R.id.toggleButton_MasterSlave)).setEnabled(false);
|
||||||
|
|
||||||
|
Log.v(TAG, "...doUnbindChannelService");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
Log.v(TAG, "onCreate...");
|
||||||
|
|
||||||
|
mChannelServiceBound = false;
|
||||||
|
|
||||||
|
setContentView(R.layout.activity_fullscreen);
|
||||||
|
|
||||||
|
initPrefs();
|
||||||
|
|
||||||
|
mChannelListAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, android.R.id.text1, mChannelDisplayList);
|
||||||
|
ListView listView_channelList = (ListView)findViewById(R.id.listView_channelList);
|
||||||
|
listView_channelList.setAdapter(mChannelListAdapter);
|
||||||
|
|
||||||
|
if(!mChannelServiceBound) doBindChannelService();
|
||||||
|
|
||||||
|
initButtons();
|
||||||
|
|
||||||
|
Log.v(TAG, "...onCreate");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onBack() {
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy()
|
||||||
|
{
|
||||||
|
Log.v(TAG, "onDestroy...");
|
||||||
|
|
||||||
|
doUnbindChannelService();
|
||||||
|
|
||||||
|
if(isFinishing())
|
||||||
|
{
|
||||||
|
stopService(new Intent(this, ChannelService.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
mChannelServiceConnection = null;
|
||||||
|
|
||||||
|
savePrefs();
|
||||||
|
|
||||||
|
Log.v(TAG, "...onDestroy");
|
||||||
|
|
||||||
|
super.onDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ServiceConnection mChannelServiceConnection = new ServiceConnection()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onServiceConnected(ComponentName name, IBinder serviceBinder)
|
||||||
|
{
|
||||||
|
Log.v(TAG, "mChannelServiceConnection.onServiceConnected...");
|
||||||
|
|
||||||
|
mChannelService = (ChannelServiceComm) serviceBinder;
|
||||||
|
|
||||||
|
// Sets a listener that handles channel events
|
||||||
|
mChannelService.setOnChannelChangedListener(new ChannelChangedListener()
|
||||||
|
{
|
||||||
|
// Occurs when a channel has new info/data
|
||||||
|
@Override
|
||||||
|
public void onChannelChanged(final ChannelInfo newInfo)
|
||||||
|
{
|
||||||
|
Integer index = mIdChannelListIndexMap.get(newInfo.deviceNumber);
|
||||||
|
|
||||||
|
if(null != index && index.intValue() < mChannelDisplayList.size())
|
||||||
|
{
|
||||||
|
mChannelDisplayList.set(index.intValue(), getDisplayText(newInfo));
|
||||||
|
runOnUiThread(new Runnable()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
mChannelListAdapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Updates the UI to allow/disallow acquiring new channels
|
||||||
|
@Override
|
||||||
|
public void onAllowAddChannel(boolean addChannelAllowed) {
|
||||||
|
// Enable Add Channel button and Master/Slave toggle if
|
||||||
|
// adding channels is allowed
|
||||||
|
((Button)findViewById(R.id.button_AddChannel)).setEnabled(addChannelAllowed);
|
||||||
|
((Button)findViewById(R.id.toggleButton_MasterSlave)).setEnabled(addChannelAllowed);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Initial check when connecting to ChannelService if adding channels is allowed
|
||||||
|
boolean allowAcquireChannel = mChannelService.isAddChannelAllowed();
|
||||||
|
((Button)findViewById(R.id.button_AddChannel)).setEnabled(allowAcquireChannel);
|
||||||
|
((Button)findViewById(R.id.toggleButton_MasterSlave)).setEnabled(allowAcquireChannel);
|
||||||
|
|
||||||
|
refreshList();
|
||||||
|
|
||||||
|
Log.v(TAG, "...mChannelServiceConnection.onServiceConnected");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onServiceDisconnected(ComponentName arg0)
|
||||||
|
{
|
||||||
|
Log.v(TAG, "mChannelServiceConnection.onServiceDisconnected...");
|
||||||
|
|
||||||
|
// Clearing and disabling when disconnecting from ChannelService
|
||||||
|
mChannelService = null;
|
||||||
|
|
||||||
|
((Button)findViewById(R.id.button_ClearChannels)).setEnabled(false);
|
||||||
|
((Button)findViewById(R.id.button_AddChannel)).setEnabled(false);
|
||||||
|
((Button)findViewById(R.id.toggleButton_MasterSlave)).setEnabled(false);
|
||||||
|
|
||||||
|
Log.v(TAG, "...mChannelServiceConnection.onServiceDisconnected");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// This method is called when 'Add Channel' button is clicked
|
||||||
|
private void addNewChannel(final boolean isMaster)
|
||||||
|
{
|
||||||
|
Log.v(TAG, "addNewChannel...");
|
||||||
|
|
||||||
|
if(null != mChannelService)
|
||||||
|
{
|
||||||
|
ChannelInfo newChannelInfo;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Telling the ChannelService to add a new channel. This method
|
||||||
|
// in ChannelService contains code required to acquire an ANT
|
||||||
|
// channel from ANT Radio Service.
|
||||||
|
newChannelInfo = mChannelService.addNewChannel(isMaster);
|
||||||
|
} catch (ChannelNotAvailableException e)
|
||||||
|
{
|
||||||
|
// Occurs when a channel is not available. Printing out the
|
||||||
|
// stack trace will show why no channels are available.
|
||||||
|
Toast.makeText(this, "Channel Not Available", Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(null != newChannelInfo)
|
||||||
|
{
|
||||||
|
// Adding new channel info to the list
|
||||||
|
addChannelToList(newChannelInfo);
|
||||||
|
mChannelListAdapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.v(TAG, "...addNewChannel");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void refreshList()
|
||||||
|
{
|
||||||
|
Log.v(TAG, "refreshList...");
|
||||||
|
|
||||||
|
if(null != mChannelService)
|
||||||
|
{
|
||||||
|
ArrayList<ChannelInfo> chInfoList = mChannelService.getCurrentChannelInfoForAllChannels();
|
||||||
|
|
||||||
|
mChannelDisplayList.clear();
|
||||||
|
for(ChannelInfo i: chInfoList)
|
||||||
|
{
|
||||||
|
addChannelToList(i);
|
||||||
|
}
|
||||||
|
mChannelListAdapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.v(TAG, "...refreshList");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addChannelToList(ChannelInfo channelInfo)
|
||||||
|
{
|
||||||
|
Log.v(TAG, "addChannelToList...");
|
||||||
|
|
||||||
|
mIdChannelListIndexMap.put(channelInfo.deviceNumber, mChannelDisplayList.size());
|
||||||
|
mChannelDisplayList.add(getDisplayText(channelInfo));
|
||||||
|
|
||||||
|
Log.v(TAG, "...addChannelToList");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static String getDisplayText(ChannelInfo channelInfo)
|
||||||
|
{
|
||||||
|
Log.v(TAG, "getDisplayText...");
|
||||||
|
String displayText = null;
|
||||||
|
|
||||||
|
if(channelInfo.error)
|
||||||
|
{
|
||||||
|
displayText = String.format("#%-6d !:%s", channelInfo.deviceNumber, channelInfo.getErrorString());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(channelInfo.isMaster)
|
||||||
|
{
|
||||||
|
displayText = String.format("#%-6d Tx:[%2d]", channelInfo.deviceNumber, channelInfo.broadcastData[0] & 0xFF);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
displayText = String.format("#%-6d Rx:[%2d]", channelInfo.deviceNumber, channelInfo.broadcastData[0] & 0xFF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.v(TAG, "...getDisplayText");
|
||||||
|
|
||||||
|
return displayText;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void clearAllChannels()
|
||||||
|
{
|
||||||
|
Log.v(TAG, "clearAllChannels...");
|
||||||
|
|
||||||
|
if(null != mChannelService)
|
||||||
|
{
|
||||||
|
// Telling ChannelService to close all the channels
|
||||||
|
mChannelService.clearAllChannels();
|
||||||
|
|
||||||
|
mChannelDisplayList.clear();
|
||||||
|
mIdChannelListIndexMap.clear();
|
||||||
|
mChannelListAdapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.v(TAG, "...clearAllChannels");
|
||||||
|
}
|
||||||
|
}
|
379
app/src/main/java/xyz/hoyer/iconsole/ChannelService.java
Normal file
379
app/src/main/java/xyz/hoyer/iconsole/ChannelService.java
Normal file
|
@ -0,0 +1,379 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012 Dynastream Innovations Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
|
* use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
* the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations under
|
||||||
|
* the License.
|
||||||
|
*/
|
||||||
|
package xyz.hoyer.iconsole;
|
||||||
|
|
||||||
|
import xyz.hoyer.iconsole.ChannelController.ChannelBroadcastListener;
|
||||||
|
|
||||||
|
import com.dsi.ant.AntService;
|
||||||
|
import com.dsi.ant.channel.AntChannel;
|
||||||
|
import com.dsi.ant.channel.AntChannelProvider;
|
||||||
|
import com.dsi.ant.channel.ChannelNotAvailableException;
|
||||||
|
import com.dsi.ant.channel.PredefinedNetwork;
|
||||||
|
|
||||||
|
import android.app.Service;
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.ComponentName;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
|
import android.content.ServiceConnection;
|
||||||
|
import android.os.Binder;
|
||||||
|
import android.os.IBinder;
|
||||||
|
import android.os.RemoteException;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.util.SparseArray;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class ChannelService extends Service
|
||||||
|
{
|
||||||
|
private static final String TAG = "ChannelService";
|
||||||
|
|
||||||
|
private Object mCreateChannel_LOCK = new Object();
|
||||||
|
|
||||||
|
SparseArray<ChannelController> mChannelControllerList = new SparseArray<ChannelController>();
|
||||||
|
|
||||||
|
ChannelChangedListener mListener;
|
||||||
|
|
||||||
|
int channelDeviceIdCounter = 0;
|
||||||
|
|
||||||
|
private boolean mAntRadioServiceBound;
|
||||||
|
private AntService mAntRadioService = null;
|
||||||
|
private AntChannelProvider mAntChannelProvider = null;
|
||||||
|
private boolean mAllowAddChannel = false;
|
||||||
|
|
||||||
|
private ServiceConnection mAntRadioServiceConnection = new ServiceConnection()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onServiceConnected(ComponentName name, IBinder service)
|
||||||
|
{
|
||||||
|
// Must pass in the received IBinder object to correctly construct an AntService object
|
||||||
|
mAntRadioService = new AntService(service);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Getting a channel provider in order to acquire channels
|
||||||
|
mAntChannelProvider = mAntRadioService.getChannelProvider();
|
||||||
|
|
||||||
|
// Initial check for number of channels available
|
||||||
|
boolean mChannelAvailable = mAntChannelProvider.getNumChannelsAvailable() > 0;
|
||||||
|
// Initial check for if legacy interface is in use. If the
|
||||||
|
// legacy interface is in use, applications can free the ANT
|
||||||
|
// radio by attempting to acquire a channel.
|
||||||
|
boolean legacyInterfaceInUse = mAntChannelProvider.isLegacyInterfaceInUse();
|
||||||
|
|
||||||
|
// If there are channels OR legacy interface in use, allow adding channels
|
||||||
|
if(mChannelAvailable || legacyInterfaceInUse) {
|
||||||
|
mAllowAddChannel = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// If no channels available AND legacy interface is not in use, disallow adding channels
|
||||||
|
mAllowAddChannel = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mAllowAddChannel) {
|
||||||
|
if(null != mListener) {
|
||||||
|
// Send an event that indicates if adding channels is allowed
|
||||||
|
mListener.onAllowAddChannel(mAllowAddChannel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onServiceDisconnected(ComponentName name)
|
||||||
|
{
|
||||||
|
die("Binder Died");
|
||||||
|
|
||||||
|
mAntChannelProvider = null;
|
||||||
|
mAntRadioService = null;
|
||||||
|
|
||||||
|
if(mAllowAddChannel) { mListener.onAllowAddChannel(false); }
|
||||||
|
mAllowAddChannel = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
public interface ChannelChangedListener
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Occurs when a Channel's Info has changed (i.e. a newly created
|
||||||
|
* channel, channel has transmitted or received data, or if channel has
|
||||||
|
* been closed.
|
||||||
|
*
|
||||||
|
* @param newInfo The channel's updated info
|
||||||
|
*/
|
||||||
|
void onChannelChanged(ChannelInfo newInfo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Occurs when there is adding a channel is being allowed or disallowed.
|
||||||
|
*
|
||||||
|
* @param addChannelAllowed True if adding channels is allowed. False, otherwise.
|
||||||
|
*/
|
||||||
|
void onAllowAddChannel(boolean addChannelAllowed);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The interface used to communicate with the ChannelService
|
||||||
|
*/
|
||||||
|
public class ChannelServiceComm extends Binder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Sets the listener to be used for channel changed event callbacks.
|
||||||
|
*
|
||||||
|
* @param listener The listener that will receive events
|
||||||
|
*/
|
||||||
|
void setOnChannelChangedListener(ChannelChangedListener listener)
|
||||||
|
{
|
||||||
|
mListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the current info for all channels currently added.
|
||||||
|
*
|
||||||
|
* @return A list that contains info for all the channels
|
||||||
|
*/
|
||||||
|
ArrayList<ChannelInfo> getCurrentChannelInfoForAllChannels()
|
||||||
|
{
|
||||||
|
ArrayList<ChannelInfo> retList = new ArrayList<ChannelInfo>();
|
||||||
|
for(int i = 0; i < mChannelControllerList.size(); i++)
|
||||||
|
{
|
||||||
|
ChannelController channel = mChannelControllerList.valueAt(i);
|
||||||
|
|
||||||
|
retList.add(channel.getCurrentInfo());
|
||||||
|
}
|
||||||
|
|
||||||
|
return retList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Acquires and adds a channel from ANT Radio Service
|
||||||
|
*
|
||||||
|
* @param isMaster True if channel is transmitting, False if channel is receiving
|
||||||
|
* @return The info for the newly acquired and added channel
|
||||||
|
* @throws ChannelNotAvailableException
|
||||||
|
*/
|
||||||
|
ChannelInfo addNewChannel(final boolean isMaster) throws ChannelNotAvailableException
|
||||||
|
{
|
||||||
|
return createNewChannel(isMaster);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes all channels currently added.
|
||||||
|
*/
|
||||||
|
void clearAllChannels() { closeAllChannels(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queries if adding a channel is allowed.
|
||||||
|
* @return True if adding a channel is allowed. False, otherwise.
|
||||||
|
*/
|
||||||
|
boolean isAddChannelAllowed() { return mAllowAddChannel; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private void closeAllChannels()
|
||||||
|
{
|
||||||
|
synchronized (mChannelControllerList)
|
||||||
|
{
|
||||||
|
// Closing all channels in the list
|
||||||
|
for(int i = 0; i < mChannelControllerList.size(); i++)
|
||||||
|
{
|
||||||
|
mChannelControllerList.valueAt(i).close();
|
||||||
|
}
|
||||||
|
mChannelControllerList.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset the device id counter
|
||||||
|
channelDeviceIdCounter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
AntChannel acquireChannel() throws ChannelNotAvailableException
|
||||||
|
{
|
||||||
|
AntChannel mAntChannel = null;
|
||||||
|
if(null != mAntChannelProvider)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* If applications require a channel with specific capabilities
|
||||||
|
* (event buffering, background scanning etc.), a Capabilities
|
||||||
|
* object should be created and then the specific capabilities
|
||||||
|
* required set to true. Applications can specify both required
|
||||||
|
* and desired Capabilities with both being passed in
|
||||||
|
* acquireChannel(context, PredefinedNetwork,
|
||||||
|
* requiredCapabilities, desiredCapabilities).
|
||||||
|
*/
|
||||||
|
mAntChannel = mAntChannelProvider.acquireChannel(this, PredefinedNetwork.ANT_PLUS1);
|
||||||
|
/*
|
||||||
|
NetworkKey mNK = new NetworkKey(new byte[] { (byte)0xb9, (byte)0xa5, (byte)0x21, (byte)0xfb,
|
||||||
|
(byte)0xbd, (byte)0x72, (byte)0xc3, (byte)0x45 });
|
||||||
|
Log.v(TAG, mNK.toString());
|
||||||
|
mAntChannel = mAntChannelProvider.acquireChannelOnPrivateNetwork(this, mNK);
|
||||||
|
*/
|
||||||
|
} catch (RemoteException e)
|
||||||
|
{
|
||||||
|
die("ACP Remote Ex");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mAntChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChannelInfo createNewChannel(final boolean isMaster) throws ChannelNotAvailableException
|
||||||
|
{
|
||||||
|
ChannelController channelController = null;
|
||||||
|
|
||||||
|
synchronized(mCreateChannel_LOCK)
|
||||||
|
{
|
||||||
|
// Acquiring a channel from ANT Radio Service
|
||||||
|
AntChannel antChannel = acquireChannel();
|
||||||
|
|
||||||
|
if(null != antChannel)
|
||||||
|
{
|
||||||
|
|
||||||
|
channelDeviceIdCounter += 1;
|
||||||
|
|
||||||
|
// Constructing a controller that will manage and control the channel
|
||||||
|
channelController = new ChannelController(antChannel, isMaster, channelDeviceIdCounter,
|
||||||
|
new ChannelBroadcastListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onBroadcastChanged(ChannelInfo newInfo)
|
||||||
|
{
|
||||||
|
// Sending a channel changed event when message from ANT is received
|
||||||
|
mListener.onChannelChanged(newInfo);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
mChannelControllerList.put(channelDeviceIdCounter, channelController);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(null == channelController) return null;
|
||||||
|
|
||||||
|
return channelController.getCurrentInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBinder onBind(Intent arg0)
|
||||||
|
{
|
||||||
|
return new ChannelServiceComm();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Receives AntChannelProvider state changes being sent from ANT Radio Service
|
||||||
|
*/
|
||||||
|
private final BroadcastReceiver mChannelProviderStateChangedReceiver = new BroadcastReceiver()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent)
|
||||||
|
{
|
||||||
|
if(AntChannelProvider.ACTION_CHANNEL_PROVIDER_STATE_CHANGED.equals(intent.getAction())) {
|
||||||
|
boolean update = false;
|
||||||
|
// Retrieving the data contained in the intent
|
||||||
|
int numChannels = intent.getIntExtra(AntChannelProvider.NUM_CHANNELS_AVAILABLE, 0);
|
||||||
|
boolean legacyInterfaceInUse = intent.getBooleanExtra(AntChannelProvider.LEGACY_INTERFACE_IN_USE, false);
|
||||||
|
|
||||||
|
if(mAllowAddChannel) {
|
||||||
|
// Was a acquire channel allowed
|
||||||
|
// If no channels available AND legacy interface is not in use, disallow acquiring of channels
|
||||||
|
if(0 == numChannels && !legacyInterfaceInUse) {
|
||||||
|
mAllowAddChannel = false;
|
||||||
|
update = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Acquire channels not allowed
|
||||||
|
// If there are channels OR legacy interface in use, allow acquiring of channels
|
||||||
|
if(numChannels > 0 || legacyInterfaceInUse) {
|
||||||
|
mAllowAddChannel = true;
|
||||||
|
update = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(update && (null != mListener)) {
|
||||||
|
// AllowAddChannel has been changed, sending event callback
|
||||||
|
mListener.onAllowAddChannel(mAllowAddChannel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private void doBindAntRadioService()
|
||||||
|
{
|
||||||
|
if(BuildConfig.DEBUG) Log.v(TAG, "doBindAntRadioService");
|
||||||
|
|
||||||
|
// Start listing for channel available intents
|
||||||
|
registerReceiver(mChannelProviderStateChangedReceiver, new IntentFilter(AntChannelProvider.ACTION_CHANNEL_PROVIDER_STATE_CHANGED));
|
||||||
|
|
||||||
|
// Creating the intent and calling context.bindService() is handled by
|
||||||
|
// the static bindService() method in AntService
|
||||||
|
mAntRadioServiceBound = AntService.bindService(this, mAntRadioServiceConnection);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doUnbindAntRadioService()
|
||||||
|
{
|
||||||
|
if(BuildConfig.DEBUG) Log.v(TAG, "doUnbindAntRadioService");
|
||||||
|
|
||||||
|
// Stop listing for channel available intents
|
||||||
|
try{
|
||||||
|
unregisterReceiver(mChannelProviderStateChangedReceiver);
|
||||||
|
} catch (IllegalArgumentException exception) {
|
||||||
|
if(BuildConfig.DEBUG) Log.d(TAG, "Attempting to unregister a never registered Channel Provider State Changed receiver.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mAntRadioServiceBound)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
unbindService(mAntRadioServiceConnection);
|
||||||
|
}
|
||||||
|
catch(IllegalArgumentException e)
|
||||||
|
{
|
||||||
|
// Not bound, that's what we want anyway
|
||||||
|
}
|
||||||
|
|
||||||
|
mAntRadioServiceBound = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate()
|
||||||
|
{
|
||||||
|
super.onCreate();
|
||||||
|
|
||||||
|
mAntRadioServiceBound = false;
|
||||||
|
|
||||||
|
doBindAntRadioService();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy()
|
||||||
|
{
|
||||||
|
closeAllChannels();
|
||||||
|
|
||||||
|
doUnbindAntRadioService();
|
||||||
|
mAntChannelProvider = null;
|
||||||
|
|
||||||
|
super.onDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void die(String error)
|
||||||
|
{
|
||||||
|
Log.e(TAG, "DIE: "+ error);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
23
build.gradle
Normal file
23
build.gradle
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
|
|
||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath 'com.android.tools.build:gradle:2.3.1'
|
||||||
|
|
||||||
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
|
// in the individual module build.gradle files
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
allprojects {
|
||||||
|
repositories {
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task clean(type: Delete) {
|
||||||
|
delete rootProject.buildDir
|
||||||
|
}
|
17
gradle.properties
Normal file
17
gradle.properties
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
# Project-wide Gradle settings.
|
||||||
|
|
||||||
|
# IDE (e.g. Android Studio) users:
|
||||||
|
# Gradle settings configured through the IDE *will override*
|
||||||
|
# any settings specified in this file.
|
||||||
|
|
||||||
|
# For more details on how to configure your build environment visit
|
||||||
|
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||||
|
|
||||||
|
# Specifies the JVM arguments used for the daemon process.
|
||||||
|
# The setting is particularly useful for tweaking memory settings.
|
||||||
|
org.gradle.jvmargs=-Xmx1536m
|
||||||
|
|
||||||
|
# When configured, Gradle will run in incubating parallel mode.
|
||||||
|
# This option should only be used with decoupled projects. More details, visit
|
||||||
|
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||||
|
# org.gradle.parallel=true
|
160
gradlew
vendored
Executable file
160
gradlew
vendored
Executable file
|
@ -0,0 +1,160 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
##
|
||||||
|
## Gradle start up script for UN*X
|
||||||
|
##
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS=""
|
||||||
|
|
||||||
|
APP_NAME="Gradle"
|
||||||
|
APP_BASE_NAME=`basename "$0"`
|
||||||
|
|
||||||
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
|
MAX_FD="maximum"
|
||||||
|
|
||||||
|
warn ( ) {
|
||||||
|
echo "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
die ( ) {
|
||||||
|
echo
|
||||||
|
echo "$*"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# OS specific support (must be 'true' or 'false').
|
||||||
|
cygwin=false
|
||||||
|
msys=false
|
||||||
|
darwin=false
|
||||||
|
case "`uname`" in
|
||||||
|
CYGWIN* )
|
||||||
|
cygwin=true
|
||||||
|
;;
|
||||||
|
Darwin* )
|
||||||
|
darwin=true
|
||||||
|
;;
|
||||||
|
MINGW* )
|
||||||
|
msys=true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Attempt to set APP_HOME
|
||||||
|
# Resolve links: $0 may be a link
|
||||||
|
PRG="$0"
|
||||||
|
# Need this for relative symlinks.
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG=`dirname "$PRG"`"/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
SAVED="`pwd`"
|
||||||
|
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||||
|
APP_HOME="`pwd -P`"
|
||||||
|
cd "$SAVED" >/dev/null
|
||||||
|
|
||||||
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
# Determine the Java command to use to start the JVM.
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||||
|
else
|
||||||
|
JAVACMD="$JAVA_HOME/bin/java"
|
||||||
|
fi
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD="java"
|
||||||
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Increase the maximum file descriptors if we can.
|
||||||
|
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||||
|
MAX_FD_LIMIT=`ulimit -H -n`
|
||||||
|
if [ $? -eq 0 ] ; then
|
||||||
|
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||||
|
MAX_FD="$MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
ulimit -n $MAX_FD
|
||||||
|
if [ $? -ne 0 ] ; then
|
||||||
|
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Darwin, add options to specify how the application appears in the dock
|
||||||
|
if $darwin; then
|
||||||
|
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Cygwin, switch paths to Windows format before running java
|
||||||
|
if $cygwin ; then
|
||||||
|
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||||
|
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||||
|
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||||
|
|
||||||
|
# We build the pattern for arguments to be converted via cygpath
|
||||||
|
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||||
|
SEP=""
|
||||||
|
for dir in $ROOTDIRSRAW ; do
|
||||||
|
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||||
|
SEP="|"
|
||||||
|
done
|
||||||
|
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||||
|
# Add a user-defined pattern to the cygpath arguments
|
||||||
|
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||||
|
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||||
|
fi
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
i=0
|
||||||
|
for arg in "$@" ; do
|
||||||
|
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||||
|
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||||
|
|
||||||
|
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||||
|
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||||
|
else
|
||||||
|
eval `echo args$i`="\"$arg\""
|
||||||
|
fi
|
||||||
|
i=$((i+1))
|
||||||
|
done
|
||||||
|
case $i in
|
||||||
|
(0) set -- ;;
|
||||||
|
(1) set -- "$args0" ;;
|
||||||
|
(2) set -- "$args0" "$args1" ;;
|
||||||
|
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||||
|
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||||
|
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||||
|
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||||
|
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||||
|
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||||
|
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||||
|
function splitJvmOpts() {
|
||||||
|
JVM_OPTS=("$@")
|
||||||
|
}
|
||||||
|
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||||
|
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||||
|
|
||||||
|
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
90
gradlew.bat
vendored
Normal file
90
gradlew.bat
vendored
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
@if "%DEBUG%" == "" @echo off
|
||||||
|
@rem ##########################################################################
|
||||||
|
@rem
|
||||||
|
@rem Gradle startup script for Windows
|
||||||
|
@rem
|
||||||
|
@rem ##########################################################################
|
||||||
|
|
||||||
|
@rem Set local scope for the variables with windows NT shell
|
||||||
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
set DEFAULT_JVM_OPTS=
|
||||||
|
|
||||||
|
set DIRNAME=%~dp0
|
||||||
|
if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
|
set APP_BASE_NAME=%~n0
|
||||||
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@rem Find java.exe
|
||||||
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|
||||||
|
set JAVA_EXE=java.exe
|
||||||
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
|
if "%ERRORLEVEL%" == "0" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:findJavaFromJavaHome
|
||||||
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
|
if exist "%JAVA_EXE%" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:init
|
||||||
|
@rem Get command-line arguments, handling Windowz variants
|
||||||
|
|
||||||
|
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||||
|
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||||
|
|
||||||
|
:win9xME_args
|
||||||
|
@rem Slurp the command line arguments.
|
||||||
|
set CMD_LINE_ARGS=
|
||||||
|
set _SKIP=2
|
||||||
|
|
||||||
|
:win9xME_args_slurp
|
||||||
|
if "x%~1" == "x" goto execute
|
||||||
|
|
||||||
|
set CMD_LINE_ARGS=%*
|
||||||
|
goto execute
|
||||||
|
|
||||||
|
:4NT_args
|
||||||
|
@rem Get arguments from the 4NT Shell from JP Software
|
||||||
|
set CMD_LINE_ARGS=%$
|
||||||
|
|
||||||
|
:execute
|
||||||
|
@rem Setup the command line
|
||||||
|
|
||||||
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
|
@rem Execute Gradle
|
||||||
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||||
|
|
||||||
|
:end
|
||||||
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||||
|
|
||||||
|
:fail
|
||||||
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
|
rem the _cmd.exe /c_ return code!
|
||||||
|
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||||
|
exit /b 1
|
||||||
|
|
||||||
|
:mainEnd
|
||||||
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|
||||||
|
:omega
|
1
settings.gradle
Normal file
1
settings.gradle
Normal file
|
@ -0,0 +1 @@
|
||||||
|
include ':app', ':android_antlib_4-14-0'
|
Loading…
Reference in a new issue