to be able using a remote service through localhost IP (to hide real address from users in other intents) I am using this service to port-forwarding :
public class PortForward extends Service implements Runnable {
private static final String TAG = "Port Forward";
private int localPort;
private int remotePort;
private String remoteHost;
private boolean running = false;
private int lastUp = -1;
private int lastDown = -1;
private int bUp = 0;
private int bDown = 0;
LocalBroadcastManager bm;
private Thread t;
ServerSocketChannel serverSocketChannel = null;
public Handler sendBroadcastHandler = new Handler() {
public void handleMessage(Message msg) {
Intent i = new Intent().setAction(MainActivity.USAGE_UPDATE);
i.putExtra("bUp", bUp);
i.putExtra("bDown", bDown);
bm.sendBroadcast(i);
}
};
public Handler sendDeathHandler = new Handler() {
public void handleMessage(Message msg) {
Bundle b = msg.getData();
String causeOfDeath = b.getString("causeOfDeath", "unknown");
Notification note = new Notification.Builder(PortForward.this)
.setContentTitle("TCP forwarding thread dead")
.setContentText("Cause of death: " + causeOfDeath)
.setSmallIcon(R.drawable.ic_launcher).build();
NotificationManager mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
mNotificationManager.notify(1338, note);
}
};
private void updateCounts() {
updateCounts(false);
}
private void updateCounts(boolean force) {
if (!force && (bUp - lastUp < 10000 && bDown - lastDown < 10000)) {
return;
}
lastUp = bUp;
lastDown = bDown;
Message msg = sendBroadcastHandler.obtainMessage();
sendBroadcastHandler.sendMessage(msg);
}
#Override
public void onDestroy() {
Log.d(TAG, "Service onDestroy");
if (t != null) {
t.interrupt();
try {
t.join();
} catch (InterruptedException e) {
Log.d(TAG, "couldn't join forwarder-thread");
System.exit(1);
}
}
Log.d(TAG, "Killed it");
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "Service onStart");
if (running){
updateCounts(true);
return START_REDELIVER_INTENT;
}
running = true;
bm = LocalBroadcastManager.getInstance(this);
localPort = intent.getIntExtra("localPort", -1);
remotePort = intent.getIntExtra("remotePort", -1);
remoteHost = intent.getStringExtra("remoteHost");
t = new Thread(this);
t.start();
Log.d(TAG, "launching a thread");
Notification note = new Notification.Builder(this)
.setContentTitle("Forwarding TCP Port")
.setContentText(String.format(
"localhost:%s -> %s:%s", localPort, remoteHost, remotePort))
.setSmallIcon(R.drawable.ic_launcher)
.build();
Intent i = new Intent(this, MainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pi = PendingIntent.getActivity(this, 0, i, 0);
note.contentIntent = pi;
note.flags |= Notification.FLAG_NO_CLEAR;
startForeground(1337, note);
Log.d(TAG, "doing startForeground");
updateCounts(true);
return START_REDELIVER_INTENT;
}
private void reportException(Exception e){
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
Message msg = sendDeathHandler.obtainMessage();
Bundle b = msg.getData();
b.putString("causeOfDeath", sw.toString());
sendDeathHandler.sendMessage(msg);
}
private void finish(Selector s){
try {
serverSocketChannel.close();
} catch (IOException e){ }
Set<SelectionKey> selectedKeys = s.keys();
Iterator<SelectionKey> keyIterator = selectedKeys.iterator();
while (keyIterator.hasNext()) {
closeConnectionForKey(keyIterator.next());
}
}
private void closeChannel(SocketChannel c){
if (c != null){
try {
if (c != null){
c.close();
}
} catch (IOException e){ }
}
}
private void closeConnectionForKey(SelectionKey key){
PFGroup g = null;
try {
g = (PFGroup)key.attachment();
} catch (Exception e){
return;
}
if (g == null) {return;}
closeChannel(g.iChannel);
closeChannel(g.oChannel);
}
#Override
public void run() {
String causeOfDeath = null;
System.out.println("Server online");
Selector selector = null;
try {
selector = Selector.open();
serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.socket().bind(new InetSocketAddress(localPort));
serverSocketChannel.configureBlocking(false);
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
} catch (IOException e) {
reportException(e);
return;
}
System.out.println("Server socket bound.");
while (true) {
System.out.println("Waiting for conn");
updateCounts();
int readyChannels = 0;
try {
readyChannels = selector.select();
} catch (IOException e) {
reportException(e);
continue;
}
if (Thread.currentThread().isInterrupted()) {
finish(selector);
return;
}
if (readyChannels == 0) {
continue;
}
Set<SelectionKey> selectedKeys = selector.selectedKeys();
Iterator<SelectionKey> keyIterator = selectedKeys.iterator();
while (keyIterator.hasNext()) {
//System.out.println("Ready on " + readyChannels);
SelectionKey key = keyIterator.next();
keyIterator.remove();
if (!key.isValid()) {
continue;
} else if (key.isAcceptable()) {
System.out.println("Acceptable!");
PFGroup g = new PFGroup();
// 512KB buffers
g.iBuffer = ByteBuffer.allocate(512000);
g.oBuffer = ByteBuffer.allocate(512000);
boolean iConnected = false;
try {
g.iChannel = serverSocketChannel.accept();
iConnected = g.iChannel.finishConnect();
if (iConnected){
g.sidesOn++;
}
g.iChannel.configureBlocking(false);
g.iKey = g.iChannel.register(selector, 0, g);
g.oChannel = SocketChannel.open();
g.oChannel.configureBlocking(false);
g.oChannel.connect(new InetSocketAddress(remoteHost, remotePort));
g.oKey =g.oChannel.register(selector, SelectionKey.OP_CONNECT, g);
} catch (IOException e) {
continue;
}
} else if (key.isConnectable()) {
System.out.println("connectable!");
try {
SocketChannel c = (SocketChannel) key.channel();
PFGroup g = (PFGroup)key.attachment();
if (!c.finishConnect()) {
System.out.println("couldn't finish conencting");
continue;
}
g.sidesOn++;
System.out.println("Initilized the bidirectional forward");
key.interestOps(SelectionKey.OP_READ);
g.iKey = g.iChannel.register(selector, SelectionKey.OP_READ, g);
} catch (IOException e) {
continue;
}
} else if (key.isReadable()) {
try {
ByteBuffer b = null;
SocketChannel from = null;
SocketChannel to = null;
PFGroup g = (PFGroup)key.attachment();
String label = null;
if (key.channel() == g.iChannel){
from = g.iChannel;
to = g.oChannel;
b = g.iBuffer;
label = "incoming";
} else if (key.channel() == g.oChannel){
from = g.oChannel;
to = g.iChannel;
b = g.oBuffer;
label = "outgoing";
}
int i = from.read(b);
b.flip();
while (b.hasRemaining()) {
int bytes = to.write(b);
if(label.equals("incoming")){
bUp += bytes;
} else {
bDown += bytes;
}
}
b.clear();
if (i == -1) {
key.cancel();
g.sidesOn--;
if (g.sidesOn == 0){
System.out.println("Done, closing keys");
closeConnectionForKey(key);
}
}
} catch (IOException e){
Log.d(TAG, "closing connection for key.");
closeConnectionForKey(key);
}
}
}
}
}
public class PFGroup {
public ByteBuffer iBuffer;
public ByteBuffer oBuffer;
public SocketChannel iChannel;
public SocketChannel oChannel;
public int sidesOn = 0;
SelectionKey iKey;
SelectionKey oKey;
}
}
and in my main activity i used it like this:
Intent i=new Intent(this, PortForward.class)
.putExtra("localPort", 1195)
.putExtra("remotePort", port)
.putExtra("remoteHost", address);
startService(i);
but it does not work. when app is in background i can not use address:port through 127.0.0.1:1195 .
and also no related log appeasers in logcat.
Related
My App prints ( Bluetooth printer) without errors or issues in Android 8 thru 10, but in Android 11 it can't print the whole ticket
It always stop half way .
in the error apppear this message
2022-04-13 11:33:10.692 4721-4825/? E/bt_btif_sock_rfcomm: send data to app error writing RFCOMM data back to app: Broken pipe
any help??????
code of bluetooth port
public class BluetoothPort implements IPrinterPort {
private static final String TAG = "BluetoothPort";
private BluetoothDevice mDevice;
private static String mDeviceName;
private static String mDeviceAddress;
private static BluetoothSocket mSocket;
private BluetoothAdapter mAdapter;
private BluetoothPort.ConnectThread mConnectThread;
private static InputStream inputStream;
private static OutputStream outputStream;
private Context mContext;
private Handler mHandler;
private int mState;
private static int readLen;
private final UUID PRINTER_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
private PrinterInstance mPrinter;
private BroadcastReceiver boundDeviceReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if("android.bluetooth.device.action.BOND_STATE_CHANGED".equals(action)) {
BluetoothDevice device = (BluetoothDevice)intent.getParcelableExtra("android.bluetooth.device.extra.DEVICE");
if(!BluetoothPort.this.mDevice.equals(device)) {
return;
}
switch(device.getBondState()) {
case 10:
BluetoothPort.this.mContext.unregisterReceiver(BluetoothPort.this.boundDeviceReceiver);
BluetoothPort.this.setState(102);
Utils.Log("BluetoothPort", "bound cancel");
break;
case 11:
Utils.Log("BluetoothPort", "bounding......");
break;
case 12:
Utils.Log("BluetoothPort", "bound success");
BluetoothPort.this.mContext.unregisterReceiver(BluetoothPort.this.boundDeviceReceiver);
BluetoothPort.this.PairOrConnect(false);
}
}
}
};
public BluetoothPort(Context context, BluetoothDevice device, Handler handler) {
this.mHandler = handler;
this.mDevice = device;
this.mAdapter = BluetoothAdapter.getDefaultAdapter();
this.mState = 103;
this.mContext = context;
}
public BluetoothPort() {
}
public BluetoothPort(Context context, String address, Handler handler) {
this.mHandler = handler;
this.mAdapter = BluetoothAdapter.getDefaultAdapter();
this.mDevice = this.mAdapter.getRemoteDevice(address);
this.mState = 103;
this.mContext = context;
}
public void open() {
Utils.Log("BluetoothPort", "connect to: " + this.mDevice.getName());
if(this.mState != 103) {
this.close();
}
if(this.mDevice.getBondState() == 10) {
Log.i("BluetoothPort", "device.getBondState() is BluetoothDevice.BOND_NONE");
this.PairOrConnect(true);
} else if(this.mDevice.getBondState() == 12) {
this.PairOrConnect(false);
}
}
private void PairOrConnect(boolean pair) {
if(pair) {
IntentFilter boundFilter = new IntentFilter("android.bluetooth.device.action.BOND_STATE_CHANGED");
this.mContext.registerReceiver(this.boundDeviceReceiver, boundFilter);
boolean success = false;
try {
Method createBondMethod = BluetoothDevice.class.getMethod("createBond", new Class[0]);
success = ((Boolean)createBondMethod.invoke(this.mDevice, new Object[0])).booleanValue();
} catch (IllegalAccessException var5) {
var5.printStackTrace();
} catch (IllegalArgumentException var6) {
var6.printStackTrace();
} catch (InvocationTargetException var7) {
var7.printStackTrace();
} catch (NoSuchMethodException var8) {
var8.printStackTrace();
}
Log.i("BluetoothPort", "createBond is success? : " + success);
} else {
//this.mConnectThread = new BluetoothPort.ConnectThread((BluetoothPort.ConnectThread)null);
//this.mConnectThread.start();
}
}
#TargetApi(10)
private boolean ReTryConnect() {
Utils.Log("BluetoothPort", "android SDK version is:" + Build.VERSION.SDK_INT);
try {
if(Build.VERSION.SDK_INT >= 10) {
mSocket = this.mDevice.createInsecureRfcommSocketToServiceRecord(this.PRINTER_UUID);
} else {
Method method = this.mDevice.getClass().getMethod("createRfcommSocket", new Class[]{Integer.TYPE});
mSocket = (BluetoothSocket)method.invoke(this.mDevice, new Object[]{Integer.valueOf(1)});
}
mSocket.connect();
return false;
} catch (Exception var2) {
Log.e(TAG, "فشل1") ;
Utils.Log("BluetoothPort", "connect failed:");
var2.printStackTrace();
return true;
}
}
public void close() {
Utils.Log("BluetoothPort", "close()");
try {
if(mSocket != null) {
Log.e(TAG, "فشل2") ;
mSocket.close();
}
} catch (IOException var2) {
Log.e(TAG, "فشل2") ;
Utils.Log("BluetoothPort", "close socket failed");
var2.printStackTrace();
}
this.mConnectThread = null;
this.mDevice = null;
mSocket = null;
if(this.mState != 102) {
this.setState(103);
}
}
public int write(byte[] data) {
try {
if(outputStream != null) {
outputStream.write(data);
outputStream.flush();
return 0;
} else {
return -1;
}
} catch (IOException var3) {
Log.e(TAG, "فشل3") ;
Utils.Log("BluetoothPort", "write error.");
var3.printStackTrace();
return -1;
}
}
public byte[] read() {
byte[] readBuff = null;
try {
if(inputStream != null && (readLen = inputStream.available()) > 0) {
readBuff = new byte[readLen];
inputStream.read(readBuff);
}
} catch (IOException var3) {
Log.e(TAG, "فشل4") ;
Utils.Log("BluetoothPort", "read error");
var3.printStackTrace();
}
Log.w("BluetoothPort", "read length:" + readLen);
return readBuff;
}
public static synchronized byte[] read(int timeout) {
byte[] receiveBytes = null;
try {
while((readLen = inputStream.available()) <= 0) {
timeout -= 50;
if(timeout <= 0) {
break;
}
try {
Thread.sleep(50L);
} catch (InterruptedException var3) {
Log.e(TAG, "فشل5") ;
var3.printStackTrace();
}
}
if(readLen > 0) {
receiveBytes = new byte[readLen];
inputStream.read(receiveBytes);
}
} catch (IOException var4) {
Log.e(TAG, "فشل6") ;
Utils.Log("BluetoothPort", "read error1");
var4.printStackTrace();
}
return receiveBytes;
}
private synchronized void setState(int state) {
Utils.Log("BluetoothPort", "setState() " + this.mState + " -> " + state);
if(this.mState != state) {
this.mState = state;
if(this.mHandler != null) {
this.mHandler.obtainMessage(this.mState).sendToTarget();
}
}
}
public int getState() {
return this.mState;
}
public PrinterInstance btAutoConn(Context context, BluetoothAdapter adapter, Handler mHandler) {
Properties pro = Utils.getBtConnInfo(context);
mDeviceAddress = pro.getProperty("mac");
if(mDeviceAddress != null && !mDeviceAddress.equals("")) {
Log.v("mac", mDeviceAddress);
this.mDevice = adapter.getRemoteDevice(mDeviceAddress);
mDeviceName = this.mDevice.getName();
this.mPrinter = new PrinterInstance(context, this.mDevice, mHandler);
this.mPrinter.openConnection();
Log.v("btport", "open-success!");
return this.mPrinter;
} else {
return null;
}
}
public PrinterInstance btConnnect(Context context, String mac, BluetoothAdapter adapter, Handler mHandler) {
this.mDevice = adapter.getRemoteDevice(mac);
this.mPrinter = new PrinterInstance(context, this.mDevice, mHandler);
this.mPrinter.openConnection();
Log.v("btport", "open-success!");
return this.mPrinter;
}
public static byte getData(int time) {
byte data = 0;
try {
InputStream inputStream = mSocket.getInputStream();
for(int j = 0; j < 5; ++j) {
if(inputStream.available() != 0) {
byte[] b = new byte[inputStream.available()];
int i = inputStream.read(b);
if(j != 0) {
data = b[i - 1];
break;
}
}
Thread.sleep((long)time);
write1(new byte[]{16, 4, 2});
}
} catch (Exception var6) {
Log.e(TAG, "فشل8") ;
Log.e("TAG", var6.toString());
}
return data;
}
public static byte getEndData(int time) {
byte ret = 0;
try {
InputStream inputStream = mSocket.getInputStream();
for(int j = 0; j < 5; ++j) {
if(inputStream.available() != 0) {
byte[] b = new byte[inputStream.available()];
int i = inputStream.read(b);
if(j != 0) {
ret = b[i - 1];
break;
}
}
Thread.sleep((long)time);
write1(new byte[]{27, 118});
}
} catch (Exception var6) {
Log.e(TAG, "فشل9") ;
var6.printStackTrace();
}
return ret;
}
public static int write1(byte[] data) {
try {
if(outputStream != null) {
Log.e(TAG, "فشل2") ;
outputStream.write(data);
outputStream.flush();
return 0;
} else {
return -1;
}
} catch (IOException var2) {
Log.e(TAG, "فشل10") ;
Utils.Log("BluetoothPort", "write error.");
var2.printStackTrace();
return -1;
}
}
public static String getmDeviceName() {
return mDeviceName;
}
public static void setmDeviceName(String mDeviceName) {
mDeviceName = mDeviceName;
}
public static String getmDeviceAddress() {
return mDeviceAddress;
}
public static void setmDeviceAddress(String mDeviceAddress) {
mDeviceAddress = mDeviceAddress;
}
private class ConnectThread extends Thread {
private ConnectThread() {
}
public void run() {
mAdapter.cancelDiscovery();
try {
Log.e(TAG, "فشل2") ;
Thread.sleep(1000L);
} catch (InterruptedException var6) {
Log.e(TAG, "فشل11") ;
var6.printStackTrace();
}
boolean hasError = false;
BluetoothPort.this.mAdapter.cancelDiscovery();
try {
BluetoothPort.mSocket = BluetoothPort.this.mDevice.createRfcommSocketToServiceRecord(BluetoothPort.this.PRINTER_UUID);
BluetoothPort.mSocket.connect();
} catch (IOException var5) {
Log.e(TAG, "فشل12") ;
Utils.Log("BluetoothPort", "ConnectThread failed. retry.");
var5.printStackTrace();
hasError = BluetoothPort.this.ReTryConnect();
}
synchronized(this) {
BluetoothPort.this.mConnectThread = null;
}
if(!hasError) {
try {
BluetoothPort.inputStream = BluetoothPort.mSocket.getInputStream();
BluetoothPort.outputStream = BluetoothPort.mSocket.getOutputStream();
} catch (IOException var3) {
Log.e(TAG, "فشل13") ;
hasError = true;
Utils.Log("BluetoothPort", "Get Stream failed");
var3.printStackTrace();
}
}
if(hasError) {
BluetoothPort.this.setState(102);
BluetoothPort.this.close();
} else {
BluetoothPort.this.setState(101);
}
}
public void cancel() {
try {
mSocket.close();
} catch (IOException e) {
Log.e(TAG, "Could not close the client socket", e);
}
}
}
}
There is a memory leak reported by LeakCanary in my Android App. I have Googled and studied for days and cannot find any solution. The leaked object is an instance of Activity called "MakeFire". It seems to be related to android.view.WindowManagerGlobal. Can anyone point out how the leak happened, and how to fix it?
Here is the LeakCanary ScreenCap
Here is the source code of the MakeFire Activity
public class MakeFire extends SharedMethod implements StatusBarFragment.OnFragmentInteractionListener,
DayTimeFragment.OnFragmentInteractionListener, BackButtonFragment.OnFragmentInteractionListener {
private Button firePlough;
private Button bowDrill;
private TextView makeFireWithBowDrillTime;
private TextView requirementTextview;
private Button performButton;
private String selectedButton;
private boolean firePloughOn;
private boolean bowDrillOn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_make_fire);
firePlough = (Button) findViewById(R.id.firePlough);
bowDrill = (Button) findViewById(R.id.bowDrill);
makeFireWithBowDrillTime = (TextView) findViewById(R.id.makeFireWithBowDrillTime);
requirementTextview = (TextView) findViewById(R.id.requirementTextview);
performButton = (Button) findViewById(R.id.performButton);
}
#Override
public void onDestroy() {
super.onDestroy();
RefWatcher refWatcher = MyApplication.getRefWatcher(this);
refWatcher.watch(this);
}
#Override
public void onBackPressed() {
Bundle extra = new Bundle();
extra.putString("classToGoBack", getClass().getName());
Intent intent = new Intent(this, InGameMenu.class);
intent.putExtras(extra);
startActivity(intent);
}
#Override
public void onResume() {
super.onResume();
GameData.useImmersiveModeSticky(this);
}
#Override
public void onStop() {
super.onStop();
try {
//save on the latest save file
FileOutputStream latestSavedGame = openFileOutput("latestSavedGame", Context.MODE_PRIVATE);
ObjectOutputStream latestGameData = new ObjectOutputStream(latestSavedGame);
latestGameData.writeObject(GameData.GDI);
latestSavedGame.close();
} catch (Exception e) {
//TODO - delete it before uploading the app
GameData.GDI.showPlainMsg("sharedMethodProblem!", this);
final StringWriter sw = new StringWriter();
final PrintWriter pw = new PrintWriter(sw, true);
e.printStackTrace(pw);
GameData.GDI.showPlainMsg(sw.getBuffer().toString(), this);
}
boolean savedGameIsFine;
try {
FileInputStream latestSavedGame = openFileInput("latestSavedGame");
ObjectInputStream latestGameData = new ObjectInputStream(latestSavedGame);
savedGameIsFine = (latestGameData.readObject() != null);
latestSavedGame.close();
} catch (Exception e) {
savedGameIsFine = false;
}
if (savedGameIsFine) {
try {
//save on the latest save file
FileOutputStream latestSavedGame = openFileOutput("latestSavedGameBackup", Context.MODE_PRIVATE);
ObjectOutputStream latestGameData = new ObjectOutputStream(latestSavedGame);
latestGameData.writeObject(GameData.GDI);
latestSavedGame.close();
} catch (Exception e) {
}
} else {
}
}
#Override
protected void onStart() {
super.onStart();
updateAllViews();
requirementTextview.setVisibility(View.INVISIBLE);
performButton.setVisibility(View.INVISIBLE);
}
//method for updating all amendable views in the page
private void updateAllViews() {
//visibility of fire plough button
if (GameData.GDI.anyThisInventoryAvailable(GameData.FIRE_PLOUGH) &&
GameData.GDI.anyThisInventoryAvailable(GameData.TINDER) &&
(!GameData.GDI.stormOn || GameData.GDI.currentLocation.campfireWindBlock)
) {
firePlough.setCompoundDrawablesWithIntrinsicBounds(0,R.drawable.ic_fireplow_3_f,0,0);
firePlough.setTextColor(ContextCompat.getColor(this, R.color.buttonOnColour));
firePloughOn = true;
}
else {
firePlough.setCompoundDrawablesWithIntrinsicBounds(0,R.drawable.ic_fireplow_3_f_o,0,0);
firePlough.setTextColor(ContextCompat.getColor(this, R.color.buttonOffColour));
firePloughOn = false;
}
//visibility of bow drill button
if (GameData.GDI.bowDrillUnlocked) {
bowDrill.setVisibility(View.VISIBLE);
makeFireWithBowDrillTime.setVisibility(View.VISIBLE);
if (GameData.GDI.anyThisInventoryAvailable(GameData.BOW_DRILL) &&
GameData.GDI.anyThisInventoryAvailable(GameData.TINDER) &&
(!GameData.GDI.stormOn || GameData.GDI.currentLocation.campfireWindBlock)
) {
bowDrill.setCompoundDrawablesWithIntrinsicBounds(0,R.drawable.ic_bow_drill_3_f,0,0);
bowDrill.setTextColor(ContextCompat.getColor(this, R.color.buttonOnColour));
bowDrillOn = true;
}
else {
bowDrill.setCompoundDrawablesWithIntrinsicBounds(0,R.drawable.ic_bow_drill_3_f_o,0,0);
bowDrill.setTextColor(ContextCompat.getColor(this, R.color.buttonOffColour));
bowDrillOn = false;
}
}
updateStatusBarFragment();
updateDayTimeFragment();
}
public void makeFireWithFirePlough(View view) {
if (firePloughOn) {
performButton.setVisibility(View.VISIBLE);
}
else {
performButton.setVisibility(View.INVISIBLE);
}
requirementTextview.setVisibility(View.VISIBLE);
requirementTextview.setText(R.string.makeFireWithFirePloughRqm);
selectedButton = "fire plough";
}
public void makeFireWithBowDrill(View view) {
if (bowDrillOn) {
performButton.setVisibility(View.VISIBLE);
}
else {
performButton.setVisibility(View.INVISIBLE);
}
requirementTextview.setVisibility(View.VISIBLE);
requirementTextview.setText(R.string.makeFireWithBowDrillRqm);
selectedButton = "bow drill";
}
public void perform(View view){
if (!GameData.GDI.stormOn || GameData.GDI.currentLocation.campfireWindBlock){
switch (selectedButton){
case "fire plough":
String msgToShow = "";
String extraInfo = "";
String[] timePassMsg;
Bundle extras = new Bundle();
//timepass method must run before the fireToLast method
timePassMsg = GameData.GDI.timePass(30, 1, 1, 1, this);
if (GameData.GDI.anyThisInventoryInBackpack(GameData.TINDER)) {
GameData.GDI.setInventoryAmount(GameData.TINDER, true, -1);
}
else {
GameData.GDI.setInventoryAmount(GameData.TINDER, false, -1);
}
extras.putString("toolUsed", getString(R.string.usedTinderMsg));
//update tool durability
GameData.GDI.firePloughDurability = GameData.GDI.updateInventoryDurability(GameData.FIRE_PLOUGH, GameData.GDI.firePloughDurability, GameData.FIRE_PLOUGH_MAX_DURABILITY);
//Because in GameCamp.updateInventoryDurability, if the tool broke, it will reset the durability to its maxDurability;
//so if these 2 numbers equal, the tool just broke
if (GameData.GDI.firePloughDurability == GameData.FIRE_PLOUGH_MAX_DURABILITY) {
extraInfo += getString(R.string.firePloughBreakMsg) + "\n\n";
}
GameData.GDI.bowDrillUnlockCounter += 1;
if (Math.random() < 0.75) {
GameData.GDI.currentLocation.fireOn = true;
GameData.GDI.currentLocation.fireToLast += 10;
msgToShow += getString(R.string.success) + "\n";
extras.putString("className", "Fire");
}
else {
msgToShow += getString(R.string.fail) + "\n";
if (!GameData.GDI.bowDrillUnlocked) {
if (GameData.GDI.bowDrillUnlockCounter >= 3) {
extraInfo += getString(R.string.bowDrillUnlockMsg) + "\n\n";
GameData.GDI.bowDrillUnlocked = true;
GameData.GDI.setCraftingAlertIcon(3);
}
}
extras.putString("className", "Make Fire");
}
Intent intent = new Intent(this, LoadingPage.class);
extras.putString("actionName", getString(R.string.makingFireWithFirePlough));
extras.putInt("timeNeeded", 30);
extras.putString("msgToShow", msgToShow);
extras.putString("extraInfo", extraInfo);
extras.putString("timePassMsg", timePassMsg[0]);
extras.putString("deathReason", timePassMsg[1]);
intent.putExtras(extras);
startActivity(intent);
break;
case "bow drill":
String msgToShow1 = "";
String extraInfo1 = "";
String[] timePassMsg1;
Bundle extras1 = new Bundle();
//timepass method must run before the fireToLast method
timePassMsg1 = GameData.GDI.timePass(10, 1, 1, 1, this);
if (GameData.GDI.anyThisInventoryInBackpack(GameData.TINDER)) {
GameData.GDI.setInventoryAmount(GameData.TINDER, true, -1);
}
else {
GameData.GDI.setInventoryAmount(GameData.TINDER, false, -1);
}
extras1.putString("toolUsed", getString(R.string.usedTinderMsg));
//update tool durability
GameData.GDI.bowDrillDurability = GameData.GDI.updateInventoryDurability(GameData.BOW_DRILL, GameData.GDI.bowDrillDurability, GameData.BOW_DRILL_MAX_DURABILITY);
//Because in GameCamp.updateInventoryDurability, if the tool broke, it will reset the durability to its maxDurability;
//so if these 2 numbers equal, the tool just broke
if (GameData.GDI.bowDrillDurability == GameData.BOW_DRILL_MAX_DURABILITY) {
extraInfo1 += getString(R.string.bowDrillBreakMsg) + "\n\n";
}
if (Math.random() < 0.95) {
GameData.GDI.currentLocation.fireOn = true;
GameData.GDI.currentLocation.fireToLast += 10;
msgToShow1 += getString(R.string.success) + "\n";
extras1.putString("className", "Fire");
}
else {
msgToShow1 += getString(R.string.fail) + "\n";
extras1.putString("className", "Make Fire");
}
Intent intent1 = new Intent(this, LoadingPage.class);
extras1.putString("actionName", getString(R.string.makingFireWithBowDrill));
extras1.putString("className", "Fire");
extras1.putInt("timeNeeded", 10);
extras1.putString("msgToShow", msgToShow1);
extras1.putString("extraInfo", extraInfo1);
extras1.putString("timePassMsg", timePassMsg1[0]);
extras1.putString("deathReason", timePassMsg1[1]);
intent1.putExtras(extras1);
startActivity(intent1);
break;
}
}
else {
GameData.GDI.showPlainMsg(getString(R.string.cannotMakeFireInStormMsg), this);
}
}
//fragment method
public void updateStatusBarFragment() {
StatusBarFragment statusBarFragment = (StatusBarFragment)getSupportFragmentManager().findFragmentById(R.id.statusBarFragment);
statusBarFragment.updateStatusBar();
}
public void updateDayTimeFragment() {
DayTimeFragment dayTimeFragment = (DayTimeFragment)getSupportFragmentManager().findFragmentById(R.id.dayTimeFragment);
dayTimeFragment.updateDayTimeView();
}
public void backButton(View view){
Intent intent = new Intent(this, Fire.class);
startActivity(intent);
}
}
I followed Epson SDK and used sample code... To print Receipts
So over there from samples I got that I can print Text, Image and both Ways...
By using this... to print Text and Images..
public class MainActivity extends Activity implements View.OnClickListener, ReceiveListener {
private Context mContext = null;
private EditText mEditTarget = null;
private Spinner mSpnSeries = null;
private Spinner mSpnLang = null;
private Printer mPrinter = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = this;
int[] target = {
R.id.btnDiscovery,
R.id.btnSampleReceipt,
};
for (int i = 0; i < target.length; i++) {
Button button = (Button)findViewById(target[i]);
button.setOnClickListener(this);
}
mSpnSeries = (Spinner)findViewById(R.id.spnModel);
ArrayAdapter<SpnModelsItem> seriesAdapter = new ArrayAdapter<SpnModelsItem>(this, android.R.layout.simple_spinner_item);
seriesAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
seriesAdapter.add(new SpnModelsItem(getString(R.string.printerseries_t20), Printer.TM_T20));
mSpnSeries.setAdapter(seriesAdapter);
mSpnSeries.setSelection(0);
try {
Log.setLogSettings(mContext, Log.PERIOD_TEMPORARY, Log.OUTPUT_STORAGE, null, 0, 1, Log.LOGLEVEL_LOW);
}
catch (Exception e) {
ShowMsg.showException(e, "setLogSettings", mContext);
}
mEditTarget = (EditText)findViewById(R.id.edtTarget);
}
#Override
protected void onActivityResult(int requestCode, final int resultCode, final Intent data) {
if (data != null && resultCode == RESULT_OK) {
String target = data.getStringExtra(getString(R.string.title_target));
if (target != null) {
EditText mEdtTarget = (EditText)findViewById(R.id.edtTarget);
mEdtTarget.setText(target);
}
}
}
#Override
public void onClick(View v) {
Intent intent = null;
switch (v.getId()) {
case R.id.btnDiscovery:
intent = new Intent(this, DiscoveryActivity.class);
startActivityForResult(intent, 0);
break;
case R.id.btnSampleReceipt:
updateButtonState(false);
if (!runPrintReceiptSequence()) {
updateButtonState(true);
}
break;
case R.id.btnSampleCoupon:
updateButtonState(false);
if (!runPrintCouponSequence()) {
updateButtonState(true);
}
break;
default:
// Do nothing
break;
}
}
private boolean runPrintReceiptSequence() {
if (!initializeObject()) {
return false;
}
if (!createReceiptData()) {
finalizeObject();
return false;
}
if (!printData()) {
finalizeObject();
return false;
}
return true;
}
private boolean createReceiptData() {
String method = "";
Bitmap logoData = BitmapFactory.decodeResource(getResources(), R.drawable.store);
StringBuilder textData = new StringBuilder();
final int barcodeWidth = 2;
final int barcodeHeight = 100;
if (mPrinter == null) {
return false;
}
try {
method = "addTextAlign";
mPrinter.addTextAlign(Printer.ALIGN_CENTER);
method = "addImage";
mPrinter.addImage(logoData, 0, 0,
logoData.getWidth(),
logoData.getHeight(),
Printer.COLOR_1,
Printer.MODE_MONO,
Printer.HALFTONE_DITHER,
Printer.PARAM_DEFAULT,
Printer.COMPRESS_AUTO);
method = "addFeedLine";
mPrinter.addFeedLine(1);
textData.append("EPSON PRINT DEMO TEST - \n");
textData.append("STORE DIRECTOR – XYZ\n");
textData.append("\n");
textData.append("28/06/16 05:15 012 0154 0225\n");
textData.append("ST# 21 OP# 001 TE# 01 TR# 747\n");
textData.append("------------------------------\n");
method = "addText";
mPrinter.addText(textData.toString());
textData.delete(0, textData.length());
textData.append("524 5 GREEN TEA 19.99 R\n");
textData.append("003 2 LEMON TEA 59.99 R\n");
textData.append("------------------------------\n");
method = "addText";
mPrinter.addText(textData.toString());
textData.delete(0, textData.length());
textData.append("SUBTOTAL 79.98\n");
textData.append("TAX 15.00\n");
method = "addText";
mPrinter.addText(textData.toString());
textData.delete(0, textData.length());
method = "addTextSize";
mPrinter.addTextSize(2, 2);
method = "addText";
mPrinter.addText("TOTAL 94.98.41\n");
method = "addTextSize";
mPrinter.addTextSize(1, 1);
method = "addFeedLine";
mPrinter.addFeedLine(1);
textData.append("CASH 100.00\n");
textData.append("CHANGE 5.02\n");
textData.append("------------------------------\n");
method = "addText";
mPrinter.addText(textData.toString());
textData.delete(0, textData.length());
textData.append("Purchased item total number\n");
textData.append("Sign Up and Save !\n");
textData.append("With Preferred Saving Card\n");
method = "addText";
mPrinter.addText(textData.toString());
textData.delete(0, textData.length());
method = "addFeedLine";
mPrinter.addFeedLine(2);
method = "addCut";
mPrinter.addCut(Printer.CUT_FEED);
}
catch (Exception e) {
ShowMsg.showException(e, method, mContext);
return false;
}
textData = null;
return true;
}
private boolean runPrintCouponSequence() {
if (!initializeObject()) {
return false;
}
if (!createCouponData()) {
finalizeObject();
return false;
}
if (!printData()) {
finalizeObject();
return false;
}
return true;
}
private boolean printData() {
if (mPrinter == null) {
return false;
}
if (!connectPrinter()) {
return false;
}
PrinterStatusInfo status = mPrinter.getStatus();
dispPrinterWarnings(status);
if (!isPrintable(status)) {
ShowMsg.showMsg(makeErrorMessage(status), mContext);
try {
mPrinter.disconnect();
}
catch (Exception ex) {
// Do nothing
}
return false;
}
try {
mPrinter.sendData(Printer.PARAM_DEFAULT);
}
catch (Exception e) {
ShowMsg.showException(e, "sendData", mContext);
try {
mPrinter.disconnect();
}
catch (Exception ex) {
// Do nothing
}
return false;
}
return true;
}
private boolean initializeObject() {
try {
mPrinter = new Printer(((SpnModelsItem) mSpnSeries.getSelectedItem()).getModelConstant(),
((SpnModelsItem) mSpnLang.getSelectedItem()).getModelConstant(),
mContext);
}
catch (Exception e) {
ShowMsg.showException(e, "Printer", mContext);
return false;
}
mPrinter.setReceiveEventListener(this);
return true;
}
private void finalizeObject() {
if (mPrinter == null) {
return;
}
mPrinter.clearCommandBuffer();
mPrinter.setReceiveEventListener(null);
mPrinter = null;
}
private boolean connectPrinter() {
boolean isBeginTransaction = false;
if (mPrinter == null) {
return false;
}
try {
mPrinter.connect(mEditTarget.getText().toString(), Printer.PARAM_DEFAULT);
}
catch (Exception e) {
ShowMsg.showException(e, "connect", mContext);
return false;
}
try {
mPrinter.beginTransaction();
isBeginTransaction = true;
}
catch (Exception e) {
ShowMsg.showException(e, "beginTransaction", mContext);
}
if (isBeginTransaction == false) {
try {
mPrinter.disconnect();
}
catch (Epos2Exception e) {
// Do nothing
return false;
}
}
return true;
}
private void disconnectPrinter() {
if (mPrinter == null) {
return;
}
try {
mPrinter.endTransaction();
}
catch (final Exception e) {
runOnUiThread(new Runnable() {
#Override
public synchronized void run() {
ShowMsg.showException(e, "endTransaction", mContext);
}
});
}
try {
mPrinter.disconnect();
}
catch (final Exception e) {
runOnUiThread(new Runnable() {
#Override
public synchronized void run() {
ShowMsg.showException(e, "disconnect", mContext);
}
});
}
finalizeObject();
}
private boolean isPrintable(PrinterStatusInfo status) {
if (status == null) {
return false;
}
if (status.getConnection() == Printer.FALSE) {
return false;
}
else if (status.getOnline() == Printer.FALSE) {
return false;
}
else {
;//print available
}
return true;
}
private String makeErrorMessage(PrinterStatusInfo status) {
String msg = "";
if (status.getBatteryLevel() == Printer.BATTERY_LEVEL_0) {
msg += getString(R.string.handlingmsg_err_battery_real_end);
}
return msg;
}
private void dispPrinterWarnings(PrinterStatusInfo status) {
EditText edtWarnings = (EditText)findViewById(R.id.edtWarnings);
String warningsMsg = "";
if (status == null) {
return;
}
if (status.getPaper() == Printer.PAPER_NEAR_END) {
warningsMsg += getString(R.string.handlingmsg_warn_receipt_near_end);
}
if (status.getBatteryLevel() == Printer.BATTERY_LEVEL_1) {
warningsMsg += getString(R.string.handlingmsg_warn_battery_near_end);
}
edtWarnings.setText(warningsMsg);
}
private void updateButtonState(boolean state) {
Button btnReceipt = (Button)findViewById(R.id.btnSampleReceipt);
Button btnCoupon = (Button)findViewById(R.id.btnSampleCoupon);
btnReceipt.setEnabled(state);
btnCoupon.setEnabled(state);
}
#Override
public void onPtrReceive(final Printer printerObj, final int code, final PrinterStatusInfo status, final String printJobId) {
runOnUiThread(new Runnable() {
#Override
public synchronized void run() {
ShowMsg.showResult(code, makeErrorMessage(status), mContext);
dispPrinterWarnings(status);
updateButtonState(true);
new Thread(new Runnable() {
#Override
public void run() {
disconnectPrinter();
}
}).start();
}
});
}
}
In the same way I want to print PDF. Is this Possible without any library?
Or else is it possible to print PDF in thermal Printer?
Can anyone suggest me how to print PDF in a thermal printer?
Here I have this to print a Image/bitmap
Bitmap logoData = BitmapFactory.decodeResource(getResources(), R.drawable.store);
StringBuilder textData = new StringBuilder();
final int barcodeWidth = 2;
final int barcodeHeight = 100;
with addimage.. and for text I am giving plain text... with addtext....
Can Any one suggest Me How to add a PDF to this...
I followed May tutorials,... But Nothing Found related to PDF in thermal Printer(EPSON) Printer..
I am trying to communicate from android to a microprocessor controlled device, which uses HC-05, I have tried every possible solution, but btSocket.connect() is throwing
read failed, socket might closed or timeout, read ret android
Relevant code snippet is provided below:-
/**
* Sends the data Over BlueTooth
* #param data
* bytes which is to be send to the bibox.
*
* */
private void sendDataToBlueTooth(byte[] data){
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
String mMacChecking = pref.getString("BL", "bl");
if (!mMacChecking.equals("bl")) {
// Intent in = new Intent(getApplicationContext(), DataSendReceive.class);
// in.putExtra("isBtRemoteData", true);
// in.putExtra("bData", data);
// startActivity(in);
final SharedPreferences pre = PreferenceManager.getDefaultSharedPreferences(this.getApplicationContext());
this.mDeviceMACAddress = pre.getString("BL", "");
this.mSendArray = data;
this.mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (this.mBluetoothAdapter == null) {
Toast.makeText(this, R.string.no_bt_device, Toast.LENGTH_LONG).show();
this.finish();
return;
}
this.connectTOdevice();
this.mHandler = new Handler() {
#SuppressLint("ShowToast")
#Override
public void handleMessage(final android.os.Message msg) {
if (msg.what == 1) {
mConnectStatus = true;
for (int i = 0; i < mSendArray.length; i++) {
write(mSendArray[i]);
}
String str = Arrays.toString(mSendArray);
Log.d("", str);
//Added an alert dialog to show the data..
// To activate the alert, put the below 3 lines inside the on click of the OK button...
onBackPressed();
try {
Thread.sleep(1000);
} catch (final InterruptedException e) {
e.printStackTrace();
}
} else if (msg.what == 2) {
// Set button to display current status
// connectStat = true;
final byte[] readBuf = (byte[]) msg.obj;
System.out.println("InHandler - ");
String receivedString = "";
for (final byte b : readBuf) {
// `byte` to `Byte`
final int temp = b;
final String tempString = String.valueOf(temp);
receivedString = receivedString.concat("," + tempString);
}
Log.d("received string", receivedString);
for (final byte element : readBuf) {
System.out.print(element + ",");
}
// System.out.println("" + readBuf);
} else if (mBluetoothAdapter.isEnabled()) {
final Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
} else {
// Connection failed
mFailToast.show();
/* Intent scan = new Intent(getApplicationContext(), BluetoothDeviceDiscover.class); */
finish();
// startActivity(scan);
}
}
};
mFailToast = Toast.makeText(this, "Failed to connect please on " + this.mDeviceMACAddress + " or scan for new device", Toast.LENGTH_SHORT);
this.mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (this.mBluetoothAdapter == null) {
Toast.makeText(this, R.string.no_bt_device, Toast.LENGTH_LONG).show();
this.finish();
return;
}
this.connectTOdevice();
}
}
#Override
protected void onDestroy() {
super.onDestroy();
try {
if (this.mBtSocket != null) {
this.mBtSocket.close();
}
} catch (final IOException e2) {}
}
public void write(final byte arr2) {
if (this.mConnectStatus == true) if (this.mOutStream != null) {
try {
this.mOutStream.write(arr2);
} catch (final IOException e) {
showToast(getString(R.string.dataNotSendMessage), false);
}
} else {
showToast(getString(R.string.switchOnBlueToothDevice), false);
}
}
public void connectTOdevice() {
this.mConnectThread = new ConnectThread(this.mDeviceMACAddress);
this.mConnectThread.start();
}
private final BroadcastReceiver mPairReceiver = new BroadcastReceiver() {
boolean isUnpairToastToBeDisplayed = true;
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
String DEVICE_PIN = getString(R.string.device_pin);
final BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (action.equals("android.bluetooth.device.action.BOND_STATE_CHANGED")) {
byte[] pin;
try {
pin = (byte[]) BluetoothDevice.class.getMethod("convertPinToBytes", String.class).invoke(BluetoothDevice.class, DEVICE_PIN);
BluetoothDevice.class.getMethod("setPin", byte[].class).invoke(device, pin);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
final int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR);
final int prevState = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, BluetoothDevice.ERROR);
if (state == BluetoothDevice.BOND_BONDED && prevState == BluetoothDevice.BOND_BONDING) {
//Continue work here....
//If the number of paired devices greater than 3, unpair everything except the current one...
//Causing problem in lenovo tablet...
//Problem :- Tablet hang for more than 4 paired devices...
BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
Set<BluetoothDevice> mPairedDevices;
mPairedDevices = btAdapter.getBondedDevices();
final SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
String deviceAddress = pref.getString("BL", "NoDevice");
if (mPairedDevices.size() > MAX_ALLOWED_PAIRED_DEVICES) {
// findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);
for (final BluetoothDevice deviceForLoop : mPairedDevices) {
//if the device for loop doesn't match the latest saved address...
//unpair the device...
if(!deviceAddress.equals(deviceForLoop.getAddress())){
isUnpairToastToBeDisplayed = false;
unpairDevice(deviceForLoop);
isUnpairToastToBeDisplayed = true;
}
}
}
showToast(getString(R.string.pairedToastMessage),false);
} else if (state == BluetoothDevice.BOND_NONE && prevState == BluetoothDevice.BOND_BONDED){
if(!isUnpairToastToBeDisplayed)
showToast(getString(R.string.unpairedToastMessage),false);
}
}
try {
device.getClass().getMethod("setPairingConfirmation", boolean.class).invoke(device, true);
Intent i = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
sendBroadcast(i);
} catch (IllegalArgumentException e1) {
e1.printStackTrace();
} catch (IllegalAccessException e1) {
e1.printStackTrace();
} catch (InvocationTargetException e1) {
e1.printStackTrace();
} catch (NoSuchMethodException e1) {
e1.printStackTrace();
}
}
};
private void unpairDevice(final BluetoothDevice device) {
try {
final Method m = device.getClass().getMethod("removeBond", (Class[]) null);
m.invoke(device, (Object[]) null);
} catch (final Exception e) {
// Log.e(TAG, e.getMessage());
}
}
public class ConnectThread extends Thread {
private final String address;
private boolean connectionStatus;
ConnectThread(final String MACaddress) {
this.address = MACaddress;
this.connectionStatus = false;
}
#Override
public void run() {
mBluetoothAdapter.cancelDiscovery();
try {
final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(this.address);
IntentFilter intent = new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
registerReceiver(mPairReceiver, intent);
try {
SPP_UUID = device.getUuids()[0].getUuid();
BluetoothSocket tmp = device.createInsecureRfcommSocketToServiceRecord(SPP_UUID);
Class<?> clazz = tmp.getRemoteDevice().getClass();
Class<?>[] paramTypes = new Class<?>[] {Integer.TYPE};
Method m = clazz.getMethod("createRfcommSocket", paramTypes);
Object[] params = new Object[] {Integer.valueOf(1)};
mBtSocket = (BluetoothSocket) m.invoke(tmp.getRemoteDevice(), params);
} catch (final IOException e) {
this.connectionStatus = false;
} catch (Exception e) {
}
} catch (final IllegalArgumentException e) {
this.connectionStatus = false;
}
try {
mBtSocket.connect();
this.connectionStatus = true;
} catch (final IOException e1) {
try {
mBtSocket.close();
Log.d("check", "check");
} catch (final IOException e2) {}
}
// Create a data stream so we can talk to server.
try {
mOutStream = mBtSocket.getOutputStream();
} catch (final IOException e2) {
this.connectionStatus = false;
}
// Send final result
if (this.connectionStatus) {
mHandler.sendEmptyMessage(1);
} else {
mHandler.sendEmptyMessage(0);
}
}
}
}
I found the answer in the following question:-
IOException: read failed, socket might closed - Bluetooth on Android 4.3
Actually I had to use reflection only on the fall back, ie, inside the catch when the connect fails.
I'm making an app that sends a notification to the status bar, it sends the notification when stepping through the code in the debugger, however it never sends the notification when run in realtime.
Here is my runnable that generates the notification, again when stepping through this code in the debugger the notification runs however in realtime nothing happens.
public class NewsEvents_Service extends Service {
private static final String NEWSEVENTS = "newsevents";
private static final String KEYWORDS = "keywords";
private NotificationManager mNM;
private ArrayList<NewsEvent> neList;
private int count;
#Override
public void onCreate() {
mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
neList = new ArrayList<NewsEvent>();
getKeywords();
//getNewsEvents();
Thread thr = new Thread(null, mTask, "NewsEvents_Service");
thr.start();
Log.d("Thread", "IT STARTED!!!!!!????!!!!!!!!!!!!!!!?!!?");
}
#Override
public void onDestroy() {
// Cancel the notification -- we use the same ID that we had used to start it
mNM.cancel(R.string.ECS);
// Tell the user we stopped.
Toast.makeText(this, "Service Done", Toast.LENGTH_SHORT).show();
}
/**
* The function that runs in our worker thread
*/
Runnable mTask = new Runnable() {
public void run() {
getNewsEventsFromWeb();
for(NewsEvent ne : neList){
Log.d("Thread Running", "Service Code running!!!!!!!!!!!!!!!");
String body = ne.getBody().replaceAll("\\<.*?>", "");
String title = ne.getTitle();
for(String s : keyWordList){
if(body.contains(s) || body.contains(s.toLowerCase()) ||
title.contains(s) || title.contains(s.toLowerCase())){
ne.setInterested(true);
}
}
if(ne.isInterested() == true ){
Notification note = new Notification(R.drawable.icon,
"New ECS News Event", System.currentTimeMillis());
Intent i = new Intent(NewsEvents_Service.this, FullNewsEvent.class);
i.putExtra("ne", ne);
PendingIntent pi = PendingIntent.getActivity(NewsEvents_Service.this, 0,
i, 0);
note.setLatestEventInfo(NewsEvents_Service.this, "New Event", ne.getTitle(), pi);
note.flags = Notification.FLAG_AUTO_CANCEL;
mNM.notify(R.string.ECS, note);
}
}
}
};
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
/**
* Show a notification while this service is running.
*/
private void getNewsEventsFromWeb() {
HttpClient client = new DefaultHttpClient();
HttpGet get;
try {
get = new HttpGet(getString(R.string.jsonnewsevents));
ResponseHandler<String> response = new BasicResponseHandler();
String responseBody = client.execute(get, response);
String page = responseBody;
Bundle data = new Bundle();
data.putString("page",page);
Message msg = new Message();
msg.setData(data);
handler.sendMessage(msg);
}
catch (Throwable t) {
Log.d("UpdateNews", "PROBLEMS");
}
}
private Handler handler = new Handler(){
#Override
public void handleMessage(Message msg) {
String page = msg.getData().getString("page");
try {
JSONArray parseArray = new JSONArray(page);
for (int i = 0; i < parseArray.length(); i++) {
JSONObject jo = parseArray.getJSONObject(i);
String title = jo.getString("title");
String body =jo.getString("body");
String pd = jo.getString("postDate");
String id = jo.getString("id");
NewsEvent ne = new NewsEvent(title, pd , body, id);
boolean unique = true;
for(NewsEvent ne0 : neList){
if(ne.getId().equals(ne0.getId())){
unique = false;
}else{
unique = true;
}
}
if(unique == true){
neList.add(ne);
}
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
private ArrayList<String> keyWordList;
public void getNewsEvents(){
try {
InputStream fi = openFileInput(NEWSEVENTS);
if (fi!=null) {
ObjectInputStream in = new ObjectInputStream(fi);
neList = (ArrayList<NewsEvent>) in.readObject();
in.close();
}
}
catch (java.io.FileNotFoundException e) {
// that's OK, we probably haven't created it yet
}
catch (Throwable t) {
Toast
.makeText(this, "Exception: "+t.toString(), Toast.LENGTH_LONG)
.show();
}
if(neList == null){
neList = new ArrayList<NewsEvent>();
}
}
public ArrayList<String> getKeywords(){
try {
InputStream fi = openFileInput(KEYWORDS);
if (fi!=null) {
ObjectInputStream in = new ObjectInputStream(fi);
keyWordList = (ArrayList<String>) in.readObject();
in.close();
}
}
catch (java.io.FileNotFoundException e) {
// that's OK, we probably haven't created it yet
}
catch (Throwable t) {
Toast
.makeText(this, "Exception: "+t.toString(), Toast.LENGTH_LONG)
.show();
}
if(keyWordList == null){
keyWordList = new ArrayList<String>();
return keyWordList;
}
return keyWordList;
}
/**
* This is the object that receives interactions from clients. See RemoteService
* for a more complete example.
*/
private final IBinder mBinder = new Binder() {
#Override
protected boolean onTransact(int code, Parcel data, Parcel reply,
int flags) throws RemoteException {
return super.onTransact(code, data, reply, flags);
}
};
}
Here is my activity that schedules the service to run
public class NewsEvents extends ListActivity{
private URL JSONNewsEvents;
private ArrayList<NewsEvent> neList;
private ArrayList<String> keyWordList;
private Worker worker;
private NewsEvents ne;
public static final String KEYWORDS = "keywords";
private static final String NEWSEVENTS = "newsevents";
public static final int ONE_ID = Menu.FIRST+1;
private PendingIntent newsAlarm;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.newsevents);
ne = this;
neList = new ArrayList<NewsEvent>();
try {
JSONNewsEvents = new URL(getString(R.string.jsonnewsevents));
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
worker = new Worker(handler, this);
setListAdapter(new IconicAdapter());
getKeywords();
worker.execute(JSONNewsEvents);
}
#Override
protected void onStop() {
super.onStop();
writeNewsEvents() ;
}
#Override
protected void onPause(){
super.onPause();
writeNewsEvents();
}
private void writeNewsEvents() {
try {
OutputStream fi = openFileOutput(NEWSEVENTS, 0);
if (fi!=null) {
ObjectOutputStream out = new ObjectOutputStream(fi);
out.writeObject(neList);
out.close();
}
}
catch (java.io.FileNotFoundException e) {
// that's OK, we probably haven't created it yet
}
catch (Throwable t) {
Toast
.makeText(this, "Exception: "+t.toString(), Toast.LENGTH_LONG)
.show();
}
}
/**
* #return
*/
public ArrayList<String> getKeywords(){
try {
InputStream fi = openFileInput(KEYWORDS);
if (fi!=null) {
ObjectInputStream in = new ObjectInputStream(fi);
keyWordList = (ArrayList<String>) in.readObject();
in.close();
}
}
catch (java.io.FileNotFoundException e) {
// that's OK, we probably haven't created it yet
}
catch (Throwable t) {
Toast
.makeText(this, "Exception: "+t.toString(), Toast.LENGTH_LONG)
.show();
}
if(keyWordList == null){
keyWordList = new ArrayList<String>();
return keyWordList;
}
return keyWordList;
}
public void onListItemClick(ListView parent, View v,
int position, long id) {
startFullNewsEvent(neList.get(position));
}
/**
* #param newsEvent
*/
public void startFullNewsEvent(NewsEvent ne) {
Intent intent = new Intent(this, FullNewsEvent.class);
intent.putExtra("ne", ne);
this.startActivity(intent);
finish();
}
private Handler handler = new Handler(){
#Override
public void handleMessage(Message msg) {
String page = msg.getData().getString("page");
try {
JSONArray parseArray = new JSONArray(page);
for (int i = 0; i < parseArray.length(); i++) {
JSONObject jo = parseArray.getJSONObject(i);
String title = jo.getString("title");
String body =jo.getString("body");
String pd = jo.getString("postDate");
String id = jo.getString("id");
NewsEvent ne = new NewsEvent(title, pd , body, id);
boolean unique = true;
for(NewsEvent ne0 : neList){
if(ne.getId().equals(ne0.getId())){
unique = false;
}else{
unique = true;
}
}
if(unique == true){
neList.add(ne);
}
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ne.setListAdapter(new IconicAdapter());
}
};
public class IconicAdapter extends ArrayAdapter<NewsEvent> {
IconicAdapter() {
super(NewsEvents.this, R.layout.rownews, neList);
}
public View getView(int position, View convertView,ViewGroup parent) {
LayoutInflater inflater=getLayoutInflater();
View row=inflater.inflate(R.layout.rownews, parent, false);
TextView label=(TextView)row.findViewById(R.id.label);
ImageView image= (ImageView)row.findViewById(R.id.icon);
String body = neList.get(position).getBody();
body.replaceAll("\\<.*?>", "");
String title = neList.get(position).getTitle();
for(String s : keyWordList){
if(body.contains(s) || body.contains(s.toLowerCase()) ||
title.contains(s) || title.contains(s.toLowerCase())){
neList.get(position).setInterested(true);
}
}
if(neList.get(position).isInterested() == true){
image.setImageResource(R.drawable.star);
}
label.setText(neList.get(position).getTitle());
return(row);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
populateMenu(menu);
return(super.onCreateOptionsMenu(menu));
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
return(applyMenuChoice(item) || super.onOptionsItemSelected(item));
}
//Creates our activity to menus
private void populateMenu(Menu menu) {
menu.add(Menu.NONE, ONE_ID, Menu.NONE, "Home");
}
private boolean applyMenuChoice(MenuItem item) {
switch (item.getItemId()) {
case ONE_ID: startHome(); return(true);
}
return(false);
}
public void startHome() {
Intent intent = new Intent(this, ECS.class);
this.startActivity(intent);
finish();
}
}
Race conditions, I'm making an HTTP Request and then handing it off to a handler, immediately following that I iterator through the array list, which at full speed is empty because the HTTP hasn't completed. In debugging it all slows down so the HTTP is complete and all works well.
Threads and Network Connections, a deadly combination.