Language - Android Java: Difference between revisions

From Phidgets Support
No edit summary
 
(3 intermediate revisions by 2 users not shown)
Line 1: Line 1:
<metadesc>Communicate over USB with sensors, controllers and relays with Phidgets! Our Android Java API supports Android using Javac, NetBeans or Eclipse.</metadesc>
#REDIRECT [[Language_-_Java_Android_Studio_Android]]
[[Category:Language]]
__TOC__
 
== Quick Downloads ==
 
=== Documentation ===
 
*{{Phidget22API}} (Select Java from drop-down menu)
 
=== Example Code ===
 
*{{SampleCodeOS|Android|Android Java Examples}}
 
=== Libraries===
*[{{SERVER}}/downloads/phidget22/libraries/android/phidget22-android.zip Android Java Library Download]
{{AllQuickDownloads}}
 
== Getting Started with Android Java ==
 
If you are new to writing code for Phidgets, we recommend starting by running, then modifying existing examples. This will allow you to:
{{ExampleCodeReasons}}
 
== Android Studio ==
 
=== Use Our Examples ===
 
In order to run the examples in Android Studio, all you need to do is download the the relevant example project for your device from:
 
*{{SampleCodeOS|Android|Android Java Examples}}
 
Next, open Android Studio on your development machine. Import the project using File->New->Import Project
 
[[Image:android_studio_import.png|link= | center]]
 
Navigate to your project in the resulting dialog box and click 'OK'
 
[[Image:android_studio_import_dialog.png|link= | center]]
 
Once the project has been imported, you can simply click the 'Run' button, and the example will compile and run on your chosen device.
 
[[Image:android_studio_run.png|link= | center]]
 
You may be prompted to select the Deployment Target. In this case, select your Android device and click OK.
 
[[Image:android_deployment_target.png|link=|center]]
 
Once the app is running on your device, if a Phidget corresponding to the example is attached either directly via USB, or to a computer running the Phidget Network Service on the same local network as the Android device, then device information and settings should appear on the screen.
 
In this case, we've run the "Hello World" example, so a list of available Phidgets is displayed.
 
[[Image:android_screenshot.png|link= | center]]
 
When you are ready, the next step is configuring your project and writing your own code!
 
=== Important Note ===
The examples provided are designed to be incredibly simplistic in order to highlight the base requirements to run Phidgets on Android. To this end, we opted to open and close the Phidgets in the onCreate and onDestroy handlers of the main activity respectively. This is likely a bad idea for implementing apps for any practical use, as the activity is prone to being destroyed and re-created for a wide variety of reasons, from closing the app, to rotating the screen. In order to ensure your Phidget remains attached through these events, we recommend running your Phidgets in a secondary service.
 
