├── .gitignore
├── .travis.yml
├── LICENSE
├── NOTICE
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── info
│ │ └── schnatterer
│ │ └── pmcaFilesystemServer
│ │ ├── BaseActivity.java
│ │ ├── FilesystemScanner.java
│ │ ├── HttpServer.java
│ │ ├── ListAdapter.java
│ │ ├── Logger.java
│ │ ├── MainActivity.java
│ │ ├── WifiActivity.java
│ │ ├── WifiDirectActivity.java
│ │ └── WifiSettingActivity.java
│ └── res
│ ├── layout
│ ├── list.xml
│ └── log.xml
│ ├── mipmap-hdpi
│ └── ic_launcher.png
│ ├── mipmap-mdpi
│ └── ic_launcher.png
│ ├── mipmap-xhdpi
│ └── ic_launcher.png
│ ├── mipmap-xxhdpi
│ └── ic_launcher.png
│ ├── mipmap-xxxhdpi
│ └── ic_launcher.png
│ ├── values
│ └── strings.xml
│ └── web_hi_res_512.png
├── build.gradle
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | /.gradle
2 | /.idea
3 | /build
4 | /local.properties
5 | /*.iml
6 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: android
2 |
3 | env:
4 | - BUILD_TOOLS_VERSION=28.0.3
5 |
6 | android:
7 | components:
8 | # Use the latest revision of Android SDK Tools
9 | - tools
10 | - platform-tools
11 |
12 | # When changing the following, change also in build.gradle!
13 | - build-tools-${BUILD_TOOLS_VERSION}
14 | - android-23
15 |
16 | - extra-android-m2repository
17 |
18 | before_install:
19 | # Avoid ./gradlew: Permission denied
20 | - chmod +x gradlew
21 |
22 | install:
23 | # Avoids "Failed to install the following Android SDK packages as some licences have not been accepted."
24 | - echo yes | sdkmanager "build-tools;${BUILD_TOOLS_VERSION}"
25 |
26 | cache:
27 | directories:
28 | - $HOME/.gradle/caches/
29 | - $HOME/.gradle/wrapper/
30 |
31 | script:
32 | # Use assembleRelease here to make sure the changes have not affected proguard
33 | - ./gradlew clean build connectedCheck assembleRelease --stacktrace
34 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2019 Johannes Schnatterer
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/NOTICE:
--------------------------------------------------------------------------------
1 | pmcaFilesystemServer
2 |
3 | Copyright 2019 Johannes Schnatterer.
4 | Published under The MIT License (MIT).
5 |
6 | This product reuses code of the following products.
7 |
8 | * https://github.com/ma1co/PMCADemo
9 | * https://github.com/LubikR/SynologyUploader
10 | * https://github.com/Bostwickenator/STGUploader
11 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | pmcaFilesystemServer
2 | ====
3 | [](https://travis-ci.org/schnatterer/pmcaFilesystemServer)
4 |
5 | Simple Android app for Sony Cameras ( PlayMemories Camera App Store) that provides the File System
6 | of the camera via HTTP.
7 |
8 | This app uses the [OpenMemories: Framework](https://github.com/ma1co/OpenMemories-Framework) and is
9 | greatly inspired by the following existing open source PMCA Apps
10 |
11 | * [ma1co/PMCADemo](https://github.com/ma1co/PMCADemo)
12 | * [LubikR/SynologyUploader](https://github.com/LubikR/SynologyUploader)
13 | * [Bostwickenator/STGUploader](https://github.com/Bostwickenator/STGUploader)
14 |
15 | # Pre-release of new UI
16 |
17 | The PR for the new user interface hase been dangling for years. Now there is a pre-release that can be installed via Sony-PMCA-RE or through adb. See [#4](https://github.com/schnatterer/pmcaFilesystemServer/pull/4).
18 |
19 |
20 |
21 | # Installation
22 |
23 | * Use [Sony-PMCA-RE](https://github.com/ma1co/Sony-PMCA-RE),
24 | * via [sony-pmca.appspot.com](https://sony-pmca.appspot.com/apps) or
25 | * through adb (using [tweak app](https://github.com/ma1co/OpenMemories-Tweak)).
26 |
27 | # Usage
28 |
29 | On Startup a WiFi Connection will be established. Once this succeeds a webserver is started
30 | and its URL is displayed. There you can download all data from the camera, like images and videos.
31 |
32 | This works around the constraint of certain Sony cameras where videos can not be downloaded via WiFi.
33 |
34 | ⚠ The Web Server exposes the whole file system without authentication to everyone on the same network
35 | as the camera. Make sure to run this in a private network, using WiFi direct or by using your
36 | Mobile's Hotspot.
37 |
38 | # Development
39 |
40 | ```bash
41 | adb tcpip 5555
42 | adb connect 192.168.178.53:5555
43 | ```
44 |
45 | See https://stackoverflow.com/a/3623727
46 |
47 | For creating a release, set git tag and then upload an *unsigned* APK to GitHub's release page.
48 | Signed APKs seem to be denied by Sony-PMCA-RE.
49 |
50 | The app writes a log file to the SD card: `/storage/sdcard0/pmcaFilesystemServer/LOG.TXT`.
51 |
52 | ## Icon
53 |
54 | Was generated with
55 | [AndroidAssetStudio](https://romannurik.github.io/AndroidAssetStudio/icons-launcher.html#foreground.type=text&foreground.text.text=HTTP%20FS&foreground.text.font=Allerta%20Stencil&foreground.space.trim=1&foreground.space.pad=0.1&foreColor=rgba(96%2C%20125%2C%20139%2C%200)&backColor=rgb(139%2C%20195%2C%2074)&crop=0&backgroundShape=square&effects=none&name=ic_launcher)
56 |
57 | ## Feature Ideas
58 |
59 | * QR Code: https://stackoverflow.com/a/8800974/
60 | * Basic Auth: https://github.com/NanoHttpd/nanohttpd/issues/496
61 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 | /*.iml
3 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | /* Cameras run older android systems, e.g.
5 | Sony α 6500:
6 | adb shell getprop ro.build.version.release
7 | 4.1.2
8 | adb shell getprop ro.build.version.sdk
9 | 16
10 | */
11 | compileSdkVersion 23
12 | buildToolsVersion '28.0.3'
13 |
14 | defaultConfig {
15 | applicationId "info.schnatterer.pmcaFilesystemServer"
16 | //noinspection MinSdkTooLow
17 | minSdkVersion 10
18 | //noinspection ExpiredTargetSdkVersion
19 | targetSdkVersion 23
20 | versionCode 2
21 | versionName "0.1.1-SNAPSHOT"
22 | }
23 | buildTypes {
24 | release {
25 | minifyEnabled false
26 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
27 | }
28 | }
29 | }
30 |
31 | dependencies {
32 | compile 'com.github.ma1co.OpenMemories-Framework:framework:f8df350'
33 | provided 'com.github.ma1co.OpenMemories-Framework:stubs:f8df350'
34 | compile 'org.nanohttpd:nanohttpd-webserver:2.3.1'
35 | }
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in C:\Users\Alex\AppData\Local\Android\sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 | # Needed to keep generic types and @Key annotations accessed via reflection
19 | -keepattributes Signature,RuntimeVisibleAnnotations,AnnotationDefault
20 |
21 | -keepclasseswithmembers class * {
22 | @com.google.api.client.util.Key ;
23 | }
24 |
25 | -keepclasseswithmembers class * {
26 | @com.google.api.client.util.Value ;
27 | }
28 |
29 | -keepnames class com.google.api.client.http.HttpTransport
30 |
31 | # Needed by google-http-client-android when linking against an older platform version
32 | -dontwarn com.google.api.client.extensions.android.**
33 |
34 | # Needed by google-api-client-android when linking against an older platform version
35 | -dontwarn com.google.api.client.googleapis.extensions.android.**
36 |
37 | # Do not obfuscate but allow shrinking of android-oauth-client
38 | -keepnames class com.wuman.android.auth.** { *; }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
27 |
28 |
31 |
32 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/app/src/main/java/info/schnatterer/pmcaFilesystemServer/BaseActivity.java:
--------------------------------------------------------------------------------
1 | package info.schnatterer.pmcaFilesystemServer;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.view.KeyEvent;
6 |
7 | import com.sony.scalar.sysutil.ScalarInput;
8 |
9 | public class BaseActivity extends Activity {
10 |
11 | @Override
12 | public boolean onKeyDown(int keyCode, KeyEvent event) {
13 | switch (event.getScanCode()) {
14 | case ScalarInput.ISV_KEY_DELETE:
15 | case ScalarInput.ISV_KEY_SK2:
16 | case ScalarInput.ISV_KEY_MENU:
17 | return onDeleteKeyUp();
18 | default:
19 | return super.onKeyDown(keyCode, event);
20 | }
21 | }
22 |
23 | protected boolean onDeleteKeyUp() {
24 | onBackPressed();
25 | return true;
26 | }
27 |
28 | protected void setAutoPowerOffMode(boolean enable) {
29 | String mode = enable ? "APO/NORMAL" : "APO/NO";// or "APO/SPECIAL" ?
30 | Intent intent = new Intent();
31 | intent.setAction("com.android.server.DAConnectionManagerService.apo");
32 | intent.putExtra("apo_info", mode);
33 | sendBroadcast(intent);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/src/main/java/info/schnatterer/pmcaFilesystemServer/FilesystemScanner.java:
--------------------------------------------------------------------------------
1 | package info.schnatterer.pmcaFilesystemServer;
2 |
3 | import android.os.Environment;
4 |
5 | import java.io.File;
6 | import java.util.ArrayList;
7 | import java.util.Iterator;
8 | import java.util.List;
9 |
10 | /*
11 | * Bases on https://github.com/Bostwickenator/STGUploader/blob/master/app/src/main/java/org/bostwickenator/googlephotos/FilesystemScanner.java
12 | * Commit b8ce40d
13 | */
14 | class FilesystemScanner {
15 |
16 | private static final String[] rawFormats = {".arw"};
17 | private static final String[] jpegFormats = {".jpg"};
18 | private static final String[] videoFormats = {".mts", ".mp4"};
19 |
20 | public static List getRawsOnExternalStorage() {
21 | return getFilteredFileList(Environment.getExternalStorageDirectory(), rawFormats);
22 | }
23 |
24 | public static List getJpegsOnExternalStorage() {
25 | return getFilteredFileList(Environment.getExternalStorageDirectory(), jpegFormats);
26 | }
27 |
28 | public static List getVideosOnExternalStorage() {
29 | return getFilteredFileList(Environment.getExternalStorageDirectory(), videoFormats);
30 | }
31 |
32 | private static List getFilteredFileList(File directory, String... extensions) {
33 | File[] subFiles = directory.listFiles();
34 | List filtered = new ArrayList<>();
35 | if (subFiles != null) {
36 | for (File f : subFiles) {
37 | String filename = f.getName().toLowerCase();
38 | if (f.isFile()) {
39 | for (String extension : extensions) {
40 | if (filename.endsWith(extension)) {
41 | filtered.add(f);
42 | break;
43 | }
44 | }
45 | } else if (f.isDirectory()) {
46 | filtered.addAll(getFilteredFileList(f, extensions));
47 | }
48 | }
49 | }
50 | return filtered;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/app/src/main/java/info/schnatterer/pmcaFilesystemServer/HttpServer.java:
--------------------------------------------------------------------------------
1 | package info.schnatterer.pmcaFilesystemServer;
2 |
3 | import com.github.ma1co.openmemories.framework.DeviceInfo;
4 |
5 | import java.io.File;
6 | import java.util.List;
7 |
8 | import fi.iki.elonen.SimpleWebServer;
9 |
10 | public class HttpServer extends SimpleWebServer {
11 | static final int PORT = 8080;
12 | static final String HOST = null; // bind to all interfaces by default
13 | static final String WWW_ROOT = "/";
14 | static final boolean QUIET = false;
15 |
16 | public HttpServer() {
17 | super(HOST, PORT, new File(WWW_ROOT).getAbsoluteFile(), QUIET);
18 | }
19 |
20 | @Override
21 | public Response serve(IHTTPSession session) {
22 |
23 | if (session.getUri().equals("/")) {
24 | return serveRoot();
25 | } else {
26 | return super.serve(session);
27 | }
28 | }
29 |
30 | private Response serveRoot() {
31 | String heading = getDeviceInfo().getBrand() + " - " + getDeviceInfo().getModel();
32 | StringBuilder response = new StringBuilder("" + heading
33 | + "" + "" + heading + "
");
36 |
37 | response.append("Videos
");
38 | createFileList(FilesystemScanner.getVideosOnExternalStorage(), response);
39 |
40 | response.append("JPEGs
");
41 | createFileList(FilesystemScanner.getJpegsOnExternalStorage(), response);
42 |
43 | response.append("RAW
");
44 | createFileList(FilesystemScanner.getRawsOnExternalStorage(), response);
45 |
46 | response.append("Log File
");
47 | createLinkToLogFile(response);
48 |
49 | response.append("File System
");
50 | response.append(listDirectory("/", new File("/"))
51 | .replaceFirst(".*", ""));
52 | return newFixedLengthResponse(Response.Status.OK, MIME_HTML, response.toString());
53 | }
54 |
55 | private void createLinkToLogFile(StringBuilder response) {
56 | response.append("");
60 | response.append(logFile.getName());
61 | response.append("");
62 | }
63 |
64 | private DeviceInfo getDeviceInfo() {
65 | return DeviceInfo.getInstance();
66 | }
67 |
68 | private void createFileList(List files, StringBuilder response) {
69 | response.append("");
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/app/src/main/java/info/schnatterer/pmcaFilesystemServer/ListAdapter.java:
--------------------------------------------------------------------------------
1 | package info.schnatterer.pmcaFilesystemServer;
2 |
3 | import android.content.Context;
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 | import android.widget.ArrayAdapter;
8 | import android.widget.TextView;
9 |
10 | public class ListAdapter extends ArrayAdapter {
11 | public static class ListItem {
12 | public String getText1() { return ""; }
13 | public String getText2() { return ""; }
14 | }
15 |
16 | public ListAdapter(Context context, T[] objects) {
17 | super(context, 0, objects);
18 | }
19 |
20 | @Override
21 | public View getView(int position, View convertView, ViewGroup parent) {
22 | LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
23 | if (convertView == null)
24 | convertView = inflater.inflate(android.R.layout.simple_list_item_2, parent, false);
25 | T item = getItem(position);
26 | ((TextView) convertView.findViewById(android.R.id.text1)).setText(item.getText1());
27 | ((TextView) convertView.findViewById(android.R.id.text2)).setText(item.getText2());
28 | return convertView;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/app/src/main/java/info/schnatterer/pmcaFilesystemServer/Logger.java:
--------------------------------------------------------------------------------
1 | package info.schnatterer.pmcaFilesystemServer;
2 |
3 | import android.os.Environment;
4 | import android.util.Log;
5 |
6 | import java.io.*;
7 | import java.text.SimpleDateFormat;
8 | import java.util.Date;
9 | import java.util.Locale;
10 |
11 | public class Logger {
12 |
13 | public static final String DATE_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSS";
14 |
15 | public static File getFile() {
16 | // e.g. /storage/sdcard0/pmcaFilesystemServer/LOG.TXT
17 | return new File(Environment.getExternalStorageDirectory(), "pmcaFilesystemServer/LOG.TXT");
18 | }
19 |
20 | protected static void log(String msg) {
21 | try {
22 | getFile().getParentFile().mkdirs();
23 | BufferedWriter writer = new BufferedWriter(new FileWriter(getFile(), true));
24 | SimpleDateFormat sdf = new SimpleDateFormat(DATE_PATTERN, Locale.US);
25 | writer.append(sdf.format(new Date()));
26 | writer.append(" ");
27 | writer.append(msg);
28 | writer.newLine();
29 | writer.close();
30 | } catch (IOException e) {
31 | Log.e("pmcaFilesystemServer", "Error writing log", e);
32 | }
33 | }
34 | protected static void log(String type, String msg) { log("[" + type + "] " + msg); }
35 |
36 | public static void info(String msg) { log("INFO", msg); }
37 | public static void error(String msg) { log("ERROR", msg); }
38 | }
39 |
--------------------------------------------------------------------------------
/app/src/main/java/info/schnatterer/pmcaFilesystemServer/MainActivity.java:
--------------------------------------------------------------------------------
1 | package info.schnatterer.pmcaFilesystemServer;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.view.View;
7 | import android.widget.AdapterView;
8 | import android.widget.ListView;
9 |
10 | import java.io.PrintWriter;
11 | import java.io.StringWriter;
12 |
13 | public class MainActivity extends BaseActivity implements AdapterView.OnItemClickListener {
14 | protected class ActivityListItem extends ListAdapter.ListItem {
15 | private int nameResource;
16 | private Class extends Activity> clazz;
17 |
18 | public ActivityListItem(int nameResource, Class extends Activity> clazz) {
19 | this.nameResource = nameResource;
20 | this.clazz = clazz;
21 | }
22 |
23 | @Override
24 | public String getText1() {
25 | return getResources().getString(nameResource);
26 | }
27 |
28 | public Class extends Activity> getActivityClass() {
29 | return clazz;
30 | }
31 | }
32 |
33 | protected ActivityListItem activities[] = {
34 | new ActivityListItem(R.string.title_activity_wifi, WifiActivity.class),
35 | new ActivityListItem(R.string.title_activity_wifi_direct, WifiDirectActivity.class),
36 | new ActivityListItem(R.string.title_activity_wifi_setting, WifiSettingActivity.class),
37 | };
38 |
39 | @Override
40 | protected void onCreate(Bundle savedInstanceState) {
41 | super.onCreate(savedInstanceState);
42 | setContentView(R.layout.list);
43 |
44 | Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
45 | @Override
46 | public void uncaughtException(Thread thread, Throwable throwable) {
47 | StringWriter sw = new StringWriter();
48 | sw.append(throwable.toString());
49 | sw.append("\n");
50 | throwable.printStackTrace(new PrintWriter(sw));
51 | Logger.error(sw.toString());
52 |
53 | System.exit(0);
54 | }
55 | });
56 |
57 | ListView listView = (ListView) findViewById(R.id.listView);
58 | listView.setAdapter(new ListAdapter(this, activities));
59 | listView.setOnItemClickListener(this);
60 | }
61 |
62 | @Override
63 | public void onItemClick(AdapterView> adapterView, View view, int position, long id) {
64 | ActivityListItem item = (ActivityListItem) adapterView.getItemAtPosition(position);
65 | startActivity(new Intent(this, item.getActivityClass()));
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/app/src/main/java/info/schnatterer/pmcaFilesystemServer/WifiActivity.java:
--------------------------------------------------------------------------------
1 | package info.schnatterer.pmcaFilesystemServer;
2 |
3 | import android.content.BroadcastReceiver;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.content.IntentFilter;
7 | import android.net.NetworkInfo;
8 | import android.net.wifi.SupplicantState;
9 | import android.net.wifi.WifiInfo;
10 | import android.net.wifi.WifiManager;
11 | import android.os.Bundle;
12 | import android.text.format.Formatter;
13 | import android.widget.TextView;
14 |
15 | import java.io.IOException;
16 |
17 | public class WifiActivity extends BaseActivity {
18 | private TextView textView;
19 | private WifiManager wifiManager;
20 | private BroadcastReceiver wifiStateReceiver;
21 | private BroadcastReceiver supplicantStateReceiver;
22 | private BroadcastReceiver networkStateReceiver;
23 | private HttpServer httpServer;
24 |
25 | @Override
26 | protected void onCreate(Bundle savedInstanceState) {
27 | super.onCreate(savedInstanceState);
28 | setContentView(R.layout.log);
29 |
30 | textView = (TextView) findViewById(R.id.logView);
31 |
32 | wifiManager = (WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE);
33 |
34 | wifiStateReceiver = new BroadcastReceiver() {
35 | @Override
36 | public void onReceive(Context context, Intent intent) {
37 | wifiStateChanged(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN));
38 | }
39 | };
40 |
41 | supplicantStateReceiver = new BroadcastReceiver() {
42 | @Override
43 | public void onReceive(Context context, Intent intent) {
44 | networkStateChanged(WifiInfo.getDetailedStateOf((SupplicantState) intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE)));
45 | }
46 | };
47 |
48 | networkStateReceiver = new BroadcastReceiver() {
49 | @Override
50 | public void onReceive(Context context, Intent intent) {
51 | networkStateChanged(((NetworkInfo) intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO)).getDetailedState());
52 | }
53 | };
54 |
55 | httpServer = new HttpServer();
56 | }
57 |
58 | @Override
59 | protected void onResume() {
60 | super.onResume();
61 | registerReceiver(wifiStateReceiver, new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION));
62 | registerReceiver(supplicantStateReceiver, new IntentFilter(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION));
63 | registerReceiver(networkStateReceiver, new IntentFilter(WifiManager.NETWORK_STATE_CHANGED_ACTION));
64 | wifiManager.setWifiEnabled(true);
65 | try {
66 | httpServer.start();
67 | } catch (IOException e) {
68 | Logger.error("Failed to start HTTP Server: " + e.getMessage());
69 | }
70 | setAutoPowerOffMode(false);
71 | }
72 |
73 | @Override
74 | protected void onPause() {
75 | super.onPause();
76 | unregisterReceiver(wifiStateReceiver);
77 | unregisterReceiver(supplicantStateReceiver);
78 | unregisterReceiver(networkStateReceiver);
79 | wifiManager.setWifiEnabled(false);
80 | httpServer.stop();
81 | setAutoPowerOffMode(true);
82 | }
83 |
84 | @Override
85 | protected void onDestroy() {
86 | super.onDestroy();
87 | }
88 |
89 | protected void wifiStateChanged(int state) {
90 | switch (state) {
91 | case WifiManager.WIFI_STATE_ENABLING:
92 | log("Enabling wifi");
93 | break;
94 | case WifiManager.WIFI_STATE_ENABLED:
95 | log("Wifi enabled");
96 | break;
97 | }
98 | }
99 |
100 | protected void networkStateChanged(NetworkInfo.DetailedState state) {
101 | String ssid = wifiManager.getConnectionInfo().getSSID();
102 | switch (state) {
103 | case CONNECTING:
104 | if (ssid != null)
105 | log(ssid + ": Connecting");
106 | break;
107 | case AUTHENTICATING:
108 | log(ssid + ": Authenticating");
109 | break;
110 | case OBTAINING_IPADDR:
111 | log(ssid + ": Obtaining IP");
112 | break;
113 | case CONNECTED:
114 | wifiConnected();
115 | break;
116 | case DISCONNECTED:
117 | log("Disconnected");
118 | break;
119 | case FAILED:
120 | log("Connection failed");
121 | break;
122 | }
123 | }
124 |
125 | protected void wifiConnected() {
126 | WifiInfo info = wifiManager.getConnectionInfo();
127 | String ssid = info.getSSID();
128 | String ip = Formatter.formatIpAddress(info.getIpAddress());
129 | log(ssid + ": Connected. Server URL: http://" + ip + ":" + HttpServer.PORT + "/");
130 | }
131 |
132 | protected void log(String msg) {
133 | textView.setText(msg);
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/app/src/main/java/info/schnatterer/pmcaFilesystemServer/WifiDirectActivity.java:
--------------------------------------------------------------------------------
1 | package info.schnatterer.pmcaFilesystemServer;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.content.BroadcastReceiver;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.content.IntentFilter;
8 | import android.net.wifi.WifiManager;
9 | import android.os.Bundle;
10 | import android.widget.TextView;
11 |
12 | import com.sony.wifi.direct.DirectConfiguration;
13 | import com.sony.wifi.direct.DirectManager;
14 |
15 | import java.io.IOException;
16 | import java.util.List;
17 |
18 | public class WifiDirectActivity extends BaseActivity {
19 | public static final String MY_IP_ADDRESS = "192.168.122.1";
20 |
21 | private TextView textView;
22 | private WifiManager wifiManager;
23 | private DirectManager wifiDirectManager;
24 | private BroadcastReceiver wifiStateReceiver;
25 | private BroadcastReceiver wifiDirectStateReceiver;
26 | private BroadcastReceiver groupCreateSuccessReceiver;
27 | private BroadcastReceiver groupCreateFailureReceiver;
28 | private BroadcastReceiver stationConnectedReceiver;
29 | private BroadcastReceiver stationDisconnectedReceiver;
30 | private HttpServer httpServer;
31 |
32 | @Override
33 | // This seems to be a sony-specific value
34 | @SuppressLint("WrongConstant")
35 | protected void onCreate(Bundle savedInstanceState) {
36 | super.onCreate(savedInstanceState);
37 | setContentView(R.layout.log);
38 |
39 | textView = (TextView) findViewById(R.id.logView);
40 |
41 | wifiManager = (WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE);
42 | wifiDirectManager = (DirectManager) getApplicationContext().getSystemService(DirectManager.WIFI_DIRECT_SERVICE);
43 |
44 | wifiStateReceiver = new BroadcastReceiver() {
45 | @Override
46 | public void onReceive(Context context, Intent intent) {
47 | wifiStateChanged(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN));
48 | }
49 | };
50 |
51 | wifiDirectStateReceiver = new BroadcastReceiver() {
52 | @Override
53 | public void onReceive(Context context, Intent intent) {
54 | wifiDirectStateChanged(intent.getIntExtra(DirectManager.EXTRA_DIRECT_STATE, DirectManager.DIRECT_STATE_UNKNOWN));
55 | }
56 | };
57 |
58 | groupCreateSuccessReceiver = new BroadcastReceiver() {
59 | @Override
60 | public void onReceive(Context context, Intent intent) {
61 | groupCreated((DirectConfiguration) intent.getParcelableExtra(DirectManager.EXTRA_DIRECT_CONFIG));
62 | }
63 | };
64 |
65 | groupCreateFailureReceiver = new BroadcastReceiver() {
66 | @Override
67 | public void onReceive(Context context, Intent intent) {
68 | groupCreateFailed();
69 | }
70 | };
71 |
72 | stationConnectedReceiver = new BroadcastReceiver() {
73 | @Override
74 | public void onReceive(Context context, Intent intent) {
75 | stationConnected(intent.getStringExtra(DirectManager.EXTRA_STA_ADDR));
76 | }
77 | };
78 |
79 | stationDisconnectedReceiver = new BroadcastReceiver() {
80 | @Override
81 | public void onReceive(Context context, Intent intent) {
82 | stationDisconnected(intent.getStringExtra(DirectManager.EXTRA_STA_ADDR));
83 | }
84 | };
85 |
86 | httpServer = new HttpServer();
87 | }
88 |
89 | @Override
90 | protected void onResume() {
91 | super.onResume();
92 | registerReceiver(wifiStateReceiver, new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION));
93 | registerReceiver(wifiDirectStateReceiver, new IntentFilter(DirectManager.DIRECT_STATE_CHANGED_ACTION));
94 | registerReceiver(groupCreateSuccessReceiver, new IntentFilter(DirectManager.GROUP_CREATE_SUCCESS_ACTION));
95 | registerReceiver(groupCreateFailureReceiver, new IntentFilter(DirectManager.GROUP_CREATE_FAILURE_ACTION));
96 | registerReceiver(stationConnectedReceiver, new IntentFilter(DirectManager.STA_CONNECTED_ACTION));
97 | registerReceiver(stationDisconnectedReceiver, new IntentFilter(DirectManager.STA_DISCONNECTED_ACTION));
98 | wifiManager.setWifiEnabled(true);
99 | wifiDirectManager.setDirectEnabled(true);
100 | try {
101 | httpServer.start();
102 | } catch (IOException e) {
103 | Logger.error("Failed to start HTTP Server: " + e.getMessage());
104 | }
105 | setAutoPowerOffMode(false);
106 | }
107 |
108 | @Override
109 | protected void onPause() {
110 | super.onPause();
111 | unregisterReceiver(wifiStateReceiver);
112 | unregisterReceiver(wifiDirectStateReceiver);
113 | unregisterReceiver(groupCreateSuccessReceiver);
114 | unregisterReceiver(groupCreateFailureReceiver);
115 | unregisterReceiver(stationConnectedReceiver);
116 | unregisterReceiver(stationDisconnectedReceiver);
117 | wifiDirectManager.setDirectEnabled(false);
118 | wifiManager.setWifiEnabled(false);
119 | httpServer.stop();
120 | setAutoPowerOffMode(true);
121 | }
122 |
123 | protected void wifiStateChanged(int state) {
124 | switch (state) {
125 | case WifiManager.WIFI_STATE_ENABLING:
126 | log("Enabling wifi");
127 | break;
128 | case WifiManager.WIFI_STATE_ENABLED:
129 | log("Wifi enabled");
130 | break;
131 | }
132 | }
133 |
134 | protected void wifiDirectStateChanged(int state) {
135 | switch (state) {
136 | case DirectManager.DIRECT_STATE_ENABLING:
137 | log("Enabling wifi direct");
138 | break;
139 | case DirectManager.DIRECT_STATE_ENABLED:
140 | wifiDirectEnabled();
141 | break;
142 | }
143 | }
144 |
145 | protected void wifiDirectEnabled() {
146 | log("Wifi direct enabled");
147 | List configurations = wifiDirectManager.getConfigurations();
148 | if (configurations.isEmpty()) {
149 | log("Error: No configurations found");
150 | } else {
151 | log("Creating Group");
152 | wifiDirectManager.startGo(configurations.get(configurations.size() - 1).getNetworkId());
153 | }
154 | }
155 |
156 | protected void groupCreated(DirectConfiguration configuration) {
157 | log("Group created");
158 | log("SSID: " + configuration.getSsid());
159 | log("Key: " + configuration.getPreSharedKey());
160 | log("Server URL: http://" + MY_IP_ADDRESS + ":" + HttpServer.PORT + "/");
161 | }
162 |
163 | protected void groupCreateFailed() {
164 | log("Group create failed");
165 | }
166 |
167 | protected void stationConnected(String address) {
168 | log("Station connected: " + address);
169 | }
170 |
171 | protected void stationDisconnected(String address) {
172 | log("Station disconnected: " + address);
173 | }
174 |
175 | protected void log(String msg) {
176 | textView.append(msg + "\n");
177 | }
178 | }
179 |
--------------------------------------------------------------------------------
/app/src/main/java/info/schnatterer/pmcaFilesystemServer/WifiSettingActivity.java:
--------------------------------------------------------------------------------
1 | package info.schnatterer.pmcaFilesystemServer;
2 |
3 | import android.content.Intent;
4 | import android.net.wifi.WifiManager;
5 | import android.os.Bundle;
6 |
7 | public class WifiSettingActivity extends BaseActivity {
8 | private WifiManager wifiManager;
9 |
10 | @Override
11 | protected void onCreate(Bundle savedInstanceState) {
12 | super.onCreate(savedInstanceState);
13 |
14 | wifiManager = (WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE);
15 | wifiManager.setWifiEnabled(true);
16 | }
17 |
18 | @Override
19 | protected void onResume() {
20 | super.onResume();
21 | startActivityForResult(new Intent("com.sony.scalar.app.wifisettings.WifiSettings"), 0);
22 | }
23 |
24 | @Override
25 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
26 | super.onActivityResult(requestCode, resultCode, data);
27 | finish();
28 | }
29 |
30 | @Override
31 | protected void onDestroy() {
32 | super.onDestroy();
33 | wifiManager.setWifiEnabled(false);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/log.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/schnatterer/pmcaFilesystemServer/0b9169bcb24067af0e0b790bdea3f322a6dc5dae/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/schnatterer/pmcaFilesystemServer/0b9169bcb24067af0e0b790bdea3f322a6dc5dae/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/schnatterer/pmcaFilesystemServer/0b9169bcb24067af0e0b790bdea3f322a6dc5dae/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/schnatterer/pmcaFilesystemServer/0b9169bcb24067af0e0b790bdea3f322a6dc5dae/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/schnatterer/pmcaFilesystemServer/0b9169bcb24067af0e0b790bdea3f322a6dc5dae/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | FileSystemServer
3 | Start Server via Wifi
4 | Wifi Settings
5 | Start Server via Wifi direct
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/web_hi_res_512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/schnatterer/pmcaFilesystemServer/0b9169bcb24067af0e0b790bdea3f322a6dc5dae/app/src/main/res/web_hi_res_512.png
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | google()
6 | jcenter()
7 | }
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:3.3.2'
10 |
11 | // NOTE: Do not place your application dependencies here; they belong
12 | // in the individual module build.gradle files
13 | }
14 | }
15 |
16 | allprojects {
17 | repositories {
18 | google()
19 | jcenter()
20 | maven { url "https://jitpack.io" }
21 | }
22 | }
23 |
24 | task clean(type: Delete) {
25 | delete rootProject.buildDir
26 | }
27 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/schnatterer/pmcaFilesystemServer/0b9169bcb24067af0e0b790bdea3f322a6dc5dae/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Sun Feb 24 18:17:43 CET 2019
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------