Simple web server provide image download, using org.apache.http.protocol.HttpService

Last post show a "Simple web server using org.apache.http.protocol.HttpService". In this post, I tried to provide image download, by visiting http://<ip address>:8080/image

But FAIL - As shown in the video, sometimes the download will fail. And once fail, the code will block and have to be re-start. Hope anybody can advise.


Modify MainActivity.java
package com.example.androidhttpservice;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.Enumeration;

import org.apache.http.HttpEntity;
import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.entity.ContentProducer;
import org.apache.http.entity.EntityTemplate;
import org.apache.http.entity.FileEntity;
import org.apache.http.impl.DefaultConnectionReuseStrategy;
import org.apache.http.impl.DefaultHttpResponseFactory;
import org.apache.http.impl.DefaultHttpServerConnection;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.BasicHttpProcessor;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.HttpRequestHandler;
import org.apache.http.protocol.HttpRequestHandlerRegistry;
import org.apache.http.protocol.HttpService;
import org.apache.http.protocol.ResponseConnControl;
import org.apache.http.protocol.ResponseContent;
import org.apache.http.protocol.ResponseDate;
import org.apache.http.protocol.ResponseServer;

import android.support.v7.app.ActionBarActivity;
import android.widget.TextView;
import android.os.Bundle;
import android.os.Environment;

/*
* Permission needed:
* "android.permission.INTERNET"
* "android.permission.READ_EXTERNAL_STORAGE"
*/

public class MainActivity extends ActionBarActivity {

HttpServiceThread httpServiceThread;

TextView infoIp;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

infoIp = (TextView) findViewById(R.id.infoip);
infoIp.setText(getIpAddress() + ":"
+ HttpServiceThread.HttpServerPORT + "\n");

httpServiceThread = new HttpServiceThread();
httpServiceThread.start();
}

@Override
protected void onDestroy() {
super.onDestroy();
httpServiceThread.stopServer();
}

private String getIpAddress() {
String ip = "";
try {
Enumeration<NetworkInterface> enumNetworkInterfaces = NetworkInterface
.getNetworkInterfaces();
while (enumNetworkInterfaces.hasMoreElements()) {
NetworkInterface networkInterface = enumNetworkInterfaces
.nextElement();
Enumeration<InetAddress> enumInetAddress = networkInterface
.getInetAddresses();
while (enumInetAddress.hasMoreElements()) {
InetAddress inetAddress = enumInetAddress.nextElement();

if (inetAddress.isSiteLocalAddress()) {
ip += "SiteLocalAddress: "
+ inetAddress.getHostAddress() + "\n";
}

}

}

} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
ip += "Something Wrong! " + e.toString() + "\n";
}

return ip;
}

