diff --git a/app/build.gradle b/app/build.gradle index 26972b1b1c57afe947f732dab56e559410f988d7..8cdca884b73ea95676bf135580218fa023dfeeae 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -72,13 +72,43 @@ android { exclude 'META-INF/rxjava.properties' exclude 'META-INF/dji-sdk-lib_aar.kotlin_module' exclude 'dji/thirdparty/okhttp3/internal/publicsuffix/publicsuffixes.gz' + doNotStrip "*/*/libdjivideo.so" + doNotStrip "*/*/libSDKRelativeJNI.so" + doNotStrip "*/*/libFlyForbid.so" + doNotStrip "*/*/libduml_vision_bokeh.so" + doNotStrip "*/*/libyuv2.so" + doNotStrip "*/*/libGroudStation.so" + doNotStrip "*/*/libFRCorkscrew.so" + doNotStrip "*/*/libUpgradeVerify.so" + doNotStrip "*/*/libFR.so" + doNotStrip "*/*/libDJIFlySafeCore.so" + doNotStrip "*/*/libdjifs_jni.so" + doNotStrip "*/*/libsfjni.so" + doNotStrip "*/*/libDJICommonJNI.so" + doNotStrip "*/*/libDJICSDKCommon.so" + doNotStrip "*/*/libDJIUpgradeCore.so" + doNotStrip "*/*/libDJIUpgradeJNI.so" + doNotStrip "*/*/libDJIWaypointV2Core.so" + doNotStrip "*/*/libAMapSDK_MAP_v6_9_2.so" + doNotStrip "*/*/libDJIMOP.so" + doNotStrip "*/*/libDJISDKLOGJNI.so" + exclude 'META-INF/rxjava.properties' + exclude 'assets/location_map_gps_locked.png' + exclude 'assets/location_map_gps_3d.png' } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } } dependencies { implementation files('libs/jsoup-1.9.2.jar') implementation 'com.android.support:appcompat-v7' implementation 'androidx.constraintlayout:constraintlayout:2.0.4' implementation ('com.dji:dji-sdk:4.14.1') - implementation ('com.dji:dji-sdk-provided:4.14.1') + compileOnly ('com.dji:dji-sdk-provided:4.14.1') + // GroundSdk dependencies + implementation 'com.parrot.drone.groundsdk:groundsdk:1.7.1' + runtimeOnly 'com.parrot.drone.groundsdk:arsdkengine:1.7.1' } \ No newline at end of file diff --git a/app/src/main/java/fieldscience/cs/earlham/edu/fieldday/DJIFlightActivity.java b/app/src/main/java/fieldscience/cs/earlham/edu/fieldday/DJIFlightActivity.java index ec2eea5dcafeaf0205b62303b1559e30c2e67098..b4e5c4a0dd37c1f5816629c78515bb0e3e142ec3 100644 --- a/app/src/main/java/fieldscience/cs/earlham/edu/fieldday/DJIFlightActivity.java +++ b/app/src/main/java/fieldscience/cs/earlham/edu/fieldday/DJIFlightActivity.java @@ -1,32 +1,231 @@ package fieldscience.cs.earlham.edu.fieldday; -import android.content.Context; -import android.content.DialogInterface; +import android.Manifest; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.os.AsyncTask; +import android.os.Build; import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.util.Log; import android.view.View; +import android.widget.Toast; +import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; +import com.secneo.sdk.Helper; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + +import dji.common.error.DJIError; +import dji.common.error.DJISDKError; +import dji.sdk.base.BaseProduct; +import dji.sdk.sdkmanager.DJISDKInitEvent; +import dji.sdk.sdkmanager.DJISDKManager; +import dji.sdk.base.BaseComponent; + + public class DJIFlightActivity extends AppCompatActivity { - private Context context; + + private static final String TAG = DJIFlightActivity.class.getName(); + public static final String FLAG_CONNECTION_CHANGE = "dji_sdk_connection_change"; + private static BaseProduct mProduct; + private Handler mHandler; + + private static final String[] REQUIRED_PERMISSION_LIST = new String[]{ + Manifest.permission.VIBRATE, + Manifest.permission.INTERNET, + Manifest.permission.ACCESS_WIFI_STATE, + Manifest.permission.WAKE_LOCK, + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_NETWORK_STATE, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CHANGE_WIFI_STATE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.BLUETOOTH, + Manifest.permission.BLUETOOTH_ADMIN, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.READ_PHONE_STATE, + }; + private List<String> missingPermission = new ArrayList<>(); + private AtomicBoolean isRegistrationInProgress = new AtomicBoolean(false); + private static final int REQUEST_PERMISSION_CODE = 12345; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - //setContentView(R.layout.activity_uav); - context = this; - - AlertDialog.Builder alert = new AlertDialog.Builder(DJIFlightActivity.this) - .setTitle("UAV Support Coming Soon") - .setMessage("We are developing support for UAV flights in Field Day now. Check back soon!") - .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - } - }); - AlertDialog dialog = alert.create(); - dialog.show(); + + // When the compile and target version is higher than 22, please request the following permission at runtime to ensure the SDK works well. + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + checkAndRequestPermissions(); + } + + setContentView(R.layout.activity_uav); + + //Initialize DJI SDK Manager + mHandler = new Handler(Looper.getMainLooper()); + showToast("creating..."); + + } + + /** + * Checks if there is any missing permissions, and + * requests runtime permission if needed. + */ + private void checkAndRequestPermissions() { + // Check for permissions + for (String eachPermission : REQUIRED_PERMISSION_LIST) { + if (ContextCompat.checkSelfPermission(this, eachPermission) != PackageManager.PERMISSION_GRANTED) { + missingPermission.add(eachPermission); + } + } + // Request for missing permissions + if (missingPermission.isEmpty()) { + startSDKRegistration(); + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + showToast("Need to grant the permissions!"); + ActivityCompat.requestPermissions(this, + missingPermission.toArray(new String[missingPermission.size()]), + REQUEST_PERMISSION_CODE); + } + + } + + /** + * Result of runtime permission request + */ + @Override + public void onRequestPermissionsResult(int requestCode, + @NonNull String[] permissions, + @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + // Check for granted permission and remove from missing list + if (requestCode == REQUEST_PERMISSION_CODE) { + for (int i = grantResults.length - 1; i >= 0; i--) { + if (grantResults[i] == PackageManager.PERMISSION_GRANTED) { + missingPermission.remove(permissions[i]); + } + } + } + // If there is enough permission, we will start the registration + if (missingPermission.isEmpty()) { + startSDKRegistration(); + } else { + showToast("Missing permissions!!!"); + } + } + + private void startSDKRegistration() { + showToast("starting registration..."); + if (isRegistrationInProgress.compareAndSet(false, true)) { + AsyncTask.execute(new Runnable() { + @Override + public void run() { + showToast("registering, pls wait..."); + + DJISDKManager.getInstance().registerApp(DJIFlightActivity.this.getApplicationContext(), new DJISDKManager.SDKManagerCallback() { + @Override + public void onRegister(DJIError djiError) { + if (djiError == DJISDKError.REGISTRATION_SUCCESS) { + showToast("Register Success"); + DJISDKManager.getInstance().startConnectionToProduct(); + } else { + showToast("Register sdk fails, please check the bundle id and network connection!"); + } + Log.v(TAG, djiError.getDescription()); + } + + @Override + public void onProductDisconnect() { + Log.d(TAG, "onProductDisconnect"); + showToast("Product Disconnected"); + notifyStatusChange(); + + } + @Override + public void onProductConnect(BaseProduct baseProduct) { + Log.d(TAG, String.format("onProductConnect newProduct:%s", baseProduct)); + showToast("Product Connected"); + notifyStatusChange(); + + } + + @Override + public void onProductChanged(BaseProduct baseProduct) { + + } + + @Override + public void onComponentChange(BaseProduct.ComponentKey componentKey, BaseComponent oldComponent, + BaseComponent newComponent) { + + if (newComponent != null) { + newComponent.setComponentListener(new BaseComponent.ComponentListener() { + + @Override + public void onConnectivityChange(boolean isConnected) { + Log.d(TAG, "onComponentConnectivityChanged: " + isConnected); + notifyStatusChange(); + } + }); + } + Log.d(TAG, + String.format("onComponentChange key:%s, oldComponent:%s, newComponent:%s", + componentKey, + oldComponent, + newComponent)); + + } + + @Override + public void onInitProcess(DJISDKInitEvent djisdkInitEvent, int i) { + + } + + @Override + public void onDatabaseDownloadProgress(long l, long l1) { + + } + + }); + } + }); + } + } + + private void notifyStatusChange() { + mHandler.removeCallbacks(updateRunnable); + mHandler.postDelayed(updateRunnable, 500); + } + + private Runnable updateRunnable = new Runnable() { + + @Override + public void run() { + Intent intent = new Intent(FLAG_CONNECTION_CHANGE); + sendBroadcast(intent); + } + }; + + private void showToast(final String toastMsg) { + + Handler handler = new Handler(Looper.getMainLooper()); + handler.post(new Runnable() { + @Override + public void run() { + Toast.makeText(getApplicationContext(), toastMsg, Toast.LENGTH_LONG).show(); + } + }); + } + } diff --git a/app/src/main/java/fieldscience/cs/earlham/edu/fieldday/ParrotFlightActivity.java b/app/src/main/java/fieldscience/cs/earlham/edu/fieldday/ParrotFlightActivity.java index 90e7502f40136cf9a3e7e397fb51b2aba6b77a84..6feae6dfde07520d6c1930b7e969ae5711b4f7de 100644 --- a/app/src/main/java/fieldscience/cs/earlham/edu/fieldday/ParrotFlightActivity.java +++ b/app/src/main/java/fieldscience/cs/earlham/edu/fieldday/ParrotFlightActivity.java @@ -8,7 +8,11 @@ import android.os.Bundle; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; +import com.parrot.drone.groundsdk.GroundSdk; +import com.parrot.drone.groundsdk.ManagedGroundSdk; + public class ParrotFlightActivity extends AppCompatActivity { + private GroundSdk groundSdk; private Context context; @Override @@ -17,14 +21,7 @@ public class ParrotFlightActivity extends AppCompatActivity { //setContentView(R.layout.activity_uav); context = this; - AlertDialog.Builder alert = new AlertDialog.Builder(ParrotFlightActivity.this) - .setTitle("UAV Support Coming Soon") - .setMessage("We are developing support for UAV flights in Field Day now. Check back soon!") - .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - } - }); - AlertDialog dialog = alert.create(); - dialog.show(); + groundSdk = ManagedGroundSdk.obtainSession(this); + } }