Check the [[#Common Problems, Solutions and Workarounds|Common Problems]] section for more information.
<!--
An example of how to do this can be seen in the Background Service example, available from the {{SampleCodeOS|Android|Android Java Examples}} page.
-->
 
=== Creating a New Project ===
When you are building a project from scratch, or adding Phidget functionality to an existing project, you'll need to configure your development environment to properly link the Phidget Java libraries for Android Java.
 
To start, create a new project in Android Studio:
 
[[Image:New_Android_Studio_Project.png|link=|center]]
 
Once you have a new project, be sure to switch the side bar to Project view.
 
[[Image:Android_Studio_Project_View.png|link=|center]]
 
Next, download the Phidget22 [{{SERVER}}/downloads/phidget22/libraries/any/Phidget22AndroidJava.zip Android Java libraries], extract the contents, and open the resulting folder.
 
[[Image:Android_Java_Folder.png|link=|center]]
 
Copy the .jar files into the '''app/libs/''' folder of your project. If you are only going to use network Phidgets in your app, then you don't need to copy Phidget22usb.jar into your project.
 
Right click the jar files you just copied and select "Add As Library".
 
[[Image:Add_As_Library.png|link=|center]]
 
Create a directory called '''jnilibs''' under '''app/src/main'''
 
[[Image:Android_Create_jnilibs.png|link=|center]]
 
Copy the remaining folders from the Phidget22 library (containing versions of libphidget22java.so) into the directory you just created.
 
[[Image:jnilib_files.png|link=|center]]
 
To allow the use of the network and/or USB connections, the following lines must be added to your AndroidManifest.xml file:
 
<syntaxhighlight lang="xml">
<!-- Required for network access -->
<uses-permission android:name="android.permission.INTERNET" />
 
<!-- Required for USB access -->
<uses-feature android:name="android.hardware.usb.host" />
</syntaxhighlight>
 
Finally, to import the Phidget22 library into your code, add the following line to the rest of your imports:
 
<syntaxhighlight lang="java">
import com.phidget22.*;
</syntaxhighlight>
 
The project now has access to Phidgets. Next, view the [[#Write Code | write your own code]] section located below.
 
==Write Code==
{{WriteCode_Intro|Android Java}}
 
==== Step One: Initialize and Open ====
You will need to declare your Phidget object in your code. For example, we can declare a digital input object like this:
 
<syntaxhighlight lang="java">
DigitalInput device;
</syntaxhighlight>
 
Next, we need to initialize the method(s) that the Android device can communicate with the Phidget. This is done either by enabling Network Server Discovery, and/or allowing direct USB connections as follows:
 
<syntaxhighlight lang='java'>
//Enable server discovery to list remote Phidgets
this.getSystemService(Context.NSD_SERVICE);
Net.enableServerDiscovery(ServerType.DEVICE_REMOTE);
 
//Allow direct USB connection of Phidgets
com.phidget22.usb.Manager.Initialize(this);
</syntaxhighlight>
 
To support remote (network) Phidgets on Android API versions earlier than API version 16, or to connect to Phidget Network Servers with passwords, you will need to add the specific server to your program:
 
<syntaxhighlight lang='java'>
//Add a specific network server to communicate with Phidgets remotely
Net.addServer("ServerName", "192.168.1.105", 5661, "password", 0);
</syntaxhighlight>
 
After the connection methods are established, the Phidget object needs to be initialized and opened:
<syntaxhighlight lang=java>
device = new DigitalInput();
device.open();
</syntaxhighlight>
 
Although we are not including it on this page, you should include error handling for all Phidget functions. Here is an example of the previous code with error handling:
<syntaxhighlight lang=java>
try{
    device = new DigitalInput();
    device.open();
}catch (PhidgetException e) {
    e.printStackTrace();
}
</syntaxhighlight>
==== Step Two: Wait for Attachment (plugging in) of the Phidget ====
Simply calling open does not guarantee you can use the Phidget immediately. To use a Phidget, it must be plugged in (attached). We can handle this by using event driven programming and tracking the attach events. Alternatively, we can modify our code so we wait for an attachment:
<syntaxhighlight lang="java">
ch = new DigitalInput();
ch.open(5000); //wait for attach for 5 seconds, if not time out
</syntaxhighlight>
 
Waiting for attachment will block indefinitely until a connection is made, or until the timeout value is exceeded.
 
To use events, we have to modify our code:
<syntaxhighlight lang='java'>
ch = new DigitalInput();
device.addAttachListener(new AttachListener() {
    public void onAttach(final AttachEvent attachEvent) {
        AttachEventHandler handler = new AttachEventHandler(device);
        synchronized(handler)
        {
            runOnUiThread(handler);
            try {
                handler.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
});
ch.open();
</syntaxhighlight>
 
Next, we have to declare the function that will be called when an attach event is fired - in this case the function '''AttachEventHandler''' will be called.
<syntaxhighlight lang="java">
class AttachEventHandler implements Runnable {
    Phidget device;
 
    public AttachEventHandler(Phidget device) {
        this.device = device;
    }
 
    public void run() {
        TextView attachedTxt = (TextView) findViewById(R.id.attachedTxt);
        attachedTxt.setText("Attached");
 
        //notify that we're done
        synchronized(this)
        {
    this.notify();
        }
    }
}
</syntaxhighlight>
==== Step Three: Do Things with the Phidget ====
We recommend the use of event driven programming when working with Phidgets. In a similar way to handling an attach event as described above, we can also add an event handler for a state change event:
<syntaxhighlight lang="java">
ch = new DigitalInput();
device.addStateChangeListener(new DigitalInputStateChangeListener() {
public void onStateChange(DigitalInputStateChangeEvent stateChangeEvent) {
        DigitalInputStateChangeEventHandler handler =
            new DigitalInputStateChangeEventHandler(device, stateChangeEvent);
runOnUiThread(handler);
    }
});
ch.open();
</syntaxhighlight>
 
This code will connect a function and an event. In this case, the '''DigitalInputStateChangeEventHandler''' function will be called when there has been a change to the devices input. Next, we need to create the '''DigitalInputStateChangeEventHandler''' function:
<syntaxhighlight lang="java">
class DigitalInputStateChangeEventHandler implements Runnable {
    Phidget device;
    DigitalInputStateChangeEvent stateChangeEvent;
 
    public DigitalInputStateChangeEventHandler(Phidget device,
      DigitalInputStateChangeEvent stateChangeEvent)
    {
        this.device = device;
        this.stateChangeEvent = stateChangeEvent;
    }
 
    public void run() {
        CheckBox stateBox = (CheckBox) findViewById(R.id.stateBox);
        stateBox.setChecked(stateChangeEvent.getState());
    }
}
</syntaxhighlight>
 
If events do not suit your needs, you can also poll the device directly for data using code like this:
<syntaxhighlight lang="java">
boolean state = ch.getState();
</syntaxhighlight>
==== Step Four: Close and Delete ====
At the end of your program, be sure to close your device.
<syntaxhighlight lang="java">
ch.close()
</syntaxhighlight>
 
Once the device is closed, to completely clean up after using Phidgets, you must uninitialize the USB connection as follows:
 
<syntaxhighlight lang="java">
//Disable USB connection to Phidgets
com.phidget22.usb.Manager.Uninitialize();
</syntaxhighlight>
 
== Further Reading ==
 
[[Phidget Programming Basics]] - Here you can find the basic concepts to help you get started with making your own programs that use Phidgets.
 
[[Data Interval/Change Trigger]] - Learn about these two properties that control how much data comes in from your sensors.
 
[[Using Multiple Phidgets]] - It can be difficult to figure out how to use more than one Phidget in your program. This page will guide you through the steps.
 
[[Polling vs. Events]] - Your program can gather data in either a polling-driven or event-driven manner. Learn the difference to determine which is best for your application.
 
[[Logging, Exceptions, and Errors]] - Learn about all the tools you can use to debug your program.
 
[[Phidget Network Server]] - Phidgets can be controlled and communicated with over your network- either wirelessly or over ethernet.
 
== Common Problems, Solutions and Workarounds ==
 
===Issue: <span style="color:DarkRed">My Phidget detached when I rotated my phone</span>===
 
You are likely using one of our examples, or handling the opening and closing of Phidgets in a similar way. In either case, chances are you are opening and closing Phidgets in your main activity. This is not recommended for practical applications, as the entire activity can be destroyed and re-created many times through its lifecycle due to configuration changes such as rotating the screen. This is a reality of the Android operating system, and must be addressed in whatever way best suits your application.
 
A good option to keep your Phidgets connected would be to implement a [https://developer.android.com/guide/components/services.html#CreatingStartedService Started Service] or a [https://developer.android.com/guide/components/services.html#Foreground Foreground Service], depending on your application, and open your Phidgets there.
<!--
You can use the Phidgets Background Service example as a simple reference to get started.
-->

Latest revision as of 20:10, 4 July 2019