Java tutorial
/* * Catroid: An on-device visual programming system for Android devices * Copyright (C) 2010-2017 The Catrobat Team * (<http://developer.catrobat.org/credits>) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * An additional term exception under section 7 of the GNU Affero * General Public License, version 3, is available at * http://developer.catrobat.org/license_additional_term * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.catrobat.catroid.drone.jumpingsumo; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.ServiceConnection; import android.os.Handler; import android.os.IBinder; import android.support.annotation.NonNull; import android.support.v4.content.LocalBroadcastManager; import android.util.Log; import com.parrot.arsdk.ardiscovery.ARDiscoveryDeviceNetService; import com.parrot.arsdk.ardiscovery.ARDiscoveryDeviceService; import com.parrot.arsdk.ardiscovery.ARDiscoveryService; import com.parrot.arsdk.ardiscovery.receivers.ARDiscoveryServicesDevicesListUpdatedReceiver; import com.parrot.arsdk.ardiscovery.receivers.ARDiscoveryServicesDevicesListUpdatedReceiverDelegate; import com.parrot.arsdk.arutils.ARUtilsException; import com.parrot.arsdk.arutils.ARUtilsFtpConnection; import com.parrot.arsdk.arutils.ARUtilsManager; import java.util.ArrayList; import java.util.List; import static org.catrobat.catroid.CatroidApplication.getAppContext; public class JumpingSumoDiscoverer { private static final String TAG = JumpingSumoDiscoverer.class.getSimpleName(); public interface Listener { /** * Called when the list of seen drones is updated * Called in the main thread * @param dronesList list of ARDiscoveryDeviceService which represents all available drones * Content of this list respect the drone types given in startDiscovery */ void onDronesListUpdated(List<ARDiscoveryDeviceService> dronesList); } public interface ListenerPicture { /** * Called when the pic Count changes * Called in the main thread * @param pictureCount the count of Pictures */ void onPictureCount(int pictureCount); /** * Called before medias will be downloaded * Called in the main thread * @param matchingMedias the number of medias that will be downloaded */ void onMatchingMediasFound(int matchingMedias); /** * Called each time the progress of a download changes * Called in the main thread * @param mediaName the name of the media * @param progress the progress of its download (from 0 to 100) */ void onDownloadProgressed(String mediaName, int progress); /** * Called when a media download has ended * Called in the main thread * @param mediaName the name of the media */ void onDownloadComplete(String mediaName); } private final List<Listener> listeners; private final List<ListenerPicture> listenerPictures; private final Handler handler = new Handler(getAppContext().getMainLooper()); private final Context context; private ARDiscoveryService ardiscoveryService; private ServiceConnection ardiscoveryServiceConnection; private final ARDiscoveryServicesDevicesListUpdatedReceiver ardiscoveryServicesDevicesListUpdatedReceiver; private final List<ARDiscoveryDeviceService> matchingDrones; private SDCardModule sdcardModule; private ARUtilsManager ftplistModule; private ARUtilsManager ftpqueueManager; private static final int DEVICE_PORT = 21; private boolean startDiscoveryAfterConnection = true; public JumpingSumoDiscoverer(Context contextDrone) { context = contextDrone; listeners = new ArrayList<>(); matchingDrones = new ArrayList<>(); ardiscoveryServicesDevicesListUpdatedReceiver = new ARDiscoveryServicesDevicesListUpdatedReceiver( discoveryListener); listenerPictures = new ArrayList<>(); } /* * Add a listener * All callbacks of the interface Listener will be called within this function * Should be called in the main thread * @param listener an object that implements the {@link Listener} interface */ public void addListener(Listener listener) { listeners.add(listener); notifyServiceDiscovered(matchingDrones); } public void addListenerPicture(ListenerPicture listenerPicture) { listenerPictures.add(listenerPicture); } /** * remove a listener from the listener list * @param listener an object that implements the {@link Listener} interface */ public void removeListener(Listener listener) { listeners.remove(listener); } /** * Setup the drone discoverer * Should be called before starting discovering */ public void setup() { // registerReceivers LocalBroadcastManager localBroadcastMgr = LocalBroadcastManager.getInstance(context); localBroadcastMgr.registerReceiver(ardiscoveryServicesDevicesListUpdatedReceiver, new IntentFilter(ARDiscoveryService.kARDiscoveryServiceNotificationServicesDevicesListUpdated)); if (ardiscoveryServiceConnection == null) { ardiscoveryServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { ardiscoveryService = ((ARDiscoveryService.LocalBinder) service).getService(); if (startDiscoveryAfterConnection) { startDiscovering(); startDiscoveryAfterConnection = false; } } @Override public void onServiceDisconnected(ComponentName name) { ardiscoveryService = null; } }; } if (ardiscoveryService == null) { Intent i = new Intent(context, ARDiscoveryService.class); context.bindService(i, ardiscoveryServiceConnection, Context.BIND_AUTO_CREATE); } } /** * Cleanup the object * Should be called when the object is not used anymore */ public void cleanup() { stopDiscovering(); if (ardiscoveryService != null) { new Thread(new Runnable() { @Override public void run() { ardiscoveryService.stop(); context.unbindService(ardiscoveryServiceConnection); ardiscoveryService = null; } }).start(); } // unregister receivers LocalBroadcastManager localBroadcastMgr = LocalBroadcastManager.getInstance(context); localBroadcastMgr.unregisterReceiver(ardiscoveryServicesDevicesListUpdatedReceiver); } /** * Start discovering Parrot drones * For Wifi drones, the device should be on the drone's network * When drones will be discovered, you will be notified through {@link Listener#onDronesListUpdated(List)} */ public void startDiscovering() { if (ardiscoveryService != null) { discoveryListener.onServicesDevicesListUpdated(); ardiscoveryService.start(); startDiscoveryAfterConnection = false; } else { startDiscoveryAfterConnection = true; } } /** * Stop discovering Parrot drones */ public void stopDiscovering() { if (ardiscoveryService != null) { ardiscoveryService.stop(); } startDiscoveryAfterConnection = false; } private void notifyServiceDiscovered(List<ARDiscoveryDeviceService> dronesList) { List<Listener> listenersCpy = new ArrayList<>(listeners); for (Listener listener : listenersCpy) { listener.onDronesListUpdated(dronesList); } } private final ARDiscoveryServicesDevicesListUpdatedReceiverDelegate discoveryListener = new ARDiscoveryServicesDevicesListUpdatedReceiverDelegate() { @Override public void onServicesDevicesListUpdated() { if (ardiscoveryService != null) { matchingDrones.clear(); List<ARDiscoveryDeviceService> deviceList = ardiscoveryService.getDeviceServicesArray(); if (deviceList != null) { for (ARDiscoveryDeviceService service : deviceList) { matchingDrones.add(service); } } notifyServiceDiscovered(matchingDrones); } } }; public void getInfoDevice(@NonNull ARDiscoveryDeviceService deviceService) { try { ftplistModule = new ARUtilsManager(); ftpqueueManager = new ARUtilsManager(); String productIP = ((ARDiscoveryDeviceNetService) (deviceService.getDevice())).getIp(); ftplistModule.initWifiFtp(productIP, DEVICE_PORT, ARUtilsFtpConnection.FTP_ANONYMOUS, ""); ftpqueueManager.initWifiFtp(productIP, DEVICE_PORT, ARUtilsFtpConnection.FTP_ANONYMOUS, ""); sdcardModule = new SDCardModule(ftplistModule, ftpqueueManager); sdcardModule.addListener(sdcardModulelistener); notifyPictureCount(sdcardModule.getPictureCount()); } catch (ARUtilsException e) { Log.e(TAG, "Exception", e); } } public void download() { sdcardModule.getallFlightMedias(); } public void notifyPic() { notifyPictureCount(sdcardModule.getPictureCount()); } public void onDeleteFile(String mediaName) { sdcardModule.deleteLastReceivedPic(mediaName); notifyPictureCount(sdcardModule.getPictureCount()); } private void notifyPictureCount(int pictureCount) { List<ListenerPicture> listenersCpy = new ArrayList<>(listenerPictures); for (ListenerPicture listener : listenersCpy) { listener.onPictureCount(pictureCount); } } private void notifyMatchingMediasFound(int matchingMedias) { List<ListenerPicture> listenersCpy = new ArrayList<>(listenerPictures); for (ListenerPicture listener : listenersCpy) { listener.onMatchingMediasFound(matchingMedias); } } private void notifyDownloadProgressed(String mediaName, int progress) { List<ListenerPicture> listenersCpy = new ArrayList<>(listenerPictures); for (ListenerPicture listener : listenersCpy) { listener.onDownloadProgressed(mediaName, progress); } } private void notifyDownloadComplete(String mediaName) { List<ListenerPicture> listenersCpy = new ArrayList<>(listenerPictures); for (ListenerPicture listener : listenersCpy) { listener.onDownloadComplete(mediaName); } } private final SDCardModule.Listener sdcardModulelistener = new SDCardModule.Listener() { @Override public void onMatchingMediasFound(final int matchingMedias) { handler.post(new Runnable() { @Override public void run() { notifyMatchingMediasFound(matchingMedias); } }); } @Override public void onDownloadProgressed(final String mediaName, final int progress) { handler.post(new Runnable() { @Override public void run() { notifyDownloadProgressed(mediaName, progress); } }); } @Override public void onDownloadComplete(final String mediaName) { handler.post(new Runnable() { @Override public void run() { notifyDownloadComplete(mediaName); } }); onDeleteFile(mediaName); } }; }