diff --git a/README.md b/README.md index 0d8889ba..e261759e 100644 --- a/README.md +++ b/README.md @@ -5,10 +5,16 @@ One more try to make it working with Inmotion V8 Added support for Samsung Gear Tizen based watches -Pebble app code +## Pebble app code https://github.com/JumpMaster/WheelLogPebble -Samsung Gear app code +## Samsung Gear app code https://github.com/juliomap/WheelLog-Tizen + +## Garmin Connect IQ app code + +https://github.com/marccardinal/WheelLog-Garmin-ConnectIQ + +The watch application is also available for download directly on the ConnectIQ store https://apps.garmin.com/en-US/apps/07a231a9-3f2f-4762-b0bb-b8a0b5594f40 diff --git a/app/build.gradle b/app/build.gradle index 50cc0c72..9be99ee3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -7,7 +7,7 @@ repositories { android { compileSdkVersion 26 - buildToolsVersion '27.0.3' + buildToolsVersion '28.0.3' lintOptions { abortOnError false @@ -17,8 +17,8 @@ android { applicationId "com.cooper.wheellog" minSdkVersion 18 targetSdkVersion 26 - versionCode 36 - versionName "2.0.19" + versionCode 43 + versionName "2.0.23" buildConfigField 'String', 'BUILD_TIME', 'new java.text.SimpleDateFormat("HH:mm dd.MM.yyyy", java.util.Locale.US).format(new java.util.Date(' + System.currentTimeMillis() +'L))' } buildTypes { @@ -33,7 +33,7 @@ android { dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation fileTree(include: ['*.jar'], dir: 'libs') implementation 'com.android.support:design:25.1.0' implementation 'com.android.support:gridlayout-v7:25.1.0' implementation 'com.google.android.gms:play-services-drive:10.0.1' @@ -42,6 +42,8 @@ dependencies { implementation 'com.jakewharton.timber:timber:4.3.1' implementation 'com.pavelsikun:material-seekbar-preference:2.3.0+' implementation 'com.github.PhilJay:MPAndroidChart:v3.0.0' - implementation "com.github.hotchemi:permissionsdispatcher:2.2.0" + implementation 'com.github.hotchemi:permissionsdispatcher:2.2.0' annotationProcessor "com.github.hotchemi:permissionsdispatcher-processor:2.2.0" + implementation files('libs/connectiq.jar') + implementation 'org.nanohttpd:nanohttpd:2.3.1' } diff --git a/app/libs/connectiq.jar b/app/libs/connectiq.jar new file mode 100644 index 00000000..914b6392 Binary files /dev/null and b/app/libs/connectiq.jar differ diff --git a/app/release/output.json b/app/release/output.json index e0817289..07e9fe73 100644 --- a/app/release/output.json +++ b/app/release/output.json @@ -1 +1 @@ -[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":36,"versionName":"2.0.19","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}] \ No newline at end of file +[{"outputType":{"type":"APK"},"apkData":{"type":"MAIN","splits":[],"versionCode":43,"versionName":"2.0.23","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}] \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 83d20957..7fe5c2ba 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -58,7 +58,9 @@ - + + + mDevices; + private IQDevice mDevice; + private IQApp mMyApp; + + private GarminConnectIQWebServer mWebServer; + + public static boolean isInstanceCreated() { + return instance != null; + } + + public static GarminConnectIQ instance() { + return instance; + } + + @Override + public IBinder onBind(Intent intent) { + Log.i(TAG, "onBind"); + return null; + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + Log.d(TAG,"onStartCommand"); + super.onStartCommand(intent, flags, startId); + + instance = this; + + // Setup Connect IQ + mMyApp = new IQApp(APP_ID); + mConnectIQ = ConnectIQ.getInstance(this, IQConnectType.WIRELESS); + mConnectIQ.initialize(this, true, this); + + return START_STICKY; + } + + @Override + public void onDestroy() { + Log.d(TAG,"onDestroy"); + super.onDestroy(); + + cancelRefreshTimer(); + + try { + mConnectIQ.unregisterAllForEvents(); + mConnectIQ.shutdown(this); + } catch (InvalidStateException e) { + // This is usually because the SDK was already shut down + // so no worries. + } + + stopWebServer(); + + instance = null; + } + + // General METHODS + private void populateDeviceList() { + Log.d(TAG,"populateDeviceList"); + + try { + mDevices = mConnectIQ.getKnownDevices(); + + if (mDevices != null && !mDevices.isEmpty()) { + mDevice = mDevices.get(0); + registerWithDevice(); + } + + } catch (InvalidStateException e) { + // This generally means you forgot to call initialize(), but since + // we are in the callback for initialize(), this should never happen + } catch (ServiceUnavailableException e) { + // This will happen if for some reason your app was not able to connect + // to the ConnectIQ service running within Garmin Connect Mobile. This + // could be because Garmin Connect Mobile is not installed or needs to + // be upgraded. + Toast.makeText(this, R.string.garmin_connectiq_service_unavailable_message, Toast.LENGTH_LONG).show(); + } + } + + private void registerWithDevice() { + Log.d(TAG,"registerWithDevice"); + + if (mDevice != null && mSdkReady) { + // Register for device status updates + try { + mConnectIQ.registerForDeviceEvents(mDevice, this); + } catch (InvalidStateException e) { + Log.wtf(TAG, "InvalidStateException: We should not be here!"); + } + + // Register for application status updates + try { + mConnectIQ.getApplicationInfo(APP_ID, mDevice, this); + } catch (InvalidStateException e1) { + Log.d(TAG, "e1: " + e1.getMessage()); + } catch (ServiceUnavailableException e1) { + Log.d(TAG, "e2: " + e1.getMessage()); + } + + // Register to receive messages from the device + try { + mConnectIQ.registerForAppEvents(mDevice, mMyApp, this); + } catch (InvalidStateException e) { + Toast.makeText(this, "ConnectIQ is not in a valid state", Toast.LENGTH_LONG).show(); + } + } + } + + private void unregisterWithDevice() { + Log.d(TAG,"unregisterWithDevice"); + + if (mDevice != null && mSdkReady) { + // It is a good idea to unregister everything and shut things down to + // release resources and prevent unwanted callbacks. + try { + mConnectIQ.unregisterForDeviceEvents(mDevice); + + if (mMyApp != null) { + mConnectIQ.unregisterForApplicationEvents(mDevice, mMyApp); + } + } catch (InvalidStateException e) { + } + } + } + + private void cancelRefreshTimer() { + if (keepAliveTimer != null) { + keepAliveTimer.cancel(); + keepAliveTimer = null; + } + } + + private void startRefreshTimer() { + TimerTask timerTask = new TimerTask() { + @Override + public void run() { + handler.post(new Runnable() { + public void run() { + refreshData(); + } + }); + } + }; + + keepAliveTimer = new Timer(); + keepAliveTimer.scheduleAtFixedRate(timerTask, 0, 1500); // 1.5cs + } + + private void refreshData() { + if (WheelData.getInstance() == null) + return; + + try { + HashMap data = new HashMap(); + + lastSpeed = WheelData.getInstance().getSpeed() / 10; + data.put(MESSAGE_KEY_SPEED, lastSpeed); + + lastBattery = WheelData.getInstance().getBatteryLevel(); + data.put(MESSAGE_KEY_BATTERY, lastBattery); + + lastTemperature = WheelData.getInstance().getTemperature(); + data.put(MESSAGE_KEY_TEMPERATURE, lastTemperature); + + lastFanStatus = WheelData.getInstance().getFanStatus(); + data.put(MESSAGE_KEY_FAN_STATE, lastFanStatus); + + lastConnectionState = WheelData.getInstance().isConnected(); + data.put(MESSAGE_KEY_BT_STATE, lastConnectionState); + + data.put(MESSAGE_KEY_VIBE_ALERT, false); + data.put(MESSAGE_KEY_USE_MPH, SettingsUtil.isUseMPH(GarminConnectIQ.this)); + data.put(MESSAGE_KEY_MAX_SPEED, SettingsUtil.getMaxSpeed(GarminConnectIQ.this)); + + lastRideTime = WheelData.getInstance().getRideTime(); + data.put(MESSAGE_KEY_RIDE_TIME, lastRideTime); + + lastDistance = WheelData.getInstance().getDistance(); + data.put(MESSAGE_KEY_DISTANCE, lastDistance/100); + + lastTopSpeed = WheelData.getInstance().getTopSpeed(); + data.put(MESSAGE_KEY_TOP_SPEED, lastTopSpeed/10); + + lastPower = (int)WheelData.getInstance().getPowerDouble(); + data.put(MESSAGE_KEY_POWER, lastPower); + + HashMap message = new HashMap(); + message.put(MESSAGE_KEY_MSG_TYPE, MessageType.EUC_DATA.ordinal()); + message.put(MESSAGE_KEY_MSG_DATA, new MonkeyHash(data)); + + try { + mConnectIQ.sendMessage(mDevice, mMyApp, message, new IQSendMessageListener() { + + @Override + public void onMessageStatus(IQDevice device, IQApp app, IQMessageStatus status) { + Log.d(TAG, "message status: " + status.name()); + + if (status.name() != "SUCCESS") + Toast.makeText(GarminConnectIQ.this, status.name(), Toast.LENGTH_LONG).show(); + } + + }); + } catch (InvalidStateException e) { + Log.e(TAG, "ConnectIQ is not in a valid state"); + Toast.makeText(this, "ConnectIQ is not in a valid state", Toast.LENGTH_LONG).show(); + } catch (ServiceUnavailableException e) { + Log.e(TAG, "ConnectIQ service is unavailable. Is Garmin Connect Mobile installed and running?"); + Toast.makeText(this, "ConnectIQ service is unavailable. Is Garmin Connect Mobile installed and running?", Toast.LENGTH_LONG).show(); + } + } catch (Exception ex) { + Log.e(TAG, "refreshData", ex); + Toast.makeText(this, "Error refreshing data", Toast.LENGTH_SHORT).show(); + } + } + + // IQApplicationInfoListener METHODS + @Override + public void onApplicationInfoReceived(IQApp app) { + Log.d(TAG,"onApplicationInfoReceived"); + Log.d(TAG, app.toString()); + } + + @Override + public void onApplicationNotInstalled(String arg0) { + Log.d(TAG,"onApplicationNotInstalled"); + + // The WheelLog app is not installed on the device so we have + // to let the user know to install it. + cancelRefreshTimer(); // no point in sending data... + + Toast.makeText(this, R.string.garmin_connectiq_missing_app_message, Toast.LENGTH_LONG).show(); + try { + mConnectIQ.openStore(APP_ID); + } catch (InvalidStateException e) { + + } catch (ServiceUnavailableException e) { + + } + } + + // IQDeviceEventListener METHODS + @Override + public void onDeviceStatusChanged(IQDevice device, IQDeviceStatus status) { + Log.d(TAG,"onDeviceStatusChanged"); + Log.d(TAG, "status is:" + status.name()); + + switch(status.name()) { + case "CONNECTED": + // Disabled the push method for now until a dev from garmin can shed some light on the + // intermittent FAILURE_DURING_TRANSFER that we have seen. This is documented here: + // https://forums.garmin.com/developer/connect-iq/f/legacy-bug-reports/5144/failure_during_transfer-issue-again-now-using-comm-sample + if (!FEATURE_FLAG_NANOHTTPD) { + startRefreshTimer(); + } + + // As a workaround, start a nanohttpd server that will listen for data requests from the watch. This is + // also documented on the link above and is apparently a good workaround for the meantime. In our implementation + // we instanciate the httpd server on an ephemeral port and send a message to the watch to tell it on which port + // it can request its data. + if (FEATURE_FLAG_NANOHTTPD) { + startWebServer(); + } + break; + case "NOT_PAIRED": + case "NOT_CONNECTED": + case "UNKNOWN": + cancelRefreshTimer(); + stopWebServer(); + } + } + + // IQApplicationEventListener + @Override + public void onMessageReceived(IQDevice device, IQApp app, List message, IQMessageStatus status) { + Log.d(TAG,"onMessageReceived"); + + // We know from our widget that it will only ever send us strings, but in case + // we get something else, we are simply going to do a toString() on each object in the + // message list. + StringBuilder builder = new StringBuilder(); + + if (message.size() > 0) { + for (Object o : message) { + if (o == null) { + builder.append(" received"); + } else if (o instanceof HashMap) { + try { + HashMap msg = (HashMap)o; + int msgType = (int)msg.get(MESSAGE_KEY_MSG_TYPE); + if (msgType == MessageType.PLAY_HORN.ordinal()) { + playHorn(); + } + builder = null; + } catch (Exception ex) { + builder.append("MonkeyHash received:\n\n"); + builder.append(o.toString()); + } + } else { + builder.append(o.toString()); + builder.append("\r\n"); + } + } + } else { + builder.append("Received an empty message from the ConnectIQ application"); + } + + if (builder != null) { + Toast.makeText(getApplicationContext(), builder.toString(), Toast.LENGTH_SHORT).show(); + } + } + + // ConnectIQListener METHODS + @Override + public void onInitializeError(IQSdkErrorStatus errStatus) { + Log.d(TAG,"sdk initialization error"); + mSdkReady = false; + } + + @Override + public void onSdkReady() { + Log.d(TAG,"sdk is ready"); + mSdkReady = true; + populateDeviceList(); + } + + @Override + public void onSdkShutDown() { + Log.d(TAG,"sdk shut down"); + mSdkReady = false; + } + + public void playHorn() { + Context context = getApplicationContext(); + + int horn_mode = SettingsUtil.getHornMode(context); + if (horn_mode == 1) { + final Intent hornIntent = new Intent(ACTION_REQUEST_KINGSONG_HORN); + context.sendBroadcast(hornIntent); + } else if (horn_mode == 2) { + MediaPlayer mp = MediaPlayer.create(context, R.raw.bicycle_bell); + mp.start(); + mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { + @Override + public void onCompletion(MediaPlayer mp) { + mp.release(); + } + }); + } + } + + public void startWebServer() { + Log.d(TAG,"startWebServer"); + + if (mWebServer != null) + return; + + try { + mWebServer = new GarminConnectIQWebServer(); + Log.d(TAG, "port is:" + mWebServer.getListeningPort()); + + HashMap data = new HashMap(); + data.put(MESSAGE_KEY_HTTP_PORT, mWebServer.getListeningPort()); + + HashMap message = new HashMap(); + message.put(MESSAGE_KEY_MSG_TYPE, MessageType.HTTP_READY.ordinal()); + message.put(MESSAGE_KEY_MSG_DATA, new MonkeyHash(data)); + + try { + mConnectIQ.sendMessage(mDevice, mMyApp, message, new IQSendMessageListener() { + + @Override + public void onMessageStatus(IQDevice device, IQApp app, IQMessageStatus status) { + Log.d(TAG, "message status: " + status.name()); + + if (status.name() != "SUCCESS") + Toast.makeText(GarminConnectIQ.this, status.name(), Toast.LENGTH_LONG).show(); + } + + }); + } catch (InvalidStateException e) { + Log.e(TAG, "ConnectIQ is not in a valid state"); + Toast.makeText(this, "ConnectIQ is not in a valid state", Toast.LENGTH_LONG).show(); + } catch (ServiceUnavailableException e) { + Log.e(TAG, "ConnectIQ service is unavailable. Is Garmin Connect Mobile installed and running?"); + Toast.makeText(this, "ConnectIQ service is unavailable. Is Garmin Connect Mobile installed and running?", Toast.LENGTH_LONG).show(); + } + + } catch (IOException e) { + } + } + + public void stopWebServer() { + Log.d(TAG,"stopWebServer"); + if (mWebServer != null) { + mWebServer.stop(); + mWebServer = null; + } + } +} + +class GarminConnectIQWebServer extends NanoHTTPD { + public GarminConnectIQWebServer()throws IOException { + super("127.0.0.1", 0); // 0 to automatically find an available ephemeral port + start(NanoHTTPD.SOCKET_READ_TIMEOUT, false); + } + + @Override + public Response serve(IHTTPSession session) + { + if (session.getMethod() == Method.GET && session.getUri().equals("/data")) { + return handleData(); + } + + return newFixedLengthResponse(Response.Status.NOT_FOUND, NanoHTTPD.MIME_PLAINTEXT, "Error 404, file not found."); + } + + private Response handleData() { + Log.d("GarminConnectIQWebSe...","handleData"); + JSONObject data = new JSONObject(); + + try { + data.put("" + GarminConnectIQ.MESSAGE_KEY_SPEED, WheelData.getInstance().getSpeed() / 10); // Convert to km/h + data.put("" + GarminConnectIQ.MESSAGE_KEY_BATTERY, WheelData.getInstance().getBatteryLevel()); + data.put("" + GarminConnectIQ.MESSAGE_KEY_TEMPERATURE, WheelData.getInstance().getTemperature()); + data.put("" + GarminConnectIQ.MESSAGE_KEY_FAN_STATE, WheelData.getInstance().getFanStatus()); + data.put("" + GarminConnectIQ.MESSAGE_KEY_BT_STATE, WheelData.getInstance().isConnected()); + data.put("" + GarminConnectIQ.MESSAGE_KEY_VIBE_ALERT, false); + data.put("" + GarminConnectIQ.MESSAGE_KEY_USE_MPH, SettingsUtil.isUseMPH(GarminConnectIQ.instance())); + data.put("" + GarminConnectIQ.MESSAGE_KEY_MAX_SPEED, SettingsUtil.getMaxSpeed(GarminConnectIQ.instance())); + data.put("" + GarminConnectIQ.MESSAGE_KEY_RIDE_TIME, WheelData.getInstance().getRideTime()); + data.put("" + GarminConnectIQ.MESSAGE_KEY_DISTANCE, WheelData.getInstance().getDistance() / 100); + data.put("" + GarminConnectIQ.MESSAGE_KEY_TOP_SPEED, WheelData.getInstance().getTopSpeed() / 10); + data.put("" + GarminConnectIQ.MESSAGE_KEY_POWER, (int) WheelData.getInstance().getPowerDouble()); + data.put("" + GarminConnectIQ.MESSAGE_KEY_ALARM1_SPEED, WheelData.getInstance().getKSAlarm1Speed()); + data.put("" + GarminConnectIQ.MESSAGE_KEY_ALARM2_SPEED, WheelData.getInstance().getKSAlarm2Speed()); + data.put("" + GarminConnectIQ.MESSAGE_KEY_ALARM3_SPEED, WheelData.getInstance().getKSAlarm3Speed()); + + JSONObject message = new JSONObject(); + message.put("" + GarminConnectIQ.MESSAGE_KEY_MSG_TYPE, GarminConnectIQ.MessageType.EUC_DATA.ordinal()); + message.put("" + GarminConnectIQ.MESSAGE_KEY_MSG_DATA, data); + + return newFixedLengthResponse(Response.Status.OK, "application/json", message.toString()); + } catch (JSONException e) { + return newFixedLengthResponse(Response.Status.SERVICE_UNAVAILABLE, "text/plain", ""); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/cooper/wheellog/GoogleDriveService.java b/app/src/main/java/com/cooper/wheellog/GoogleDriveService.java index d2682a83..0e933c49 100644 --- a/app/src/main/java/com/cooper/wheellog/GoogleDriveService.java +++ b/app/src/main/java/com/cooper/wheellog/GoogleDriveService.java @@ -197,7 +197,7 @@ public void onResult(@NonNull DriveApi.DriveContentsResult result) { String line; while ((line = br.readLine()) != null) - writer.append(line).append('\r'); + writer.append(line).append('\n'); br.close(); writer.close(); diff --git a/app/src/main/java/com/cooper/wheellog/MainActivity.java b/app/src/main/java/com/cooper/wheellog/MainActivity.java index 6b5c13b2..1cf7acee 100644 --- a/app/src/main/java/com/cooper/wheellog/MainActivity.java +++ b/app/src/main/java/com/cooper/wheellog/MainActivity.java @@ -568,34 +568,34 @@ private void updateScreen(boolean updateGraph) { break; case 1: // Text View if (use_mph) { - tvSpeed.setText(String.format(Locale.US, "%.1f mph", kmToMiles(WheelData.getInstance().getSpeedDouble()))); - tvTopSpeed.setText(String.format(Locale.US, "%.1f mph", kmToMiles(WheelData.getInstance().getTopSpeedDouble()))); - tvAverageSpeed.setText(String.format(Locale.US, "%.1f mph", kmToMiles(WheelData.getInstance().getAverageSpeedDouble()))); - tvAverageRidingSpeed.setText(String.format(Locale.US, "%.1f mph", kmToMiles(WheelData.getInstance().getAverageRidingSpeedDouble()))); - tvDistance.setText(String.format(Locale.US, "%.2f mi", kmToMiles(WheelData.getInstance().getDistanceDouble()))); - tvWheelDistance.setText(String.format(Locale.US, "%.2f mi", kmToMiles(WheelData.getInstance().getWheelDistanceDouble()))); - tvUserDistance.setText(String.format(Locale.US, "%.2f mi", kmToMiles(WheelData.getInstance().getUserDistanceDouble()))); - tvTotalDistance.setText(String.format(Locale.US, "%.2f mi", kmToMiles(WheelData.getInstance().getTotalDistanceDouble()))); + tvSpeed.setText(String.format(Locale.US, "%.1f " + getString(R.string.mph), kmToMiles(WheelData.getInstance().getSpeedDouble()))); + tvTopSpeed.setText(String.format(Locale.US, "%.1f " + getString(R.string.mph), kmToMiles(WheelData.getInstance().getTopSpeedDouble()))); + tvAverageSpeed.setText(String.format(Locale.US, "%.1f " + getString(R.string.mph), kmToMiles(WheelData.getInstance().getAverageSpeedDouble()))); + tvAverageRidingSpeed.setText(String.format(Locale.US, "%.1f " + getString(R.string.mph), kmToMiles(WheelData.getInstance().getAverageRidingSpeedDouble()))); + tvDistance.setText(String.format(Locale.US, "%.2f " + getString(R.string.milli), kmToMiles(WheelData.getInstance().getDistanceDouble()))); + tvWheelDistance.setText(String.format(Locale.US, "%.2f " + getString(R.string.milli), kmToMiles(WheelData.getInstance().getWheelDistanceDouble()))); + tvUserDistance.setText(String.format(Locale.US, "%.2f " + getString(R.string.milli), kmToMiles(WheelData.getInstance().getUserDistanceDouble()))); + tvTotalDistance.setText(String.format(Locale.US, "%.2f " + getString(R.string.milli), kmToMiles(WheelData.getInstance().getTotalDistanceDouble()))); } else { - tvSpeed.setText(String.format(Locale.US, "%.1f km/h", WheelData.getInstance().getSpeedDouble())); - tvTopSpeed.setText(String.format(Locale.US, "%.1f km/h", WheelData.getInstance().getTopSpeedDouble())); - tvAverageSpeed.setText(String.format(Locale.US, "%.1f km/h", WheelData.getInstance().getAverageSpeedDouble())); - tvAverageRidingSpeed.setText(String.format(Locale.US, "%.1f km/h", WheelData.getInstance().getAverageRidingSpeedDouble())); - tvDistance.setText(String.format(Locale.US, "%.3f km", WheelData.getInstance().getDistanceDouble())); - tvWheelDistance.setText(String.format(Locale.US, "%.3f km", WheelData.getInstance().getWheelDistanceDouble())); - tvUserDistance.setText(String.format(Locale.US, "%.3f km", WheelData.getInstance().getUserDistanceDouble())); - tvTotalDistance.setText(String.format(Locale.US, "%.3f km", WheelData.getInstance().getTotalDistanceDouble())); + tvSpeed.setText(String.format(Locale.US, "%.1f " + getString(R.string.kmh), WheelData.getInstance().getSpeedDouble())); + tvTopSpeed.setText(String.format(Locale.US, "%.1f " + getString(R.string.kmh), WheelData.getInstance().getTopSpeedDouble())); + tvAverageSpeed.setText(String.format(Locale.US, "%.1f " + getString(R.string.kmh), WheelData.getInstance().getAverageSpeedDouble())); + tvAverageRidingSpeed.setText(String.format(Locale.US, "%.1f " + getString(R.string.kmh), WheelData.getInstance().getAverageRidingSpeedDouble())); + tvDistance.setText(String.format(Locale.US, "%.3f " + getString(R.string.km), WheelData.getInstance().getDistanceDouble())); + tvWheelDistance.setText(String.format(Locale.US, "%.3f " + getString(R.string.km), WheelData.getInstance().getWheelDistanceDouble())); + tvUserDistance.setText(String.format(Locale.US, "%.3f " + getString(R.string.km), WheelData.getInstance().getUserDistanceDouble())); + tvTotalDistance.setText(String.format(Locale.US, "%.3f " + getString(R.string.km), WheelData.getInstance().getTotalDistanceDouble())); } - tvVoltage.setText(String.format(Locale.US, "%.2fV", WheelData.getInstance().getVoltageDouble())); + tvVoltage.setText(String.format(Locale.US, "%.2f " + getString(R.string.volt), WheelData.getInstance().getVoltageDouble())); tvTemperature.setText(String.format(Locale.US, "%d°C", WheelData.getInstance().getTemperature())); tvTemperature2.setText(String.format(Locale.US, "%d°C", WheelData.getInstance().getTemperature2())); tvAngle.setText(String.format(Locale.US, "%.2f°", WheelData.getInstance().getAngle())); tvRoll.setText(String.format(Locale.US, "%.2f°", WheelData.getInstance().getRoll())); - tvCurrent.setText(String.format(Locale.US, "%.2fA", WheelData.getInstance().getCurrentDouble())); - tvPower.setText(String.format(Locale.US, "%.2fW", WheelData.getInstance().getPowerDouble())); + tvCurrent.setText(String.format(Locale.US, "%.2f " + getString(R.string.amp), WheelData.getInstance().getCurrentDouble())); + tvPower.setText(String.format(Locale.US, "%.2f " + getString(R.string.watt), WheelData.getInstance().getPowerDouble())); tvBattery.setText(String.format(Locale.US, "%d%%", WheelData.getInstance().getBatteryLevel())); - tvFanStatus.setText(WheelData.getInstance().getFanStatus() == 0 ? "Off" : "On"); + tvFanStatus.setText(WheelData.getInstance().getFanStatus() == 0 ? getString(R.string.off) : getString(R.string.on)); tvVersion.setText(String.format(Locale.US, "%s", WheelData.getInstance().getVersion())); tvName.setText(WheelData.getInstance().getName()); tvModel.setText(WheelData.getInstance().getModel()); @@ -614,8 +614,8 @@ private void updateScreen(boolean updateGraph) { LineDataSet dataSetCurrent; if (chart1.getData() == null) { - dataSetSpeed = new LineDataSet(null, "speed"); - dataSetCurrent = new LineDataSet(null, "current"); + dataSetSpeed = new LineDataSet(null, getString(R.string.speed_axis)); + dataSetCurrent = new LineDataSet(null, getString(R.string.current_axis)); dataSetSpeed.setLineWidth(2); dataSetCurrent.setLineWidth(2); dataSetSpeed.setAxisDependency(YAxis.AxisDependency.LEFT); @@ -635,8 +635,8 @@ private void updateScreen(boolean updateGraph) { findViewById(R.id.leftAxisLabel).setVisibility(View.VISIBLE); findViewById(R.id.rightAxisLabel).setVisibility(View.VISIBLE); } else { - dataSetSpeed = (LineDataSet) chart1.getData().getDataSetByLabel("speed", true); - dataSetCurrent = (LineDataSet) chart1.getData().getDataSetByLabel("current", true); + dataSetSpeed = (LineDataSet) chart1.getData().getDataSetByLabel(getString(R.string.speed_axis), true); + dataSetCurrent = (LineDataSet) chart1.getData().getDataSetByLabel(getString(R.string.current_axis), true); } dataSetSpeed.clear(); @@ -765,6 +765,7 @@ public void onDrawerStateChanged(int newState) { chart1.setHighlightPerTapEnabled(false); chart1.setHighlightPerDragEnabled(false); chart1.getLegend().setTextColor(getResources().getColor(android.R.color.white)); + chart1.setNoDataText(getString(R.string.no_chart_data)); chart1.setNoDataTextColor(getResources().getColor(android.R.color.white)); YAxis leftAxis = chart1.getAxisLeft(); @@ -853,6 +854,7 @@ public void onPause() { @Override protected void onDestroy() { stopPebbleService(); + stopGarminConnectIQ(); stopLoggingService(); WheelData.getInstance().full_reset(); if (mBluetoothLeService != null) { @@ -861,7 +863,7 @@ protected void onDestroy() { mBluetoothLeService = null; } super.onDestroy(); - new CountDownTimer(500, 100) { + new CountDownTimer(60000, 100) { @Override public void onTick(long millisUntilFinished) { @@ -903,6 +905,10 @@ public boolean onOptionsItemSelected(MenuItem item) { return true; case R.id.miWatch: togglePebbleService(); + if (SettingsUtil.getGarminConnectIQEnable(this)) + toggleGarminConnectIQ(); + else + stopGarminConnectIQ(); return true; default: return super.onOptionsItemSelected(item); @@ -967,7 +973,7 @@ private void loadPreferences() { boolean use_ratio = sharedPreferences.getBoolean(getString(R.string.use_ratio), false); WheelData.getInstance().setUseRatio(use_ratio); - int gotway_voltage = Integer.parseInt(sharedPreferences.getString(getString(R.string.gotway_voltage), "0")); + int gotway_voltage = Integer.parseInt(sharedPreferences.getString(getString(R.string.gotway_voltage), "1")); WheelData.getInstance().setGotwayVoltage(gotway_voltage); //boolean gotway_84v = sharedPreferences.getBoolean(getString(R.string.gotway_84v), false); @@ -1080,6 +1086,18 @@ private void togglePebbleService() { startService(pebbleServiceIntent); } + private void stopGarminConnectIQ() { + if (GarminConnectIQ.isInstanceCreated()) + toggleGarminConnectIQ(); + } + private void toggleGarminConnectIQ() { + Intent garminConnectIQIntent = new Intent(getApplicationContext(), GarminConnectIQ.class); + if (GarminConnectIQ.isInstanceCreated()) + stopService(garminConnectIQIntent); + else + startService(garminConnectIQIntent); + } + private void startBluetoothService() { Intent bluetoothServiceIntent = new Intent(getApplicationContext(), BluetoothLeService.class); startService(bluetoothServiceIntent); @@ -1203,4 +1221,6 @@ private Fragment getPreferencesFragment() { return frag; } + + } \ No newline at end of file diff --git a/app/src/main/java/com/cooper/wheellog/PreferencesFragment.java b/app/src/main/java/com/cooper/wheellog/PreferencesFragment.java index 833c3d18..2ae2305d 100644 --- a/app/src/main/java/com/cooper/wheellog/PreferencesFragment.java +++ b/app/src/main/java/com/cooper/wheellog/PreferencesFragment.java @@ -13,18 +13,12 @@ import android.view.View; import android.widget.*; import android.text.InputType; -import android.text.TextUtils; import com.cooper.wheellog.utils.Constants; import com.cooper.wheellog.utils.Constants.WHEEL_TYPE; import com.cooper.wheellog.utils.SettingsUtil; -import com.cooper.wheellog.BuildConfig; import com.pavelsikun.seekbarpreference.SeekBarPreference; - - -import timber.log.Timber; - public class PreferencesFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener { enum SettingsScreen { @@ -74,8 +68,8 @@ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, Strin if (SettingsUtil.isAutoUploadEnabled(getActivity()) && !mDataWarningDisplayed) { SettingsUtil.setAutoUploadEnabled(getActivity(), false); new AlertDialog.Builder(getActivity()) - .setTitle("Enable Auto Upload?") - .setMessage("Automatic uploading while not connected to WiFi will use your mobile data. This may result in charges from your network provider if you do not have a data plan.") + .setTitle(getString(R.string.enable_auto_upload_title)) // ("Enable Auto Upload?") + .setMessage(getString(R.string.enable_auto_upload_descriprion)) .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { mDataWarningDisplayed = true; @@ -178,6 +172,18 @@ public void onClick(DialogInterface dialog, int which) { int led_mode = Integer.parseInt(sharedPreferences.getString(getString(R.string.led_mode), "0")); WheelData.getInstance().updateLedMode(led_mode); break; + case "wheel_ks_alarm3": + final int alert3 = sharedPreferences.getInt("wheel_ks_alarm3", 0); + WheelData.getInstance().updateKSAlarm3(alert3); + break; + case "wheel_ks_alarm2": + final int alert2 = sharedPreferences.getInt("wheel_ks_alarm2", 0); + WheelData.getInstance().updateKSAlarm2(alert2); + break; + case "wheel_ks_alarm1": + final int alert1 = sharedPreferences.getInt("wheel_ks_alarm1", 0); + WheelData.getInstance().updateKSAlarm1(alert1); + break; // case "reset_user_trip": // WheelData.getInstance().resetUserDistance(); // break; @@ -207,7 +213,7 @@ public void onClick(View view) { switch (currentScreen) { case Main: - tb.setTitle("Settings"); + tb.setTitle(getText(R.string.settings_title)); Preference speed_button = findPreference(getString(R.string.speed_preferences)); Preference logs_button = findPreference(getString(R.string.log_preferences)); Preference alarm_button = findPreference(getString(R.string.alarm_preferences)); @@ -276,7 +282,17 @@ public boolean onPreferenceClick(Preference preference) { getPreferenceScreen().removeAll(); if (mWheelType == WHEEL_TYPE.NINEBOT_Z) addPreferencesFromResource(R.xml.preferences_ninebot_z); if (mWheelType == WHEEL_TYPE.INMOTION) addPreferencesFromResource(R.xml.preferences_inmotion); - if (mWheelType == WHEEL_TYPE.KINGSONG) addPreferencesFromResource(R.xml.preferences_kingsong); + if (mWheelType == WHEEL_TYPE.KINGSONG) { + addPreferencesFromResource(R.xml.preferences_kingsong); + if(WheelData.getInstance().is_pref_received()) { + + correctWheelBarState(getString(R.string.wheel_max_speed), WheelData.getInstance().getWheelMaxSpeed()); + correctWheelBarState(getString(R.string.wheel_ks_alarm1), WheelData.getInstance().getKSAlarm1Speed()); + correctWheelBarState(getString(R.string.wheel_ks_alarm2), WheelData.getInstance().getKSAlarm2Speed()); + correctWheelBarState(getString(R.string.wheel_ks_alarm3), WheelData.getInstance().getKSAlarm3Speed()); + + } + } if (mWheelType == WHEEL_TYPE.GOTWAY) { //if (mWheelType == WHEEL_TYPE.INMOTION) { addPreferencesFromResource(R.xml.preferences_gotway); @@ -323,9 +339,9 @@ public boolean onPreferenceClick(Preference preference) { String versionName = BuildConfig.VERSION_NAME; String buildTime = BuildConfig.BUILD_TIME; new AlertDialog.Builder(getActivity()) - .setTitle("About WheelLog") - .setMessage(Html.fromHtml(String.format("Version %s
build at %s
by Palachzzz
palachzzz.wl@gmail.com", versionName, buildTime))) - .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { + .setTitle(R.string.about_app_title) + .setMessage(Html.fromHtml(String.format("Version %s
build at %s
by Palachzzz
palachzzz.wl@gmail.com
Thanks to:
JumpMaster - project initiator
cedbossneo - Inmotion support
juliomap - Tizen support
MacPara - some improvements
datarsoja - KS alerts
and others!", versionName, buildTime))) + .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { } @@ -344,24 +360,24 @@ public void onClick(DialogInterface dialog, int which) { @Override public boolean onPreferenceClick(Preference preference) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - builder.setTitle("MAC Edit"); + builder.setTitle(getText(R.string.edit_mac_addr_title)); final EditText input = new EditText(getActivity()); input.setInputType(InputType.TYPE_CLASS_TEXT); input.setText(SettingsUtil.getLastAddress(getActivity())); builder.setView(input); - builder.setPositiveButton("OK", new DialogInterface.OnClickListener() { + builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { final String deviceAddress = input.getText().toString(); SettingsUtil.setLastAddress(getActivity(), deviceAddress); AlertDialog.Builder builder1 = new AlertDialog.Builder(getActivity()); - builder1.setTitle("Wheel Password ( InMotion only )"); + builder1.setTitle(getText(R.string.wheel_pass_imotion)); final EditText input1 = new EditText(getActivity()); input1.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); builder1.setView(input1); - builder1.setPositiveButton("OK", new DialogInterface.OnClickListener() { + builder1.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { String password = input1.getText().toString(); @@ -374,7 +390,7 @@ public void onClick(DialogInterface dialog, int which) { //finish(); } }); - builder1.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { + builder1.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.cancel(); @@ -389,7 +405,7 @@ public void onClick(DialogInterface dialog, int which) { //finish(); } }); - builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { + builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.cancel(); @@ -407,20 +423,20 @@ public void onClick(DialogInterface dialog, int which) { break; case Speed: - tb.setTitle("Speed Settings"); + tb.setTitle(getText(R.string.speed_settings_title)); break; case Logs: - tb.setTitle("Log Settings"); + tb.setTitle(getText(R.string.logs_settings_title)); break; case Alarms: - tb.setTitle("Alarm Settings"); + tb.setTitle(getText(R.string.alarm_settings_title)); hideShowSeekBars(); break; case Watch: - tb.setTitle("Watch Settings"); + tb.setTitle(getText(R.string.watch_settings_title)); break; case Wheel: - tb.setTitle("Wheel Settings"); + tb.setTitle(getText(R.string.wheel_settings_title)); //getActivity().sendBroadcast(new Intent(Constants.ACTION_WHEEL_SETTING_CHANGED).putExtra(Constants.INTENT_EXTRA_WHEEL_REFRESH, true)); break; } diff --git a/app/src/main/java/com/cooper/wheellog/ScanActivity.java b/app/src/main/java/com/cooper/wheellog/ScanActivity.java index db6c8563..5efde550 100644 --- a/app/src/main/java/com/cooper/wheellog/ScanActivity.java +++ b/app/src/main/java/com/cooper/wheellog/ScanActivity.java @@ -103,12 +103,12 @@ public void onItemClick(AdapterView adapterView, final View view, int i, long setResult(RESULT_OK, intent); //Ask for inmotion password AlertDialog.Builder builder = new AlertDialog.Builder(view.getContext()); - builder.setTitle("Wheel Password ( InMotion only )"); + builder.setTitle(R.string.wheel_pass_imotion); final EditText input = new EditText(view.getContext()); input.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); builder.setView(input); - builder.setPositiveButton("OK", new DialogInterface.OnClickListener() { + builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { String password = input.getText().toString(); @@ -116,7 +116,7 @@ public void onClick(DialogInterface dialog, int which) { finish(); } }); - builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { + builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.cancel(); diff --git a/app/src/main/java/com/cooper/wheellog/WheelData.java b/app/src/main/java/com/cooper/wheellog/WheelData.java index 1d19dccf..e5343223 100644 --- a/app/src/main/java/com/cooper/wheellog/WheelData.java +++ b/app/src/main/java/com/cooper/wheellog/WheelData.java @@ -8,6 +8,8 @@ import android.content.DialogInterface; import android.content.Intent; import android.os.Vibrator; +import android.media.ToneGenerator; +import android.media.AudioManager; import android.text.InputType; import android.widget.EditText; @@ -18,6 +20,7 @@ import com.cooper.wheellog.utils.NinebotZAdapter; import com.cooper.wheellog.utils.SettingsUtil; + import java.text.SimpleDateFormat; import java.util.*; import java.util.concurrent.TimeUnit; @@ -62,6 +65,7 @@ public class WheelData { private int mFanStatus; private boolean mConnectionState = false; private boolean mNewWheelSettings = false; + private boolean mKSAlertsAndSpeedupdated = false; private String mName = "Unknown"; private String mModel = "Unknown"; private String mModeStr = "Unknown"; @@ -79,7 +83,7 @@ public class WheelData { private boolean mWheelLightEnabled = false; private boolean mWheelLedEnabled = false; private boolean mWheelButtonDisabled = false; - private int mWheelMaxSpeed = 25; + private int mWheelMaxSpeed = 0; private int mWheelSpeakerVolume = 50; private int mWheelTiltHorizon = 0; @@ -88,6 +92,9 @@ public class WheelData { private int mAlarm1Speed = 0; private int mAlarm2Speed = 0; private int mAlarm3Speed = 0; + private int mKSAlarm1Speed = 0; + private int mKSAlarm2Speed = 0; + private int mKSAlarm3Speed = 0; private int mAlarm1Battery = 0; private int mAlarm2Battery = 0; private int mAlarm3Battery = 0; @@ -149,9 +156,25 @@ boolean getWheelHandleButton() { } int getWheelMaxSpeed() { + return mWheelMaxSpeed; } - + + int getKSAlarm1Speed() { + + return mKSAlarm1Speed; + } + + int getKSAlarm2Speed() { + + return mKSAlarm2Speed; + } + + int getKSAlarm3Speed() { + + return mKSAlarm3Speed; + } + int getSpeakerVolume() { return mWheelSpeakerVolume; } @@ -160,6 +183,10 @@ int getPedalsPosition() { return mWheelTiltHorizon; } + public boolean is_pref_received(){ + return mKSAlertsAndSpeedupdated; + } + public void setBtName(String btName) { mBtName = btName; } @@ -348,19 +375,57 @@ public void updateMaxSpeed(int wheelMaxSpeed) { } } if (mWheelType == WHEEL_TYPE.KINGSONG) { - byte[] data = new byte[20]; - data[0] = (byte) 0xAA; - data[1] = (byte) 0x55; - data[6] = (byte) 0x1F; - data[8] = (byte) wheelMaxSpeed; - data[16] = (byte) 0x85; - data[17] = (byte) 0x14; - data[18] = (byte) 0x5A; - data[19] = (byte) 0x5A; - mBluetoothLeService.writeBluetoothGattCharacteristic(data); + if (mWheelMaxSpeed != wheelMaxSpeed) { + mWheelMaxSpeed = wheelMaxSpeed; + updateKSAlarmAndSpeed(); + } } } + + public void updateKSAlarmAndSpeed() { + byte[] data = new byte[20]; + data[0] = (byte) 0xAA; + data[1] = (byte) 0x55; + data[2] = (byte) mKSAlarm1Speed; + data[4] = (byte) mKSAlarm2Speed; + data[6] = (byte) mKSAlarm3Speed; + data[8] = (byte) mWheelMaxSpeed; + data[16] = (byte) 0x85; + + if((mWheelMaxSpeed | mKSAlarm3Speed | mKSAlarm2Speed | mKSAlarm1Speed) == 0){ + data[16] = (byte) 0x98; // request speed & alarm values from wheel + } + + data[17] = (byte) 0x14; + data[18] = (byte) 0x5A; + data[19] = (byte) 0x5A; + mBluetoothLeService.writeBluetoothGattCharacteristic(data); + + } + public void updateKSAlarm1(int wheelKSAlarm1) { + if (mKSAlarm1Speed != wheelKSAlarm1) { + mKSAlarm1Speed = wheelKSAlarm1; + updateKSAlarmAndSpeed(); + } + + } + + public void updateKSAlarm2(int wheelKSAlarm2) { + if (mKSAlarm2Speed != wheelKSAlarm2) { + mKSAlarm2Speed = wheelKSAlarm2; + updateKSAlarmAndSpeed(); + } + + } + + public void updateKSAlarm3(int wheelKSAlarm3) { + if (mKSAlarm3Speed != wheelKSAlarm3) { + mKSAlarm3Speed = wheelKSAlarm3; + updateKSAlarmAndSpeed(); + } + + } public void updateSpeakerVolume(int speakerVolume) { if (mWheelSpeakerVolume != speakerVolume) { @@ -691,21 +756,23 @@ private void raiseAlarm(ALARM_TYPE alarmType, Context mContext) { switch (alarmType) { case SPEED: - pattern = new long[]{0, 300, 150, 300, 150, 500}; + pattern = new long[]{0, 100, 100}; mSpeedAlarmExecuted = true; break; case CURRENT: - pattern = new long[]{0, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100}; + pattern = new long[]{0, 50, 50, 50, 50}; mCurrentAlarmExecuted = true; break; case TEMPERATURE: - pattern = new long[]{0, 500, 100, 100, 100, 500, 100, 100, 100, 500, 100, 100, 100}; + pattern = new long[]{0, 500, 500}; mCurrentAlarmExecuted = true; break; } mContext.sendBroadcast(intent); if (v.hasVibrator() && !mDisablePhoneVibrate) v.vibrate(pattern, -1); + ToneGenerator toneG = new ToneGenerator(AudioManager.STREAM_ALARM, 100); + toneG.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD, 200); } void decodeResponse(byte[] data, Context mContext) { @@ -792,7 +859,7 @@ private boolean decodeKingSong(byte[] data) { int battery; - if ((mModel.compareTo("KS-18L") == 0) || (mBtName.compareTo("RW") == 0 )) { + if ((mModel.compareTo("KS-18L") == 0) || (mModel.compareTo("KS-16X") == 0) ||(mBtName.compareTo("RW") == 0) || (mName.startsWith("ROCKW"))) { if (mVoltage > 8350) { battery = 100; @@ -862,6 +929,21 @@ private boolean decodeKingSong(byte[] data) { System.arraycopy(data, 17, sndata, 14, 3); sndata[17] = (byte) 0; mSerialNumber = new String(sndata); + updateKSAlarmAndSpeed(); + } + else if ((data[16] & 255) == 164 || (data[16] & 255) == 181) { //0xa4 || 0xb5 max speed and alerts + mWheelMaxSpeed = (data[10] & 255); + mKSAlarm3Speed = (data[8] & 255); + mKSAlarm2Speed = (data[6] & 255); + mKSAlarm1Speed = (data[4] & 255); + mKSAlertsAndSpeedupdated = true; + // after received 0xa4 send same repeat data[2] =0x01 data[16] = 0x98 + if((data[16] & 255) == 164) + { + data[16] = (byte)0x98; + mBluetoothLeService.writeBluetoothGattCharacteristic(data); + } + } } return false; @@ -1062,7 +1144,7 @@ void reset() { mWheelLightEnabled = false; mWheelLedEnabled = false; mWheelButtonDisabled = false; - mWheelMaxSpeed = 25; + mWheelMaxSpeed = 0; mWheelSpeakerVolume = 50; } @@ -1128,7 +1210,7 @@ boolean detectWheel(BluetoothLeService bluetoothService) { mContext.sendBroadcast(intent); Timber.i("Protocol recognized as %s", wheel_Type); //System.out.println("WheelRecognizedWD"); - if (mContext.getResources().getString(R.string.gotway).equals(wheel_Type) && (mBtName.equals("RW"))) { + if (mContext.getResources().getString(R.string.gotway).equals(wheel_Type) && (mBtName.equals("RW") || mName.startsWith("ROCKW"))) { Timber.i("It seems to be RochWheel, force to Kingsong proto"); wheel_Type = mContext.getResources().getString(R.string.kingsong); } diff --git a/app/src/main/java/com/cooper/wheellog/utils/SettingsUtil.java b/app/src/main/java/com/cooper/wheellog/utils/SettingsUtil.java index 310e5b85..fe43d928 100644 --- a/app/src/main/java/com/cooper/wheellog/utils/SettingsUtil.java +++ b/app/src/main/java/com/cooper/wheellog/utils/SettingsUtil.java @@ -98,6 +98,10 @@ public static int getHornMode(Context context) { return Integer.parseInt(getSharedPreferences(context).getString(context.getString(R.string.horn_mode), "0")); } + public static boolean getGarminConnectIQEnable(Context context) { + return getSharedPreferences(context).getBoolean(context.getString(R.string.garmin_connectiq_enable), false); + } + //Inmotion Specific, but can be the same for other wheels public static boolean hasPasswordForWheel(Context context, String id) { diff --git a/app/src/main/java/com/cooper/wheellog/views/WheelView.java b/app/src/main/java/com/cooper/wheellog/views/WheelView.java index 15ef9240..472ca918 100644 --- a/app/src/main/java/com/cooper/wheellog/views/WheelView.java +++ b/app/src/main/java/com/cooper/wheellog/views/WheelView.java @@ -293,7 +293,7 @@ protected void onSizeChanged(int w, int h, int oldw, int oldh) { Math.round(center_x + (speedTextKPHRectSize/2)), Math.round(center_y + (speedTextKPHRectSize/2))); - speedTextKPHSize = calculateFontSize(boundaryOfText, speedTextKPHRect, "km/h", textPaint); + speedTextKPHSize = calculateFontSize(boundaryOfText, speedTextKPHRect, getResources().getString(R.string.kmh), textPaint); speedTextKPHHeight = boundaryOfText.height(); @@ -437,7 +437,7 @@ protected void onDraw(Canvas canvas) { canvas.drawText(speedString, outerArcRect.centerX(), speedTextRect.centerY()+(speedTextRect.height()/2), textPaint); textPaint.setTextSize(speedTextKPHSize); textPaint.setColor(getContext().getResources().getColor(R.color.wheelview_text)); - String metric = mUseMPH ? "mph" : "km/h"; + String metric = mUseMPH ? getResources().getString(R.string.mph) : getResources().getString(R.string.kmh); canvas.drawText(metric, outerArcRect.centerX(),speedTextRect.bottom+(speedTextKPHHeight*1.25F), textPaint); //#################################################### @@ -490,24 +490,24 @@ protected void onDraw(Canvas canvas) { canvas.drawText(getResources().getString(R.string.distance), blRect.centerX(), blRect.centerY() - (box_inner_padding / 2), textPaint); canvas.drawText(getResources().getString(R.string.total), brRect.centerX(), brRect.centerY() - (box_inner_padding / 2), textPaint); - canvas.drawText(String.format(Locale.US, "%.2fV", mVoltage), tlRect.centerX(), tlRect.centerY() + boxTextHeight, textPaint); + canvas.drawText(String.format(Locale.US, "%.2f " + getResources().getString(R.string.volt), mVoltage), tlRect.centerX(), tlRect.centerY() + boxTextHeight, textPaint); //canvas.drawText(String.format(Locale.US, "%.2fW", mCurrent), trRect.centerX(), trRect.centerY() + boxTextHeight, textPaint); canvas.drawText(mCurrentTime, mlRect.centerX(), mlRect.centerY() + boxTextHeight + (box_inner_padding / 2), textPaint); if (mUseMPH) { - canvas.drawText(String.format(Locale.US, "%.1f mph", kmToMiles(mTopSpeed)), mrRect.centerX(), mrRect.centerY() + boxTextHeight, textPaint); - canvas.drawText(String.format(Locale.US, "%.2f mi", kmToMiles(mDistance)), blRect.centerX(), blRect.centerY() + boxTextHeight, textPaint); - canvas.drawText(String.format(Locale.US, "%.0f mi", kmToMiles(mTotalDistance)), brRect.centerX(), brRect.centerY() + boxTextHeight, textPaint); - canvas.drawText(String.format(Locale.US, "%.1f mph", kmToMiles(mAverageSpeed)), trRect.centerX(), trRect.centerY() + boxTextHeight, textPaint); + canvas.drawText(String.format(Locale.US, "%.1f " + getResources().getString(R.string.mph), kmToMiles(mTopSpeed)), mrRect.centerX(), mrRect.centerY() + boxTextHeight, textPaint); + canvas.drawText(String.format(Locale.US, "%.2f " + getResources().getString(R.string.milli), kmToMiles(mDistance)), blRect.centerX(), blRect.centerY() + boxTextHeight, textPaint); + canvas.drawText(String.format(Locale.US, "%.0f " + getResources().getString(R.string.milli), kmToMiles(mTotalDistance)), brRect.centerX(), brRect.centerY() + boxTextHeight, textPaint); + canvas.drawText(String.format(Locale.US, "%.1f " + getResources().getString(R.string.mph), kmToMiles(mAverageSpeed)), trRect.centerX(), trRect.centerY() + boxTextHeight, textPaint); } else { - canvas.drawText(String.format(Locale.US, "%.1f km/h", mTopSpeed), mrRect.centerX(), mrRect.centerY() + boxTextHeight, textPaint); - canvas.drawText(String.format(Locale.US, "%.1f km/h", mAverageSpeed), trRect.centerX(), trRect.centerY() + boxTextHeight, textPaint); + canvas.drawText(String.format(Locale.US, "%.1f " + getResources().getString(R.string.kmh), mTopSpeed), mrRect.centerX(), mrRect.centerY() + boxTextHeight, textPaint); + canvas.drawText(String.format(Locale.US, "%.1f " + getResources().getString(R.string.kmh), mAverageSpeed), trRect.centerX(), trRect.centerY() + boxTextHeight, textPaint); if (mDistance < 1) - canvas.drawText(String.format(Locale.US, "%.0f m", mDistance * 1000), blRect.centerX(), blRect.centerY() + boxTextHeight, textPaint); + canvas.drawText(String.format(Locale.US, "%.0f " + getResources().getString(R.string.metre), mDistance * 1000), blRect.centerX(), blRect.centerY() + boxTextHeight, textPaint); else - canvas.drawText(String.format(Locale.US, "%.2f km", mDistance), blRect.centerX(), blRect.centerY() + boxTextHeight, textPaint); + canvas.drawText(String.format(Locale.US, "%.2f " + getResources().getString(R.string.km), mDistance), blRect.centerX(), blRect.centerY() + boxTextHeight, textPaint); - canvas.drawText(String.format(Locale.US, "%.0f km", mTotalDistance), brRect.centerX(), brRect.centerY() + boxTextHeight, textPaint); + canvas.drawText(String.format(Locale.US, "%.0f " + getResources().getString(R.string.km), mTotalDistance), brRect.centerX(), brRect.centerY() + boxTextHeight, textPaint); } } diff --git a/app/src/main/res/layout/main_view_three.xml b/app/src/main/res/layout/main_view_three.xml index a42fdf72..f83abe4c 100644 --- a/app/src/main/res/layout/main_view_three.xml +++ b/app/src/main/res/layout/main_view_three.xml @@ -14,7 +14,7 @@ android:layout_marginLeft="5dp" android:layout_alignParentTop="true" android:textColor="@android:color/white" - android:text="km/h"/> + android:text="@string/kmh"/> + android:text="@string/amp"/> + + WheelLog + Первое предупреждение + Второе предупреждение + Третье предупреждение + Подъем педалей + Поиск + Остановить + Подключить + Подключение + Макс. скорость + Батарея + Расстояние + Поездка + Мой пробег + Время работы + Время в пути + Напряжение + Ток + Мощность + Температура + Пробег + Сред. скорость + Сред. движения + Наклон вперед + Наклон в бок + Темп. процессора + Пробег + Название + Модель + Версия + Серийный номер + Ожидание колеса + Вентилятор + Скорость + Режим работы + Модель колеса определена %1$s + Начало записи в %1$s + Поиск... + Повторно нажмите назад для выхода + км/ч + миль/ч + км + мили + Настройка Сигнала + Скорость подъема педалей + 4 звуковых сигнала + 3 звуковых сигнала + 2 звуковых сигнала + Подавать звуковой сингнал при нажатии кнопки на часах Pebble. + Настройки педалей + Режим светодиодов + Режим стробоскопа + Режим фары + Вкл./Выкл. + Вкл./Выкл./Авто + Вкл. + Выкл. + Авто + Строб + Отключено + Включено + Жесткие + Средние + Мягкие + Встроенный (KingSong) + через блютуз + Настройки скорости + Настройки логирования + Настройки сигналов + Настройки часов + Настройки колеса + Обнулить максимальную скорость + Обнулить мой пробег + Изменить MAC адрес + О программе Wheellog + Настройки + Пароль (только для Inmotion) + А + Максимальная скорость + Ограничение спидометра на главном экране. + Использовать мили + Показывать мили вместо километров. + Включить предупреждения + Телефон будет вибрировать во время предупреждения. + Отключить вибросигнал + Телефон не будет вибрировать, но часы Pebble будут показывать предупреждения. + Превышение скорости 1 + Предупреждение о достигнутой скорости + Превышение скорости 2 + Превышение скорости 3 + Уровень разряда 1 + Уровень предупреждения о разряде батареи. + Уровень разряда 3 + Уровень разряда 2 + Предупреждение по току + Ток + Предупреждение о превышении заданного тока. + Предупреждение о температуре + Температура + Уровень срабатывания предупреждения о температуре. + скорость + ток + Нет данных для отображения графика + Автоматическое логирование + Автоматически начать запись логов при подключении колеса. + Выгрузка логов + Автоматически выгружать логи на Google Drive. + Местоположение + Добавить текущую позицию в лог. + Использование GPS + Использовать данные GPS для точного определения местоположения. При использовании GPS повышается энергопотребление телефона, а если параметр отключен, используются данные сотовой связи. + Выкл./Вкл./Строб + Мягкие/Средние/Жесткие + Режим предупреждения + Настроить передупреждения. + Калибровка + У меня Gotway MCM + Если у вас Gotway MCM, а скорость растояние и другие параметры отображаются некорректно, тогда попробуйте установить тут галочку. + Напряжение батареи + 67В/84В/100В + Отключить первое предупреждение. + Отключить второе предупреждение. + Включить предупреждения + м + Включение фонаря + Включает передний фонарь для освещения дороги. + Включает светодиодную подсветку + Включает бугущие огни светодиодов по бокам. + Отключить кнопку на ручке + Колесо больше не будет отключаться когда кнопка на ручке будет нажата. + Уровень звука + Регулировка уровня громкости встроенных колонок. + Уровень наклона педалей + Изменение угла тангажа (вниз/вверх) педалей. + К сожалению настройки для вашего колеса пока не доступны. + В + Вт + Включить автозагрузку? + Автоматическая загрузка будет потреблять ваши мобильные данные, за это может взиматься дополнительная плата вашим мобильным оператором + + + + \ No newline at end of file diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 97804884..c88c8444 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -6,9 +6,9 @@ - Disabled - On-board (KingSong) - via bluetooth audio + @string/disabled + @string/on_board_horn_ks + @string/bluetooth_audio_horn @@ -18,9 +18,9 @@ - Hard - Medium - Soft + @string/hard + @string/medium + @string/soft @@ -30,22 +30,22 @@ - On - Off - Auto + @string/on + @string/off + @string/auto - Off - On - Strobe + @string/off + @string/on + @string/strobe - Turn off level 1 alarm - Turn off level 2 alarm - Turn on alarm + @string/off_level_1_alarm + @string/off_level_2_alarm + @string/on_level_alarm @@ -61,8 +61,8 @@ - Off - On + @string/off + @string/on @@ -71,8 +71,8 @@ - Off - On + @string/off + @string/on diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 98d2c83f..8d2ce0a3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -62,12 +62,15 @@ Model Version Serial Number - %1$d%% • %2$d°C • %3$.1f km + %1$d%% • %2$d°C • %3$.1f km Watch Icon Logging Icon Connection Icon Connection lost at %1s + Enable Auto Upload? + Automatic uploading while not connected to WiFi will use your mobile data. This may result in charges from your network provider if you do not have a data plan. + No permission to write to external storage. Logging cancelled. External storage is unavailable. Logging cancelled. Log location was requested but no permission to location data was provided. No location data will be logged. @@ -118,7 +121,11 @@ gotway_84v gotway_voltage no_settings - + wheel_ks_alarm3 + wheel_ks_alarm2 + wheel_ks_alarm1 + + // LOG PREFERENCES auto_log @@ -133,13 +140,120 @@ // WATCH PREFERENCES horn_mode + garmin_connectiq_enable + Garmin ConnectIQ + Enable connectivity to Garmin ConnectIQ + + // Garmin ConnectIQ dialogs + The WheelLog App used with this application is not installed on your ConnectIQ device. Please install the widget and try again. + The ConnectIQ service is unavailable. - // TRIP PREFERENCES reset_top_speed reset_user_distance last_mac about + km/h + mph + km + mi + Horn Mode + Executed when the select button on the Pebble watch is pressed + Tiltback speed + Wheel speed limit + 1st Alert Speed + 2nd Alert Speed + 3rd Alert Speed + 4 beeps alarm + 3 beeps alarm + 2 beeps alarm + Pedals Mode + Leds mode + Strobe Mode + Light Mode + On/Off + On/Off/Auto + On + Off + Auto + Strobe + Disabled + Enabled + Hard + Medium + Soft + On-board (KingSong) + via bluetooth audio + Speed Settings + Log Settings + Alarm Settings + Watch Preferences + Wheel Settings + Reset top speed + Reset user distance + Edit MAC address + About WheelLog + Settings + Wheel Password ( InMotion only ) + A + Max Speed + The maximum speed shown on the outer dial + Use MPH + Show speed in miles rather than kilometers + Enable Alarms + Allow the phone to vibrate as a warning + Disable Phone Vibration + Phone will not vibrate but the alarm will be passed to a connected Pebble Watch + Speed Alarm 1 + Speed that triggers the alarm + Speed Alarm 2 + Speed Alarm 3 + Battery Percent + Battery percent that activates the alarm + Battery Percent + Battery Percent + Current Alarm + Current + Current that triggers the alarm + Temperature Alarm + Temperature + Temperature that triggers the alarm + speed + current + No data available + Auto Log + Start logging automatically when a wheel is connected + Auto Upload Logs + Automatically upload log files to Google Drive + Log location + Include location data within the logs + Use GPS for location + Use GPS for location rather than network provider. GPS is more accurate but may consume more battery power + Off/On/Strobe + Soft/Medium/Hard + Alarm settings + Alarm Mode + Calibration + My Wheel is a Gotway MCM + If your wheel is Gotway MCM, and it shows wrong speed, distance and others parameters, it should make them normal + Battery voltage + 67V/84V/100V + Turn off level 1 alarm + Turn off level 2 alarm + Turn on alarm + m + Switch on the light + Activate headlight + Switch on wheel illumination + Activate leds on the sides + Disable handle button + Wheel will not disable when you press the button on the handle + Speaker volume + Change built-in speaker volume + Pedals + Horizontal pedals adjustment + Wheel settings for Ninebot Z not available yet + V + W - diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 5ce3233c..26042a9e 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -4,47 +4,47 @@ + android:title="@string/reset_top_spped_title" /> + android:title="@string/reset_user_distance_title" /> + android:title="@string/edit_mac_addr_title" /> + android:title="@string/about_app_title" /> \ No newline at end of file diff --git a/app/src/main/res/xml/preferences_alarms.xml b/app/src/main/res/xml/preferences_alarms.xml index 6326d9a5..db9e202f 100644 --- a/app/src/main/res/xml/preferences_alarms.xml +++ b/app/src/main/res/xml/preferences_alarms.xml @@ -5,34 +5,34 @@ + android:title="@string/enable_alarms_title" + android:summary="@string/enable_alarms_description" /> + android:title="@string/disable_phone_vibrate_title" + android:summary="@string/disable_phone_vibration_description" /> + android:title="@string/speed_alarm1_phone_title"> + android:title="@string/speed_alarm2_phone_title"> + android:title="@string/speed_alarm3_phone_title"> + android:title="@string/current_alarm_title"> + android:title="@string/temperature_alarm_title"> + android:summary="@string/on_off_strobe" /> + android:summary="@string/alarm_settings_title" /> + android:summary="@string/soft_medium_hard" /> + android:title="@string/calibration_title"/> + android:title="@string/is_gotway_mcm_title" + android:summary="@string/is_gotway_mcm_description" /> + android:key="@string/gotway_voltage" + android:summary="@string/battary_voltage_description" + android:title="@string/battery_voltage_title" /> \ No newline at end of file diff --git a/app/src/main/res/xml/preferences_inmotion.xml b/app/src/main/res/xml/preferences_inmotion.xml index 107f6ceb..83b25450 100644 --- a/app/src/main/res/xml/preferences_inmotion.xml +++ b/app/src/main/res/xml/preferences_inmotion.xml @@ -5,35 +5,35 @@ + android:title="@string/on_headlight_title" + android:summary="@string/on_headlight_description" /> + android:title="@string/leds_settings_title" + android:summary="@string/leds_settings_description" /> + android:title="@string/disable_handle_button_title" + android:summary="@string/disable_handle_button_description" /> - - - + android:summary="@string/on_off_auto" /> + + android:summary="@string/on_off" /> + android:summary="@string/on_off" /> + - + android:summary="@string/soft_medium_hard" /> - + - + android:key="@string/wheel_ks_alarm3" + android:summary="@string/alarm3_description" + android:title="@string/alert3_title" + sample:msbp_dialogEnabled="true" + sample:msbp_interval="1" + sample:msbp_maxValue="50" + sample:msbp_measurementUnit="@string/kmh" + sample:msbp_minValue="0" /> + + + \ No newline at end of file diff --git a/app/src/main/res/xml/preferences_logs.xml b/app/src/main/res/xml/preferences_logs.xml index 71b448c8..b5f541ed 100644 --- a/app/src/main/res/xml/preferences_logs.xml +++ b/app/src/main/res/xml/preferences_logs.xml @@ -3,23 +3,23 @@ xmlns:android="http://schemas.android.com/apk/res/android"> + android:title="@string/auto_log_title" + android:summary="@string/auto_log_description" /> + android:title="@string/auto_upload_log_title" + android:summary="@string/auto_upload_log_description" /> + android:title="@string/log_location_title" + android:summary="@string/log_location_decription" /> + android:title="@string/use_gps_title" + android:summary="@string/use_gps_description" /> \ No newline at end of file diff --git a/app/src/main/res/xml/preferences_ninebot_z.xml b/app/src/main/res/xml/preferences_ninebot_z.xml index 33e4aec2..4d80ef14 100644 --- a/app/src/main/res/xml/preferences_ninebot_z.xml +++ b/app/src/main/res/xml/preferences_ninebot_z.xml @@ -6,6 +6,6 @@ + android:title="@string/ninebotz_settings_title"/> \ No newline at end of file diff --git a/app/src/main/res/xml/preferences_speed.xml b/app/src/main/res/xml/preferences_speed.xml index cd20e099..a5459c66 100644 --- a/app/src/main/res/xml/preferences_speed.xml +++ b/app/src/main/res/xml/preferences_speed.xml @@ -5,19 +5,19 @@ + android:title="@string/use_mph_title" + android:summary="@string/use_mph_description" /> \ No newline at end of file diff --git a/app/src/main/res/xml/preferences_watch.xml b/app/src/main/res/xml/preferences_watch.xml index d4a22a3e..de913d63 100644 --- a/app/src/main/res/xml/preferences_watch.xml +++ b/app/src/main/res/xml/preferences_watch.xml @@ -3,11 +3,15 @@ xmlns:android="http://schemas.android.com/apk/res/android"> - + android:key="@string/horn_mode" + android:summary="@string/horn_mode_description" + android:title="@string/horn_mode_title" /> + \ No newline at end of file diff --git a/build.gradle b/build.gradle index 8878386c..9e97ec76 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:3.1.4' + classpath 'com.android.tools.build:gradle:3.4.0' classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' // NOTE: Do not place your application dependencies here; they belong diff --git a/gradlew b/gradlew deleted file mode 100755 index 9d82f789..00000000 --- a/gradlew +++ /dev/null @@ -1,160 +0,0 @@ -#!/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 "$@" diff --git a/gradlew.bat b/gradlew.bat index 8a0b282a..e95643d6 100755 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,90 +1,84 @@ -@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 +@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 + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@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= + +@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 Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_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=%* + +: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