private class HttpServiceThread extends Thread {

ServerSocket serverSocket;
Socket socket;
HttpService httpService;
BasicHttpContext basicHttpContext;
static final int HttpServerPORT = 8080;
boolean RUNNING = false;

HttpServiceThread() {
RUNNING = true;
startHttpService();
}

@Override
public void run() {

try {
serverSocket = new ServerSocket(HttpServerPORT);
serverSocket.setReuseAddress(true);

while (RUNNING) {
socket = serverSocket.accept();

DefaultHttpServerConnection httpServerConnection = new DefaultHttpServerConnection();
httpServerConnection.bind(socket, new BasicHttpParams());
httpService.handleRequest(httpServerConnection,
basicHttpContext);
httpServerConnection.shutdown();
}
serverSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (HttpException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

private synchronized void startHttpService() {
BasicHttpProcessor basicHttpProcessor = new BasicHttpProcessor();
basicHttpContext = new BasicHttpContext();

basicHttpProcessor.addInterceptor(new ResponseDate());
basicHttpProcessor.addInterceptor(new ResponseServer());
basicHttpProcessor.addInterceptor(new ResponseContent());
basicHttpProcessor.addInterceptor(new ResponseConnControl());

httpService = new HttpService(basicHttpProcessor,
new DefaultConnectionReuseStrategy(),
new DefaultHttpResponseFactory());

HttpRequestHandlerRegistry registry = new HttpRequestHandlerRegistry();
registry.register("/", new HomeCommandHandler());
registry.register("/image", new ImageCommandHandler());
httpService.setHandlerResolver(registry);
}

public synchronized void stopServer() {
RUNNING = false;
if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

class HomeCommandHandler implements HttpRequestHandler {

@Override
public void handle(HttpRequest request, HttpResponse response,
HttpContext httpContext) throws HttpException, IOException {

HttpEntity httpEntity = new EntityTemplate(
new ContentProducer() {

public void writeTo(final OutputStream outstream)
throws IOException {

OutputStreamWriter outputStreamWriter = new OutputStreamWriter(
outstream, "UTF-8");
String response = "<html><head></head><body><h1>Hello HttpService, from Android-er<h1></body></html>";

outputStreamWriter.write(response);
outputStreamWriter.flush();
}
});
response.setHeader("Content-Type", "text/html");
response.setEntity(httpEntity);
}

}

class ImageCommandHandler implements HttpRequestHandler {

@Override
public void handle(HttpRequest request, HttpResponse response,
HttpContext context) throws HttpException, IOException {

File file = new File(
Environment.getExternalStorageDirectory(),
"android-er_sketch.jpg");

FileEntity fileEntity = new FileEntity(file, "image/jpg");
response.setHeader("Content-Type", "application/force-download");
response.setHeader("Content-Disposition","attachment; filename=image.jpg");
response.setHeader("Content-Type", "image/jpg");
response.setEntity(fileEntity);
}

}

}

}

Layout file, activity_main.xml, refer to last post.

Permission of "android.permission.INTERNET" and "android.permission.READ_EXTERNAL_STORAGE" is needed in AndroidManifest.xml.

download filesDownload the files.

Simple web server using org.apache.http.protocol.HttpService

It is a example of simple web server, using org.apache.http.protocol.HttpService. org.apache.http.protocol.HttpServiceis a server side HTTP protocol handler based on the classic (blocking) I/O model.


MainActivity.java
package com.example.androidhttpservice;

import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.Enumeration;

import org.apache.http.HttpEntity;
import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.entity.ContentProducer;
import org.apache.http.entity.EntityTemplate;
import org.apache.http.impl.DefaultConnectionReuseStrategy;
import org.apache.http.impl.DefaultHttpResponseFactory;
import org.apache.http.impl.DefaultHttpServerConnection;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.BasicHttpProcessor;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.HttpRequestHandler;
import org.apache.http.protocol.HttpRequestHandlerRegistry;
import org.apache.http.protocol.HttpService;
import org.apache.http.protocol.ResponseConnControl;
import org.apache.http.protocol.ResponseContent;
import org.apache.http.protocol.ResponseDate;
import org.apache.http.protocol.ResponseServer;

import android.support.v7.app.ActionBarActivity;
import android.widget.TextView;
import android.os.Bundle;

/*
* Permission needed:
* "android.permission.INTERNET"
*/

public class MainActivity extends ActionBarActivity {

HttpServiceThread httpServiceThread;

TextView infoIp;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

infoIp = (TextView) findViewById(R.id.infoip);
infoIp.setText(getIpAddress() + ":"
+ HttpServiceThread.HttpServerPORT + "\n");

httpServiceThread = new HttpServiceThread();
httpServiceThread.start();
}

@Override
protected void onDestroy() {
super.onDestroy();
httpServiceThread.stopServer();
}

private String getIpAddress() {
String ip = "";
try {
Enumeration<NetworkInterface> enumNetworkInterfaces = NetworkInterface
.getNetworkInterfaces();
while (enumNetworkInterfaces.hasMoreElements()) {
NetworkInterface networkInterface = enumNetworkInterfaces
.nextElement();
Enumeration<InetAddress> enumInetAddress = networkInterface
.getInetAddresses();
while (enumInetAddress.hasMoreElements()) {
InetAddress inetAddress = enumInetAddress.nextElement();

if (inetAddress.isSiteLocalAddress()) {
ip += "SiteLocalAddress: "
+ inetAddress.getHostAddress() + "\n";
}

}

}

} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
ip += "Something Wrong! " + e.toString() + "\n";
}

return ip;
}

private class HttpServiceThread extends Thread {

ServerSocket serverSocket;
Socket socket;
HttpService httpService;
BasicHttpContext basicHttpContext;
static final int HttpServerPORT = 8080;
boolean RUNNING = false;

HttpServiceThread() {
RUNNING = true;
startHttpService();
}

@Override
public void run() {

try {
serverSocket = new ServerSocket(HttpServerPORT);
serverSocket.setReuseAddress(true);

while (RUNNING) {
socket = serverSocket.accept();
DefaultHttpServerConnection httpServerConnection = new DefaultHttpServerConnection();
httpServerConnection.bind(socket, new BasicHttpParams());
httpService.handleRequest(httpServerConnection,
basicHttpContext);
httpServerConnection.shutdown();
}
serverSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (HttpException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

private synchronized void startHttpService() {
BasicHttpProcessor basicHttpProcessor = new BasicHttpProcessor();
basicHttpContext = new BasicHttpContext();

basicHttpProcessor.addInterceptor(new ResponseDate());
basicHttpProcessor.addInterceptor(new ResponseServer());
basicHttpProcessor.addInterceptor(new ResponseContent());
basicHttpProcessor.addInterceptor(new ResponseConnControl());

httpService = new HttpService(basicHttpProcessor,
new DefaultConnectionReuseStrategy(),
new DefaultHttpResponseFactory());

HttpRequestHandlerRegistry registry = new HttpRequestHandlerRegistry();
registry.register("/", new HomeCommandHandler());
httpService.setHandlerResolver(registry);
}

public synchronized void stopServer() {
RUNNING = false;
if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

class HomeCommandHandler implements HttpRequestHandler {

@Override
public void handle(HttpRequest request, HttpResponse response,
HttpContext httpContext) throws HttpException, IOException {

HttpEntity httpEntity = new EntityTemplate(
new ContentProducer() {

public void writeTo(final OutputStream outstream)
throws IOException {

OutputStreamWriter outputStreamWriter = new OutputStreamWriter(
outstream, "UTF-8");
String response = "<html><head></head><body><h1>Hello HttpService, from Android-er<h1></body></html>";

outputStreamWriter.write(response);
outputStreamWriter.flush();
}
});
response.setHeader("Content-Type", "text/html");
response.setEntity(httpEntity);
}

}

}

}

activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.androidhttpservice.MainActivity" >

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:autoLink="web"
android:text="http://android-er.blogspot.com/"
android:textStyle="bold" />

<TextView
android:id="@+id/infoip"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

</LinearLayout>

download filesDownload the files.

FreeFlight 3 updated V3.2.14

FreeFlight 3, the official control app to pilot the Parrot Drones, updated V3.2.14.

What's New
Help menu shortcut
Major bug fixes
Academy:
Keep track of all your sessions and share your photos, videos and navigation data with other members of the Parrot Cloud.
Bebop:
New indicators in HUD: distance, speed, altitude
Rolling Spider :
Improve range
Decrease long distance lag
- Please note that the Rolling Spider firmware update should be done directly from our website : www.parrot.com/support/, updated firmware version 1.97.0 is available now.


How to show line number in Android Studio


To show line number in Android Studio:
File Menu > Settings > expand Editor > Appearance
Check the box of Show line numbers


Transfer image between Android devices, via Socket

The post "File transfer via Socket, between Android devices" show how to send text file between Android devices using Socket. In this example, we are going to send image file of "png" via Socket, with ObjectOutputStream in server side and ObjectInputStream in client side.


The png file is fixed "android-er_sketch_1000.png" at ExternalStorageDirectory in server, and received file in client will be save as "test.png" at ExternalStorageDirectory.

android-er_sketch_1000.png
Here I list the MainActivity of both server and client. For the layout files, refer to the example of "File transfer via Socket, between Android devices".

Server side MainActivity.java
package com.example.androidsocketfiletransferserver;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.Enumeration;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.os.Environment;
import android.widget.TextView;
import android.widget.Toast;

/*
* Permission needed:
* <uses-permission android:name="android.permission.INTERNET"/>
* <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
*/

public class MainActivity extends ActionBarActivity {

TextView infoIp, infoPort;

static final int SocketServerPORT = 8080;
ServerSocket serverSocket;

ServerSocketThread serverSocketThread;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
infoIp = (TextView) findViewById(R.id.infoip);
infoPort = (TextView) findViewById(R.id.infoport);

infoIp.setText(getIpAddress());

serverSocketThread = new ServerSocketThread();
serverSocketThread.start();
}

@Override
protected void onDestroy() {
super.onDestroy();

if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

private String getIpAddress() {
String ip = "";
try {
Enumeration<NetworkInterface> enumNetworkInterfaces = NetworkInterface
.getNetworkInterfaces();
while (enumNetworkInterfaces.hasMoreElements()) {
NetworkInterface networkInterface = enumNetworkInterfaces
.nextElement();
Enumeration<InetAddress> enumInetAddress = networkInterface
.getInetAddresses();
while (enumInetAddress.hasMoreElements()) {
InetAddress inetAddress = enumInetAddress.nextElement();

if (inetAddress.isSiteLocalAddress()) {
ip += "SiteLocalAddress: "
+ inetAddress.getHostAddress() + "\n";
}

}

}

} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
ip += "Something Wrong! " + e.toString() + "\n";
}

return ip;
}

public class ServerSocketThread extends Thread {

@Override
public void run() {
Socket socket = null;

try {
serverSocket = new ServerSocket(SocketServerPORT);
MainActivity.this.runOnUiThread(new Runnable() {

@Override
public void run() {
infoPort.setText("I'm waiting here: "
+ serverSocket.getLocalPort());
}});

while (true) {
socket = serverSocket.accept();
FileTxThread fileTxThread = new FileTxThread(socket);
fileTxThread.start();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

}

public class FileTxThread extends Thread {
Socket socket;

FileTxThread(Socket socket){
this.socket= socket;
}

@Override
public void run() {
File file = new File(
Environment.getExternalStorageDirectory(),
"android-er_sketch_1000.png");

byte[] bytes = new byte[(int) file.length()];
BufferedInputStream bis;
try {
bis = new BufferedInputStream(new FileInputStream(file));
bis.read(bytes, 0, bytes.length);

ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject(bytes);
oos.flush();

socket.close();

final String sentMsg = "File sent to: " + socket.getInetAddress();
MainActivity.this.runOnUiThread(new Runnable() {

@Override
public void run() {
Toast.makeText(MainActivity.this,
sentMsg,
Toast.LENGTH_LONG).show();
}});

} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}
}
}

download filesDownload the files in Server side.


Client side MainActivity.java
package com.example.androidsocketfiletransferclient;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.Socket;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import android.os.Bundle;
import android.os.Environment;

/*
* Permission needed:
* <uses-permission android:name="android.permission.INTERNET"/>
* <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
*/

public class MainActivity extends ActionBarActivity {

EditText editTextAddress;
Button buttonConnect;
TextView textPort;

static final int SocketServerPORT = 8080;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

editTextAddress = (EditText) findViewById(R.id.address);
textPort = (TextView) findViewById(R.id.port);
textPort.setText("port: " + SocketServerPORT);
buttonConnect = (Button) findViewById(R.id.connect);

buttonConnect.setOnClickListener(new OnClickListener(){

@Override
public void onClick(View v) {
ClientRxThread clientRxThread =
new ClientRxThread(
editTextAddress.getText().toString(),
SocketServerPORT);

clientRxThread.start();
}});
}

private class ClientRxThread extends Thread {
String dstAddress;
int dstPort;

ClientRxThread(String address, int port) {
dstAddress = address;
dstPort = port;
}

@Override
public void run() {
Socket socket = null;

try {
socket = new Socket(dstAddress, dstPort);

File file = new File(
Environment.getExternalStorageDirectory(),
"test.png");

ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
byte[] bytes;
FileOutputStream fos = null;
try {
bytes = (byte[])ois.readObject();
fos = new FileOutputStream(file);
fos.write(bytes);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if(fos!=null){
fos.close();
}

}

socket.close();

MainActivity.this.runOnUiThread(new Runnable() {

@Override
public void run() {
Toast.makeText(MainActivity.this,
"Finished",
Toast.LENGTH_LONG).show();
}});

} catch (IOException e) {

e.printStackTrace();

final String eMsg = "Something wrong: " + e.getMessage();
MainActivity.this.runOnUiThread(new Runnable() {

@Override
public void run() {
Toast.makeText(MainActivity.this,
eMsg,
Toast.LENGTH_LONG).show();
}});

} finally {
if(socket != null){
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}

}

download filesDownload the files in client side.


More example of Android Network programming
- Bi-directional communication between Client and Server, using ServerSocket, Socket, DataInputStream and DataOutputStream

How to fix "Found 2 versions of android-support-v4.jar in the dependency list"

Recently after updated SDK on Android-Eclipse, tried to import my old example, and have the following error reported:

Found 2 versions of android-support-v4.jar in the dependency list,
but not all the versions are identical (check is based on SHA-1 only at this time).
...

My solution is to delete the file android-support-v4.jar in libs folder of my project.

Install ADT (Android Developer Tools) on Eclipse

Android offers a custom plugin for the Eclipse IDE, called Android Development Tools (ADT). This plugin provides a powerful, integrated environment in which to develop Android apps. It extends the capabilities of Eclipse to let you quickly set up new Android projects, build an app UI, debug your app, and export signed (or unsigned) app packages (APKs) for distribution.

Note: Be aware that Android Studio is now the official IDE for Android, so you should migrate to Android Studio to receive all the latest IDE updates. 

You should install the ADT plugin only if you already have an Eclipse installation that you want to continue using.

~ referenec: http://developer.android.com/sdk/installing/installing-adt.html


Download Eclipse:
It's very straightforward, visit http://www.eclipse.org/downloads/, download Eclipse IDE for Java Developers (Eclipse 3.7.2 or greater), unpack the downloaded file, and move the unpacked folder to any location you want.


Install ADT (Android Developer Tools) on Eclipse:


  1. Start Eclipse, then select Help > Install New Software.
  2. Click Add, in the top-right corner.
  3. In the Add Repository dialog that appears, enter "ADT Plugin" for the Name and the following URL for the Location:
    https://dl-ssl.google.com/android/eclipse/
    Note: The Android Developer Tools update site requires a secure connection. Make sure the update site URL you enter starts with HTTPS.
  4. Click OK.
  5. In the Available Software dialog, select the checkbox next to Developer Tools and click Next.
  6. In the next window, you'll see a list of the tools to be downloaded. Click Next.
  7. Read and accept the license agreements, then click Finish.
    If you get a security warning saying that the authenticity or validity of the software can't be established, click OK.
  8. When the installation completes, restart Eclipse.
reference: http://developer.android.com/sdk/installing/installing-adt.html



IObit Driver Booster Pro v2.1.2 Key

IObit Driver Booster Pro
Driver Booster is an effective and easy-to-use driver updater, which analyzes outdated drivers automatically, and installs the right update for PCs with just ONE click. The newly adopted online database ensures drivers are always the latest. Moreover, it’s specially designed to tweak drivers for peak gaming performance. It’s the right driver update tool to protect PCs from hardware failures, conflicts, and system crashes.
Features
  • Expanded 20% driver database to cover more specialty devices
  •  Smarter driver scan for higher device-driver match accuracy
  •  Optimized online database for more effective scan
  •  Added driver list export feature
  •  Supported high-resolution screens including 4K for better user experience
  •  Improved skins for better user interface
  •  Added Georgian localization
  •  Fixed minor bugs
How To Activate ?

  1. Download & InstallI Obit Driver Booster Pro Trial (SKIP IF INSTALLED)
  2. Open IObit Driver Booster Pro
  3. Click “Activate”
  4. Copy the Key given below
  5. Paste it in key box
  6. Click “Activate”
  7. Done :)
ScreenShot



Serial Key
2EC72-368A4-5E4E9-D54A1

Official Whats App Web Realease Install Guide

Official Whats App Web Realease

Are you one of the 600 million people on WhatsApp? Do you grow tired of having to type all of your messages through your phone? Good news!
There’s now a desktop version. It’s a web app rather than a native client — and for now, at least, it seems to only play friendly with Google Chrome.
As you may have imagined, this allows you to use your computer to send and receive WhatsApp messages. But, true to this app’s very obvious “mobile first” mantra, the Web client is acting simply as an extension of your phone.
Installation
First, go to Whats App Web Home page in you chrome browser (WhatsApp says you should use Chrome. Other browsers may work, but to be 100% sure you’ll need to go with Google’s offering for now):
To log in on the desktop, you have to take a picture of a QR code through WhatsApp on your phone. This is necessary, presumably, because WhatsApp uses your phone number and SMS verifications rather than usernames/passwords. This currently works on Android, Windows Phone, and BlackBerry… but “due to Apple platform limitations” (WhatsApp’s words, there — we’re not sure what limitations they mean), iOS users are left out in the cold.
On the platforms where it works, however, it’s very slick.
Curiously, it seems as if it’s using your phone for more than just the initial login; note the orange warning in the screenshot below. If your phone dies, so does your WhatsApp web connection.



Note: Instructions for all mobile platforms are provided on the WhatsApp Web page. If you don’t have that option in the app on your mobile device yet, then either you’re not running the latest version or the company hasn’t enabled the new feature for your account. This seems to be a staged rollout of sorts, so if you’re in this situation a bit of patience will help.

Update Android Studio

To Update Android Studio, click Help on menu, Check for Update...


This video show how to update installed Android Studio 1.0.1 to 1.0.2.

Install Android Studio on Ubuntu Linux


To install Android Studio IDE 1.0.1 on Ubuntu, visit https://developer.android.com/sdk/index.html, download Android Studio for Linux.


Follow the steps in https://developer.android.com/sdk/installing/index.html?pkg=studio to set up Android Studio on Linux.
  1. Unpack the downloaded ZIP file into an appropriate location for your applications.
  2. To launch Android Studio, navigate to the android-studio/bin/ directory in a terminal and execute studio.sh.
    You may want to add android-studio/bin/ to your PATH environmental variable so that you can start Android Studio from any directory.
  3. Follow the setup wizard to install any necessary SDK tools.
about JAVA_HOME:
Before run Android Studio, you have to set JAVA_HOME on your system, point to JDK. Otherwise, will have error of "'tools.jar' seems to be not in Android Studio classpath. Please ensure JAVA_HOME points to JDK rather than JRE."


To setup JAVA_HOME on Linux, refer last post "Setup JAVA_HOME and path to JDK on Linux".

Next:
Refer next post up Update Android Studio.


Updated@2015-10-25:
Install Android Studio on 64-bit Ubuntu 15.10 with Ubuntu Make

Setup JAVA_HOME and path to JDK on Linux


Setup JAVA_HOME and path to JDK on Linux (Ubuntu in this example), edit the file .bashrc
$ nano .bashrc

Add the line:
export JAVA_HOME=<path to jdk>
export PATH=$JAVA_HOME/bin:$PATH

Where <path to jdk> is the path to the installed JDK.


Save it and exit.

To reload .bashrc without log-out and log-in, enter the command:
$ source ~/.bashrc


Wearable Fly Nixie Takes Flight on Stage at CES 2015


Fly Nixie Fly! The winner of the first ever Intel Make it Wearable
Challenge takes flight at CES 2015. More about Nixie: http://flynixie.com/

See more of Nixie at CES 2015: http://intel.ly/1xSmxiM

Learn more about Nixie in the Make it Wearable Challenge from Intel: http://intel.ly/17jn9p1


Win a BeagleBone Black from element14

Want to win a BeagleBone Black from element14? element14 are giving away BeagleBone Black boards every day from now until Feb 1 to new element14 members and the members who refer them. This means that your name will be entered again each time someone new lists you as a referral-- so tell all your friends and increase your odds of winning!

Visit http://www.element14.com/community/community/members/blog/2015/01/16/win-a-beaglebone-black-from-element14, register to enter.

Click "Enter to Win (Somebody Invited Me)" and BE SURE TO ENTER MY USERNAME "android-er" IN THE "INVITED BY" FIELD :)


Drag and Drop between ListView and GridView

Previous example show how to implement Drag-and-Drop between ListViews. As both ListView and Gridiew subclasses of AbsListView, it's easy to implement Drag-and-Drop between ListView and GridView.


Refactory LinearLayoutListView.java to LinearLayoutAbsListView.java, to implement our custom LinearLayout associate with AbsListView, for ListView or GridView.
package com.example.androidimageviewlist;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.AbsListView;
import android.widget.LinearLayout;

public class LinearLayoutAbsListView extends LinearLayout {

AbsListView absListView;

public LinearLayoutAbsListView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}

public LinearLayoutAbsListView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}

public LinearLayoutAbsListView(Context context, AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
// TODO Auto-generated constructor stub
}

public void setAbsListView(AbsListView alv){
absListView = alv;
}

}

Create /res/layout/gridrow.xml to define row layout for GridView.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >

<ImageView
android:id="@+id/gridrowImageView"
android:layout_gravity="center"
android:layout_width="48dp"
android:layout_height="48dp" />

</LinearLayout>

Modify /res/layout/activity_main.xml to include three <com.example.androidimageviewlist.LinearLayoutAbsListView>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="4dp"
tools:context="com.example.androidimageviewlist.MainActivity" >

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:autoLink="web"
android:text="http://android-er.blogspot.com/"
android:textStyle="bold" />

<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"
android:background="@android:color/background_dark"
android:orientation="horizontal" >

<com.example.androidimageviewlist.LinearLayoutAbsListView
android:id="@+id/pane1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_margin="4dp"
android:layout_weight="1"
android:background="@android:color/background_light"
android:orientation="vertical" >

<ListView
android:id="@+id/listview1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</com.example.androidimageviewlist.LinearLayoutAbsListView>

<com.example.androidimageviewlist.LinearLayoutAbsListView
android:id="@+id/pane2"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_margin="4dp"
android:layout_weight="1"
android:background="@android:color/background_light"
android:orientation="vertical" >

<ListView
android:id="@+id/listview2"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</com.example.androidimageviewlist.LinearLayoutAbsListView>

<com.example.androidimageviewlist.LinearLayoutAbsListView
android:id="@+id/pane3"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_margin="4dp"
android:layout_weight="1"
android:background="@android:color/background_light"
android:orientation="vertical" >

<GridView
android:id="@+id/gridview3"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="auto_fit"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:columnWidth="60dp"
android:stretchMode="columnWidth"
android:gravity="center" />
</com.example.androidimageviewlist.LinearLayoutAbsListView>
</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal" >

<TextView
android:id="@+id/prompt"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black"
android:gravity="bottom"
android:textColor="@android:color/white" />
</LinearLayout>

</LinearLayout>

MainActivity.java
package com.example.androidimageviewlist;

import java.util.ArrayList;
import java.util.List;

import android.support.v7.app.ActionBarActivity;
import android.text.method.ScrollingMovementMethod;
import android.app.Activity;
import android.content.ClipData;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.DragEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.DragShadowBuilder;
import android.view.View.OnDragListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends ActionBarActivity {

//items stored in ListView
public class Item {
Drawable ItemDrawable;
String ItemString;
Item(Drawable drawable, String t){
ItemDrawable = drawable;
ItemString = t;
}
}

//objects passed in Drag and Drop operation
class PassObject{
View view;
Item item;
List<Item> srcList;

PassObject(View v, Item i, List<Item> s){
view = v;
item = i;
srcList = s;
}
}

static class ViewHolder {
ImageView icon;
TextView text;
}

static class GridViewHolder {
ImageView icon;
}

public class ItemBaseAdapter extends BaseAdapter {

Context context;
List<Item> list;

ItemBaseAdapter(Context c, List<Item> l){
context = c;
list = l;
}

@Override
public int getCount() {
return list.size();
}

@Override
public Object getItem(int position) {
return list.get(position);
}

@Override
public long getItemId(int position) {
return position;
}

public List<Item> getList(){
return list;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
return null;
}

}


public class ItemListAdapter extends ItemBaseAdapter {

ItemListAdapter(Context c, List<Item> l) {
super(c, l);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = convertView;

// reuse views
if (rowView == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
rowView = inflater.inflate(R.layout.row, null);

ViewHolder viewHolder = new ViewHolder();
viewHolder.icon = (ImageView) rowView.findViewById(R.id.rowImageView);
viewHolder.text = (TextView) rowView.findViewById(R.id.rowTextView);
rowView.setTag(viewHolder);
}

ViewHolder holder = (ViewHolder) rowView.getTag();
holder.icon.setImageDrawable(list.get(position).ItemDrawable);
holder.text.setText(list.get(position).ItemString);

rowView.setOnDragListener(new ItemOnDragListener(list.get(position)));

return rowView;
}

}

public class ItemGridAdapter extends ItemBaseAdapter {

ItemGridAdapter(Context c, List<Item> l) {
super(c, l);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
View gridrowView = convertView;

// reuse views
if (gridrowView == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
gridrowView = inflater.inflate(R.layout.gridrow, null);

GridViewHolder gridviewHolder = new GridViewHolder();
gridviewHolder.icon = (ImageView) gridrowView.findViewById(R.id.gridrowImageView);
gridrowView.setTag(gridviewHolder);
}

GridViewHolder holder = (GridViewHolder) gridrowView.getTag();
holder.icon.setImageDrawable(list.get(position).ItemDrawable);

gridrowView.setOnDragListener(new ItemOnDragListener(list.get(position)));

return gridrowView;
}

}

List<Item> items1, items2, items3;
ListView listView1, listView2;
GridView gridView3;
ItemListAdapter myItemListAdapter1, myItemListAdapter2;
ItemGridAdapter myItemGridAdapter3;
LinearLayoutAbsListView area1, area2, area3;
TextView prompt;

//Used to resume original color in drop ended/exited
int resumeColor;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView1 = (ListView)findViewById(R.id.listview1);
listView2 = (ListView)findViewById(R.id.listview2);
gridView3 = (GridView)findViewById(R.id.gridview3);

area1 = (LinearLayoutAbsListView)findViewById(R.id.pane1);
area2 = (LinearLayoutAbsListView)findViewById(R.id.pane2);
area3 = (LinearLayoutAbsListView)findViewById(R.id.pane3);
area1.setOnDragListener(myOnDragListener);
area2.setOnDragListener(myOnDragListener);
area3.setOnDragListener(myOnDragListener);
area1.setAbsListView(listView1);
area2.setAbsListView(listView2);
area3.setAbsListView(gridView3);

initItems();
myItemListAdapter1 = new ItemListAdapter(this, items1);
myItemListAdapter2 = new ItemListAdapter(this, items2);
myItemGridAdapter3 = new ItemGridAdapter(this, items3);
listView1.setAdapter(myItemListAdapter1);
listView2.setAdapter(myItemListAdapter2);
gridView3.setAdapter(myItemGridAdapter3);

listView1.setOnItemClickListener(listOnItemClickListener);
listView2.setOnItemClickListener(listOnItemClickListener);
gridView3.setOnItemClickListener(listOnItemClickListener);

listView1.setOnItemLongClickListener(myOnItemLongClickListener);
listView2.setOnItemLongClickListener(myOnItemLongClickListener);
gridView3.setOnItemLongClickListener(myOnItemLongClickListener);

prompt = (TextView) findViewById(R.id.prompt);
// make TextView scrollable
prompt.setMovementMethod(new ScrollingMovementMethod());
//clear prompt area if LongClick
prompt.setOnLongClickListener(new OnLongClickListener(){

@Override
public boolean onLongClick(View v) {
prompt.setText("");
return true;
}});

resumeColor = getResources().getColor(android.R.color.background_light);

}

OnItemLongClickListener myOnItemLongClickListener = new OnItemLongClickListener(){

@Override
public boolean onItemLongClick(AdapterView<?> parent, View view,
int position, long id) {
Item selectedItem = (Item)(parent.getItemAtPosition(position));

ItemBaseAdapter associatedAdapter = (ItemBaseAdapter)(parent.getAdapter());
List<Item> associatedList = associatedAdapter.getList();

PassObject passObj = new PassObject(view, selectedItem, associatedList);

ClipData data = ClipData.newPlainText("", "");
DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
view.startDrag(data, shadowBuilder, passObj, 0);

return true;
}

};

OnDragListener myOnDragListener = new OnDragListener() {

@Override
public boolean onDrag(View v, DragEvent event) {
String area;
if(v == area1){
area = "area1";
}else if(v == area2){
area = "area2";
}else if(v == area3){
area = "area3";
}else{
area = "unknown";
}

switch (event.getAction()) {
case DragEvent.ACTION_DRAG_STARTED:
prompt.append("ACTION_DRAG_STARTED: " + area + "\n");
break;
case DragEvent.ACTION_DRAG_ENTERED:
prompt.append("ACTION_DRAG_ENTERED: " + area + "\n");
break;
case DragEvent.ACTION_DRAG_EXITED:
prompt.append("ACTION_DRAG_EXITED: " + area + "\n");
break;
case DragEvent.ACTION_DROP:
prompt.append("ACTION_DROP: " + area + "\n");

PassObject passObj = (PassObject)event.getLocalState();
View view = passObj.view;
Item passedItem = passObj.item;
List<Item> srcList = passObj.srcList;
AbsListView oldParent = (AbsListView)view.getParent();
ItemBaseAdapter srcAdapter = (ItemBaseAdapter)(oldParent.getAdapter());

LinearLayoutAbsListView newParent = (LinearLayoutAbsListView)v;
ItemBaseAdapter destAdapter = (ItemBaseAdapter)(newParent.absListView.getAdapter());
List<Item> destList = destAdapter.getList();

if(removeItemToList(srcList, passedItem)){
addItemToList(destList, passedItem);
}

srcAdapter.notifyDataSetChanged();
destAdapter.notifyDataSetChanged();

//smooth scroll to bottom
newParent.absListView.smoothScrollToPosition(destAdapter.getCount()-1);

break;
case DragEvent.ACTION_DRAG_ENDED:
prompt.append("ACTION_DRAG_ENDED: " + area + "\n");
default:
break;
}

return true;
}

};

class ItemOnDragListener implements OnDragListener{

Item me;

ItemOnDragListener(Item i){
me = i;
}

@Override
public boolean onDrag(View v, DragEvent event) {
switch (event.getAction()) {
case DragEvent.ACTION_DRAG_STARTED:
prompt.append("Item ACTION_DRAG_STARTED: " + "\n");
break;
case DragEvent.ACTION_DRAG_ENTERED:
prompt.append("Item ACTION_DRAG_ENTERED: " + "\n");
v.setBackgroundColor(0x30000000);
break;
case DragEvent.ACTION_DRAG_EXITED:
prompt.append("Item ACTION_DRAG_EXITED: " + "\n");
v.setBackgroundColor(resumeColor);
break;
case DragEvent.ACTION_DROP:
prompt.append("Item ACTION_DROP: " + "\n");

PassObject passObj = (PassObject)event.getLocalState();
View view = passObj.view;
Item passedItem = passObj.item;
List<Item> srcList = passObj.srcList;
AbsListView oldParent = (AbsListView)view.getParent();
ItemBaseAdapter srcAdapter = (ItemBaseAdapter)(oldParent.getAdapter());

AbsListView newParent = (AbsListView)v.getParent();
ItemBaseAdapter destAdapter = (ItemBaseAdapter)(newParent.getAdapter());
List<Item> destList = destAdapter.getList();

int removeLocation = srcList.indexOf(passedItem);
int insertLocation = destList.indexOf(me);
/*
* If drag and drop on the same list, same position,
* ignore
*/
if(srcList != destList || removeLocation != insertLocation){
if(removeItemToList(srcList, passedItem)){
destList.add(insertLocation, passedItem);
}

srcAdapter.notifyDataSetChanged();
destAdapter.notifyDataSetChanged();
}

v.setBackgroundColor(resumeColor);

break;
case DragEvent.ACTION_DRAG_ENDED:
prompt.append("Item ACTION_DRAG_ENDED: " + "\n");
v.setBackgroundColor(resumeColor);
default:
break;
}

return true;
}

}

OnItemClickListener listOnItemClickListener = new OnItemClickListener(){

@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
Toast.makeText(MainActivity.this,
((Item)(parent.getItemAtPosition(position))).ItemString,
Toast.LENGTH_SHORT).show();
}

};

private void initItems(){
items1 = new ArrayList<Item>();
items2 = new ArrayList<Item>();
items3 = new ArrayList<Item>();

TypedArray arrayDrawable = getResources().obtainTypedArray(R.array.resicon);
TypedArray arrayText = getResources().obtainTypedArray(R.array.restext);

for(int i=0; i<arrayDrawable.length(); i++){
Drawable d = arrayDrawable.getDrawable(i);
String s = arrayText.getString(i);
Item item = new Item(d, s);
items1.add(item);
}

arrayDrawable.recycle();
arrayText.recycle();
}

private boolean removeItemToList(List<Item> l, Item it){
boolean result = l.remove(it);
return result;
}

private boolean addItemToList(List<Item> l, Item it){
boolean result = l.add(it);
return result;
}

}

download filesDownload the files.

Lumia 435 & Lumia 532

Introducing the Lumia 435


Specifications

Lumia 435
 
Operating systemWindows Phone 8.1 with Lumia Denim
HERE location servicesGlobal HERE Maps and HERE Drive+Free HERE Transit available in the Store
Display4”WVGALCD 800×480 pixels screen
Battery1560mAh battery
Processor1.2 GHz dual-core Qualcomm Snapdragon 200 processor
Main camera2 MP FF, Lumia Camera
Front facing cameraVGA
Memory
1GB RAM, 8GB 
+ up to 30GB free OneDrive,
micro SD up to 128GB
Dimensions131.85g

 

Introducing the Lumia 532


Lumia-532-group


Specifications

Lumia 532
 
Operating systemWindows Phone 8.1 with Lumia Denim
HERE location servicesFree global HERE Maps and HERE Drive+Free HERE Transit available in the Store
Display4” WVGA LCD 800×480
Battery1560mAh battery
Processor1.2 GHz quad-core Qualcomm Snapdragon 200 processor
Main camera5 MP FF, Lumia Camera
Front facing cameraVGA
Memory1GB RAM, 8GB internal mass memory + up to 30GB free OneDrive, micro SD up to 128GB
Dimensions131.8g

Easter Egg on Android 5.0.2 Lollipop, Flappy Bird game



To find the Easter Egg on Android 5.0.2 Lollipop, a build-in Flappy Bird game:
  • Access the Setting
  • Repeatedly tap on Android version to open Lollipop page
  • Tap on Lollipop logo to change color
  • Long tap on Lollipop logo to start the Flappy Bird game.

Nexus 7 (2012 version) WiFi received Android Lollipop, 5.0.2

My Nexus 7 (1st gen, 2012 version) WiFi received Android Lollipop, 5.0.2, OTA update.



Drag and Drop items between ListView, with OnDragListener on ListView cells

In last two post "Drag and Drop items between ListView" and "Improved Drag and Drop items between ListView", it drag a ListView item, drop on a LinearLayout, then add the item to the associated ListView, always on bottom. Not drop on ListView actually.

In this exercise, another OnDragListener (ItemOnDragListener) implemented for rowView of ListView items, such that we can actually drop on ListView items, and insert in the previous position.


MainActivity.java
package com.example.androidimageviewlist;

import java.util.ArrayList;
import java.util.List;

import android.support.v7.app.ActionBarActivity;
import android.text.method.ScrollingMovementMethod;
import android.app.Activity;
import android.content.ClipData;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.DragEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.DragShadowBuilder;
import android.view.View.OnDragListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends ActionBarActivity {

//items stored in ListView
public class Item {
Drawable ItemDrawable;
String ItemString;
Item(Drawable drawable, String t){
ItemDrawable = drawable;
ItemString = t;
}
}

//objects passed in Drag and Drop operation
class PassObject{
View view;
Item item;
List<Item> srcList;

PassObject(View v, Item i, List<Item> s){
view = v;
item = i;
srcList = s;
}
}

static class ViewHolder {
ImageView icon;
TextView text;
}

public class ItemsListAdapter extends BaseAdapter {

private Context context;
private List<Item> list;

ItemsListAdapter(Context c, List<Item> l){
context = c;
list = l;
}

@Override
public int getCount() {
return list.size();
}

@Override
public Object getItem(int position) {
return list.get(position);
}

@Override
public long getItemId(int position) {
return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = convertView;

// reuse views
if (rowView == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
rowView = inflater.inflate(R.layout.row, null);

ViewHolder viewHolder = new ViewHolder();
viewHolder.icon = (ImageView) rowView.findViewById(R.id.rowImageView);
viewHolder.text = (TextView) rowView.findViewById(R.id.rowTextView);
rowView.setTag(viewHolder);
}

ViewHolder holder = (ViewHolder) rowView.getTag();
holder.icon.setImageDrawable(list.get(position).ItemDrawable);
holder.text.setText(list.get(position).ItemString);

rowView.setOnDragListener(new ItemOnDragListener(list.get(position)));

return rowView;
}

public List<Item> getList(){
return list;
}
}

List<Item> items1, items2, items3;
ListView listView1, listView2, listView3;
ItemsListAdapter myItemsListAdapter1, myItemsListAdapter2, myItemsListAdapter3;
LinearLayoutListView area1, area2, area3;
TextView prompt;

//Used to resume original color in drop ended/exited
int resumeColor;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView1 = (ListView)findViewById(R.id.listview1);
listView2 = (ListView)findViewById(R.id.listview2);
listView3 = (ListView)findViewById(R.id.listview3);

area1 = (LinearLayoutListView)findViewById(R.id.pane1);
area2 = (LinearLayoutListView)findViewById(R.id.pane2);
area3 = (LinearLayoutListView)findViewById(R.id.pane3);
area1.setOnDragListener(myOnDragListener);
area2.setOnDragListener(myOnDragListener);
area3.setOnDragListener(myOnDragListener);
area1.setListView(listView1);
area2.setListView(listView2);
area3.setListView(listView3);

initItems();
myItemsListAdapter1 = new ItemsListAdapter(this, items1);
myItemsListAdapter2 = new ItemsListAdapter(this, items2);
myItemsListAdapter3 = new ItemsListAdapter(this, items3);
listView1.setAdapter(myItemsListAdapter1);
listView2.setAdapter(myItemsListAdapter2);
listView3.setAdapter(myItemsListAdapter3);

/*
//Auto scroll to end of ListView
listView1.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
listView2.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
listView3.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
*/

listView1.setOnItemClickListener(listOnItemClickListener);
listView2.setOnItemClickListener(listOnItemClickListener);
listView3.setOnItemClickListener(listOnItemClickListener);

listView1.setOnItemLongClickListener(myOnItemLongClickListener);
listView2.setOnItemLongClickListener(myOnItemLongClickListener);
listView3.setOnItemLongClickListener(myOnItemLongClickListener);

prompt = (TextView) findViewById(R.id.prompt);
// make TextView scrollable
prompt.setMovementMethod(new ScrollingMovementMethod());
//clear prompt area if LongClick
prompt.setOnLongClickListener(new OnLongClickListener(){

@Override
public boolean onLongClick(View v) {
prompt.setText("");
return true;
}});

resumeColor = getResources().getColor(android.R.color.background_light);

}

OnItemLongClickListener myOnItemLongClickListener = new OnItemLongClickListener(){

@Override
public boolean onItemLongClick(AdapterView<?> parent, View view,
int position, long id) {
Item selectedItem = (Item)(parent.getItemAtPosition(position));

ItemsListAdapter associatedAdapter = (ItemsListAdapter)(parent.getAdapter());
List<Item> associatedList = associatedAdapter.getList();

PassObject passObj = new PassObject(view, selectedItem, associatedList);

ClipData data = ClipData.newPlainText("", "");
DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
view.startDrag(data, shadowBuilder, passObj, 0);

return true;
}

};

OnDragListener myOnDragListener = new OnDragListener() {

@Override
public boolean onDrag(View v, DragEvent event) {
String area;
if(v == area1){
area = "area1";
}else if(v == area2){
area = "area2";
}else if(v == area3){
area = "area3";
}else{
area = "unknown";
}

switch (event.getAction()) {
case DragEvent.ACTION_DRAG_STARTED:
prompt.append("ACTION_DRAG_STARTED: " + area + "\n");
break;
case DragEvent.ACTION_DRAG_ENTERED:
prompt.append("ACTION_DRAG_ENTERED: " + area + "\n");
break;
case DragEvent.ACTION_DRAG_EXITED:
prompt.append("ACTION_DRAG_EXITED: " + area + "\n");
break;
case DragEvent.ACTION_DROP:
prompt.append("ACTION_DROP: " + area + "\n");

PassObject passObj = (PassObject)event.getLocalState();
View view = passObj.view;
Item passedItem = passObj.item;
List<Item> srcList = passObj.srcList;
ListView oldParent = (ListView)view.getParent();
ItemsListAdapter srcAdapter = (ItemsListAdapter)(oldParent.getAdapter());

LinearLayoutListView newParent = (LinearLayoutListView)v;
ItemsListAdapter destAdapter = (ItemsListAdapter)(newParent.listView.getAdapter());
List<Item> destList = destAdapter.getList();

if(removeItemToList(srcList, passedItem)){
addItemToList(destList, passedItem);
}

srcAdapter.notifyDataSetChanged();
destAdapter.notifyDataSetChanged();

//smooth scroll to bottom
newParent.listView.smoothScrollToPosition(destAdapter.getCount()-1);

break;
case DragEvent.ACTION_DRAG_ENDED:
prompt.append("ACTION_DRAG_ENDED: " + area + "\n");
default:
break;
}

return true;
}

};

class ItemOnDragListener implements OnDragListener{

Item me;

ItemOnDragListener(Item i){
me = i;
}

@Override
public boolean onDrag(View v, DragEvent event) {
switch (event.getAction()) {
case DragEvent.ACTION_DRAG_STARTED:
prompt.append("Item ACTION_DRAG_STARTED: " + "\n");
break;
case DragEvent.ACTION_DRAG_ENTERED:
prompt.append("Item ACTION_DRAG_ENTERED: " + "\n");
v.setBackgroundColor(0x30000000);
break;
case DragEvent.ACTION_DRAG_EXITED:
prompt.append("Item ACTION_DRAG_EXITED: " + "\n");
v.setBackgroundColor(resumeColor);
break;
case DragEvent.ACTION_DROP:
prompt.append("Item ACTION_DROP: " + "\n");

PassObject passObj = (PassObject)event.getLocalState();
View view = passObj.view;
Item passedItem = passObj.item;
List<Item> srcList = passObj.srcList;
ListView oldParent = (ListView)view.getParent();
ItemsListAdapter srcAdapter = (ItemsListAdapter)(oldParent.getAdapter());

ListView newParent = (ListView)v.getParent();
ItemsListAdapter destAdapter = (ItemsListAdapter)(newParent.getAdapter());
List<Item> destList = destAdapter.getList();

int removeLocation = srcList.indexOf(passedItem);
int insertLocation = destList.indexOf(me);
/*
* If drag and drop on the same list, same position,
* ignore
*/
if(srcList != destList || removeLocation != insertLocation){
if(removeItemToList(srcList, passedItem)){
destList.add(insertLocation, passedItem);
}

srcAdapter.notifyDataSetChanged();
destAdapter.notifyDataSetChanged();
}

v.setBackgroundColor(resumeColor);

break;
case DragEvent.ACTION_DRAG_ENDED:
prompt.append("Item ACTION_DRAG_ENDED: " + "\n");
v.setBackgroundColor(resumeColor);
default:
break;
}

return true;
}

}

OnItemClickListener listOnItemClickListener = new OnItemClickListener(){

@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
Toast.makeText(MainActivity.this,
((Item)(parent.getItemAtPosition(position))).ItemString,
Toast.LENGTH_SHORT).show();
}

};

private void initItems(){
items1 = new ArrayList<Item>();
items2 = new ArrayList<Item>();
items3 = new ArrayList<Item>();

TypedArray arrayDrawable = getResources().obtainTypedArray(R.array.resicon);
TypedArray arrayText = getResources().obtainTypedArray(R.array.restext);

for(int i=0; i<arrayDrawable.length(); i++){
Drawable d = arrayDrawable.getDrawable(i);
String s = arrayText.getString(i);
Item item = new Item(d, s);
items1.add(item);
}

arrayDrawable.recycle();
arrayText.recycle();
}

private boolean removeItemToList(List<Item> l, Item it){
boolean result = l.remove(it);
return result;
}

private boolean addItemToList(List<Item> l, Item it){
boolean result = l.add(it);
return result;
}

}

LinearLayoutListView.java and the layout file, /res/layout/activity_main.xml, refer to last post.

/res/layout/row.xml and /res/values/arrays.xml, refer to previous post of "Custom ListView with ImageView".

To use Drag and Drop on your app, you have to modify AndroidManifest.xml to set android:minSdkVersion="11".



download filesDownload the files.

Next:
Drag and Drop between ListView and GridView