|
|
package com.waveshare.epaperesp32loader;
|
|
|
|
|
|
import android.graphics.Bitmap;
|
|
|
import android.graphics.Color;
|
|
|
import android.os.Bundle;
|
|
|
import android.os.Handler;
|
|
|
import android.support.v7.app.AppCompatActivity;
|
|
|
import android.util.Log;
|
|
|
import android.view.View;
|
|
|
import android.view.Window;
|
|
|
import android.widget.TextView;
|
|
|
|
|
|
import com.waveshare.epaperesp32loader.communication.BluetoothHelper;
|
|
|
import com.waveshare.epaperesp32loader.image_processing.EPaperDisplay;
|
|
|
|
|
|
/**
|
|
|
* <h1>Upload activity</h1>
|
|
|
* The activity shows the progress of image uploading into display
|
|
|
* of the selected bluetooth device.
|
|
|
*
|
|
|
* @author Waveshare team
|
|
|
* @version 1.0
|
|
|
* @since 8/20/2018
|
|
|
*/
|
|
|
|
|
|
public class UploadActivity extends AppCompatActivity
|
|
|
{
|
|
|
private TextView textView;
|
|
|
private SocketHandler handler;
|
|
|
|
|
|
@Override
|
|
|
protected void onCreate(Bundle savedInstanceState)
|
|
|
{
|
|
|
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
|
|
|
super.onCreate(savedInstanceState);
|
|
|
setContentView(R.layout.upload_activity);
|
|
|
getSupportActionBar().setTitle(R.string.dlg_send);
|
|
|
|
|
|
// View
|
|
|
//--------------------------------------
|
|
|
textView = findViewById(R.id.upload_text);
|
|
|
textView.setText("Uploading: 0%");
|
|
|
|
|
|
// Bluetooth helper and its handler
|
|
|
//--------------------------------------
|
|
|
BluetoothHelper.initialize(AppStartActivity.btDevice, handler = new SocketHandler());
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
protected void onResume()
|
|
|
{
|
|
|
super.onResume();
|
|
|
|
|
|
// Bluetooth socket connection
|
|
|
//--------------------------------------
|
|
|
if (!BluetoothHelper.connect() || !handler.init(AppStartActivity.indTableImage))
|
|
|
{
|
|
|
setResult(RESULT_CANCELED);
|
|
|
finish();
|
|
|
}
|
|
|
else textView.setText("Uploading 0 %");
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
protected void onPause()
|
|
|
{
|
|
|
BluetoothHelper.close();
|
|
|
super.onPause();
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
protected void onDestroy()
|
|
|
{
|
|
|
BluetoothHelper.close();
|
|
|
super.onDestroy();
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public void onBackPressed()
|
|
|
{
|
|
|
BluetoothHelper.close();
|
|
|
setResult(RESULT_OK);
|
|
|
finish();
|
|
|
}
|
|
|
|
|
|
public void onCancel(View view)
|
|
|
{
|
|
|
onBackPressed();
|
|
|
}
|
|
|
|
|
|
// Uploaded data buffer
|
|
|
//---------------------------------------------------------
|
|
|
private static final int BUFF_SIZE = 256;
|
|
|
private static byte[] buffArr = new byte[BUFF_SIZE];
|
|
|
private static int buffInd;
|
|
|
private static int xLine;
|
|
|
//---------------------------------------------------------
|
|
|
// Socket Handler
|
|
|
//---------------------------------------------------------
|
|
|
class SocketHandler extends Handler
|
|
|
{
|
|
|
private int pxInd; // Pixel index in picture
|
|
|
private int stInd; // Stage index of uploading
|
|
|
private int dSize; // Size of uploaded data by LOAD command
|
|
|
private int[] array; // Values of picture pixels
|
|
|
|
|
|
public SocketHandler()
|
|
|
{
|
|
|
super();
|
|
|
}
|
|
|
|
|
|
// Converts picture pixels into selected pixel format
|
|
|
// and sends EPDx command
|
|
|
//-----------------------------------------------------
|
|
|
private boolean init(Bitmap bmp)
|
|
|
{
|
|
|
int w = bmp.getWidth(); // Picture with
|
|
|
int h = bmp.getHeight();// Picture height
|
|
|
int epdInd = EPaperDisplay.epdInd;
|
|
|
array = new int[w*h]; // Array of pixels
|
|
|
int i = 0; // Index of pixel in the array of pixels
|
|
|
|
|
|
// Loading pixels into array
|
|
|
//-------------------------------------------------
|
|
|
|
|
|
for (int y = 0; y < h; y++)
|
|
|
for (int x = 0; x < w; x++, i++)
|
|
|
if(epdInd == 25 || epdInd ==37)
|
|
|
array[i] = getVal_7color(bmp.getPixel(x, y));
|
|
|
else
|
|
|
array[i] = getVal(bmp.getPixel(x, y));
|
|
|
|
|
|
pxInd = 0;
|
|
|
xLine = 0; //2.13inch
|
|
|
stInd = 0;
|
|
|
dSize = 0;
|
|
|
|
|
|
buffInd = 2; // Size of command in bytes
|
|
|
buffArr[0] = (byte)'I'; // Name of command (Initialize)
|
|
|
buffArr[1] = (byte)EPaperDisplay.epdInd; // Index of display
|
|
|
|
|
|
return u_send(false);
|
|
|
}
|
|
|
|
|
|
// The function is executed after every "Ok!" response
|
|
|
// obtained from esp32, which means a previous command
|
|
|
// is complete and esp32 is ready to get the new one.
|
|
|
//-----------------------------------------------------
|
|
|
private boolean handleUploadingStage()
|
|
|
{
|
|
|
int epdInd = EPaperDisplay.epdInd;
|
|
|
|
|
|
// 2.13 e-Paper display
|
|
|
if ((epdInd == 3) || (epdInd == 39))
|
|
|
{
|
|
|
if(stInd == 0) return u_line(0, 0, 100);
|
|
|
//-------------------------------------------------
|
|
|
if(stInd == 1) return u_show();
|
|
|
}
|
|
|
|
|
|
// 2.13 b V4
|
|
|
else if ((epdInd == 40))
|
|
|
{
|
|
|
if(stInd == 0) return u_line(0, 0, 50);
|
|
|
if(stInd == 1) return u_next();
|
|
|
if(stInd == 2) return u_line(3, 50, 50);
|
|
|
if(stInd == 3) return u_show();
|
|
|
}
|
|
|
|
|
|
// White-black e-Paper displays
|
|
|
//-------------------------------------------------
|
|
|
else if ((epdInd==0)||(epdInd==6)||(epdInd==7)||(epdInd==9)||(epdInd==12)||
|
|
|
(epdInd==16)||(epdInd==19)||(epdInd==22)||(epdInd==26)||(epdInd==27)||(epdInd==28))
|
|
|
{
|
|
|
if(stInd == 0) return u_data(0,0,100);
|
|
|
if(stInd == 1) return u_show();
|
|
|
}
|
|
|
|
|
|
// 7.5 colored e-Paper displays
|
|
|
//-------------------------------------------------
|
|
|
else if (epdInd>15 && epdInd < 22)
|
|
|
{
|
|
|
if(stInd == 0) return u_data(-1,0,100);
|
|
|
if(stInd == 1) return u_show();
|
|
|
}
|
|
|
|
|
|
// 5.65f colored e-Paper displays
|
|
|
//-------------------------------------------------
|
|
|
else if (epdInd == 25 || epdInd == 37)
|
|
|
{
|
|
|
if(stInd == 0) return u_data(-2,0,100);
|
|
|
if(stInd == 1) return u_show();
|
|
|
}
|
|
|
|
|
|
// Other colored e-Paper displays
|
|
|
//-------------------------------------------------
|
|
|
else
|
|
|
{
|
|
|
// if(stInd==0 && epdInd==23)return u_data(0,0,100);
|
|
|
if(stInd == 0)return u_data((epdInd == 1)? -1 : 0,0,50);
|
|
|
if(stInd == 1)return u_next();
|
|
|
if(stInd == 2)return u_data(3,50,50);
|
|
|
if(stInd == 3)return u_show();
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
// Returns the index of color in palette
|
|
|
//-----------------------------------------------------
|
|
|
public int getVal(int color)
|
|
|
{
|
|
|
int r = Color.red(color);
|
|
|
int b = Color.blue(color);
|
|
|
|
|
|
if((r == 0xFF) && (b == 0xFF)) return 1;
|
|
|
if((r == 0x7F) && (b == 0x7F)) return 2;
|
|
|
if((r == 0xFF) && (b == 0x00)) return 3;
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
// Returns the index of color in palette just for 5.65f e-Paper
|
|
|
//-----------------------------------------------------
|
|
|
public int getVal_7color(int color)
|
|
|
{
|
|
|
int r = Color.red(color);
|
|
|
int g = Color.green(color);
|
|
|
int b = Color.blue(color);
|
|
|
|
|
|
if((r == 0x00) && (g == 0x00) && (b == 0x00)) return 0;
|
|
|
if((r == 0xFF) && (g == 0xFF) && (b == 0xFF)) return 1;
|
|
|
if((r == 0x00) && (g == 0xFF) && (b == 0x00)) return 2;
|
|
|
if((r == 0x00) && (g == 0x00) && (b == 0xFF)) return 3;
|
|
|
if((r == 0xFF) && (g == 0x00) && (b == 0x00)) return 4;
|
|
|
if((r == 0xFF) && (g == 0xFF) && (b == 0x00)) return 5;
|
|
|
if((r == 0xFF) && (g == 0x80) && (b == 0x00)) return 6;
|
|
|
|
|
|
return 7;
|
|
|
}
|
|
|
|
|
|
// Sends command cmd
|
|
|
//-----------------------------------------------------
|
|
|
private boolean u_send(boolean next)
|
|
|
{
|
|
|
if (!BluetoothHelper.btThread.write(buffArr, buffInd))
|
|
|
return false; // Command sending is failed
|
|
|
|
|
|
if(next) stInd++; // Go to next stage if it is needed
|
|
|
return true; // Command is sent successful
|
|
|
}
|
|
|
|
|
|
// Next stage command
|
|
|
//-----------------------------------------------------
|
|
|
private boolean u_next()
|
|
|
{
|
|
|
buffInd = 1; // Size of command in bytes
|
|
|
buffArr[0] = (byte)'N';// Name of command (Next)
|
|
|
|
|
|
pxInd = 0;
|
|
|
return u_send(true);
|
|
|
}
|
|
|
|
|
|
// The finishing command
|
|
|
//-----------------------------------------------------
|
|
|
private boolean u_show()
|
|
|
{
|
|
|
buffInd = 1; // Size of command in bytes
|
|
|
buffArr[0] = (byte)'S';// Name of command (Show picture)
|
|
|
|
|
|
// Return false if the SHOW command is not sent
|
|
|
//-------------------------------------------------
|
|
|
if (!u_send(true)) return false;
|
|
|
|
|
|
// Otherwise exit the uploading activity.
|
|
|
//-------------------------------------------------
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
// Sends pixels of picture and shows uploading progress
|
|
|
//-----------------------------------------------------
|
|
|
private boolean u_load(int k1, int k2)
|
|
|
{
|
|
|
// Uploading progress message
|
|
|
//-------------------------------------------------
|
|
|
String x = "" + (k1 + k2*pxInd/array.length);
|
|
|
if (x.length() > 5) x = x.substring(0, 5);
|
|
|
handleUserInterfaceMessage(x);
|
|
|
|
|
|
// Size of uploaded data
|
|
|
//-------------------------------------------------
|
|
|
dSize += buffInd;
|
|
|
|
|
|
// Request message contains:
|
|
|
// data (maximum BUFF_SIZE bytes),
|
|
|
// size of uploaded data (4 bytes),
|
|
|
// length of data
|
|
|
// command name "LOAD"
|
|
|
//-------------------------------------------------
|
|
|
buffArr[0] = (byte)'L';
|
|
|
|
|
|
// Size of packet
|
|
|
//-------------------------------------------------
|
|
|
buffArr[1] = (byte)(buffInd );
|
|
|
buffArr[2] = (byte)(buffInd >> 8);
|
|
|
|
|
|
// Data size
|
|
|
//-------------------------------------------------
|
|
|
buffArr[3] = (byte)(dSize );
|
|
|
buffArr[4] = (byte)(dSize >> 8);
|
|
|
buffArr[5] = (byte)(dSize >> 16);
|
|
|
|
|
|
return u_send(pxInd >= array.length);
|
|
|
}
|
|
|
|
|
|
// Pixel format converting
|
|
|
//-----------------------------------------------------
|
|
|
private boolean u_data(int c, int k1, int k2)
|
|
|
{
|
|
|
buffInd = 6; // pixels' data offset
|
|
|
|
|
|
if(c == -1)
|
|
|
{
|
|
|
while ((pxInd < array.length) && (buffInd + 1 < BUFF_SIZE))
|
|
|
{
|
|
|
int v = 0;
|
|
|
|
|
|
for(int i = 0; i < 16; i += 2)
|
|
|
{
|
|
|
if (pxInd < array.length) v |= (array[pxInd] << i);
|
|
|
pxInd++;
|
|
|
}
|
|
|
|
|
|
buffArr[buffInd++] = (byte)(v );
|
|
|
buffArr[buffInd++] = (byte)(v >> 8);
|
|
|
}
|
|
|
}
|
|
|
else if(c == -2)
|
|
|
{
|
|
|
while ((pxInd < array.length) && (buffInd + 1 < BUFF_SIZE))
|
|
|
{
|
|
|
int v = 0;
|
|
|
|
|
|
for(int i = 0; i < 16; i += 4)
|
|
|
{
|
|
|
if (pxInd < array.length) v |= (array[pxInd] << i);
|
|
|
pxInd++;
|
|
|
}
|
|
|
|
|
|
buffArr[buffInd++] = (byte)(v );
|
|
|
buffArr[buffInd++] = (byte)(v >> 8);
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
while ((pxInd < array.length) && (buffInd < BUFF_SIZE))
|
|
|
{
|
|
|
int v = 0;
|
|
|
|
|
|
for (int i = 0; i < 8; i++)
|
|
|
{
|
|
|
if ((pxInd < array.length) && (array[pxInd] != c)) v |= (128 >> i);
|
|
|
pxInd++;
|
|
|
}
|
|
|
|
|
|
buffArr[buffInd++] = (byte)v;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return u_load(k1, k2);
|
|
|
}
|
|
|
|
|
|
// Pixel format converting (2.13 e-Paper display)
|
|
|
//-----------------------------------------------------
|
|
|
private boolean u_line(int c, int k1, int k2)
|
|
|
{
|
|
|
buffInd = 6; // pixels' data offset
|
|
|
while ((pxInd < array.length) && (buffInd < 246)) // 15*16+6 ,16*8 = 128
|
|
|
{
|
|
|
int v = 0;
|
|
|
|
|
|
for (int i = 0; (i < 8) && (xLine < 122); i++, xLine++){
|
|
|
if (array[pxInd++] != c) v |= (128 >> i);
|
|
|
}
|
|
|
if(xLine >= 122 )xLine = 0;
|
|
|
buffArr[buffInd++] = (byte)v;
|
|
|
}
|
|
|
return u_load(k1, k2);
|
|
|
}
|
|
|
|
|
|
//-------------------------------------------
|
|
|
// Handles socket message
|
|
|
//-------------------------------------------
|
|
|
public void handleMessage(android.os.Message msg)
|
|
|
{
|
|
|
// "Fatal error" event
|
|
|
//-------------------------------------------------
|
|
|
if (msg.what == BluetoothHelper.BT_FATAL_ERROR)
|
|
|
{
|
|
|
setResult(RESULT_CANCELED);
|
|
|
finish();
|
|
|
}
|
|
|
|
|
|
// "Data is received" event
|
|
|
//-------------------------------------------------
|
|
|
else if (msg.what == BluetoothHelper.BT_RECEIVE_DATA)
|
|
|
{
|
|
|
// Convert data to string
|
|
|
//---------------------------------------------
|
|
|
String line = new String((byte[]) msg.obj, 0, msg.arg1);
|
|
|
|
|
|
// If esp32 is ready for new command
|
|
|
//---------------------------------------------
|
|
|
if (line.contains("Ok!"))
|
|
|
{
|
|
|
// Try to handle received data.
|
|
|
// If it's failed, restart the uploading
|
|
|
//-----------------------------------------
|
|
|
if (handleUploadingStage()) return;
|
|
|
}
|
|
|
|
|
|
// Exit is the message is unknown
|
|
|
//---------------------------------------------
|
|
|
else if (!line.contains("Error!")) return;
|
|
|
|
|
|
// Otherwise restart the uploading
|
|
|
//-----------------------------------------
|
|
|
BluetoothHelper.close();
|
|
|
BluetoothHelper.connect();
|
|
|
handler.init(AppStartActivity.indTableImage);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
// User Interface Handler
|
|
|
//---------------------------------------------------------
|
|
|
public void handleUserInterfaceMessage(String msg)
|
|
|
{
|
|
|
runOnUiThread(new UserInterfaceHandler(msg));
|
|
|
}
|
|
|
|
|
|
private class UserInterfaceHandler implements Runnable
|
|
|
{
|
|
|
public String msg;
|
|
|
|
|
|
public UserInterfaceHandler(String msg)
|
|
|
{
|
|
|
this.msg = "Uploading: " + msg + "%";
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public void run()
|
|
|
{
|
|
|
textView.setText(msg);
|
|
|
}
|
|
|
}
|
|
|
} |