I am trying to write a app which scans for beacons,
when I login to the app, it starts scanning but after some seconds it just crashes. if I turn off my bluetooth it works fine. this is the error I get:
Process: com.noxel.apppaneladmintry2, PID: 11192
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.example.niloofar.showroom.BeaconsFragment.onScannerClosed()' on a null object reference
at com.example.niloofar.showroom.BeaconScannerFragment.onCancel(BeaconScannerFragment.java:56)
at android.app.Dialog$ListenersHandler.handleMessage(Dialog.java:1260)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5257)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:921)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:716)
and this is my code,
package com.example.niloofar.showroom;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothManager;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AlertDialog;
import android.util.Log;
import android.view.View;
import android.support.design.widget.NavigationView;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import java.util.UUID;
import no.nordicsemi.android.beacon.Beacon;
import no.nordicsemi.android.beacon.BeaconRegion;
import no.nordicsemi.android.beacon.BeaconServiceConnection;
import no.nordicsemi.android.beacon.Proximity;
import no.nordicsemi.android.beacon.ServiceProxy;
public class drawermenu extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener, BeaconServiceConnection.BeaconsListener, BeaconServiceConnection.RegionListener {
public ProfileFragment profileFragment;
private static final String SCANNER_FRAGMENT = "scannerFragment";
public static final String NRF_BEACON_SERVICE_URL = "market://details?id=no.nordicsemi.android.beacon.service";
public static final String OPENED_FROM_LAUNCHER = "no.nordicsemi.android.nrfbeacon.extra.opened_from_launcher";
public static final String EXTRA_OPEN_DFU = "no.nordicsemi.android.nrfbeacon.extra.open_dfu";
public static final int BEACON_COMPANY_ID = 0x0059;
private static final int REQUEST_ENABLE_BT = 1;
private boolean mServiceConnected;
private boolean mFragmentResumed;
private DatabaseHelper mDatabaseHelper;
private BeaconAdapter mAdapter;
private BeaconScannerFragment mScannerFragment;
int minor;
public Fragment fragment=null;
public FragmentA fragmentA;
#Override
protected void onCreate(Bundle savedInstanceState) {
try {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
// Device does not support Bluetooth
Toast.makeText(this, "Device dows not support Bluetooth", Toast.LENGTH_LONG);
} else {
if (!mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
}
mDatabaseHelper = new DatabaseHelper(this);
getSupportActionBar().setElevation(0);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
}catch (Exception ex) {
Log.d("ERROR", ex.getMessage());
}
}
#Override
public void onStart() {
super.onStart();
// final Cursor cursor = mDatabaseHelper.getAllRegions();
bindService();
}
#Override
public void onResume() {
super.onResume();
// startScanning();
if (mFragmentResumed)
return;
mFragmentResumed = true;
// bindService();
onAddOrEditRegion();
}
#Override
public void onPause() {
super.onPause();
// stopScanning();
if (!mFragmentResumed)
return;
mFragmentResumed = false;
unbindService();
}
private BeaconServiceConnection mServiceConnection = new BeaconServiceConnection() {
#Override
public void onServiceConnected() {
try {
mServiceConnected = true;
final BeaconScannerFragment scannerFragment = mScannerFragment;
if (scannerFragment != null) {
startRangingBeaconsInRegion(BEACON_COMPANY_ID, BeaconRegion.ANY_UUID, scannerFragment);
} else {
// final FragmentManager fm = getChildFragmentManager();
// if (fm.getBackStackEntryCount() == 0) {
// Start scan only if there is no any other fragment (Mona Lisa) open
startScanning();
// }
}
} catch (Exception ex) {
Log.d("ERROR", ex.getMessage());
}
}
#Override
public void onServiceDisconnected() {
try {
mServiceConnected = false;
} catch (Exception ex) {
Log.e("ERROR", ex.getMessage());
}
}
};
public void onAddOrEditRegion() {
// if (!ensurePermission())
// return;
try {
stopScanning();
// mScannerFragment=null;
final BeaconScannerFragment fragment = mScannerFragment = new BeaconScannerFragment();
fragment.show(getSupportFragmentManager(), SCANNER_FRAGMENT);
// fragment.isHidden();
mServiceConnection.startRangingBeaconsInRegion(BEACON_COMPANY_ID, BeaconRegion.ANY_UUID, fragment);
}
catch (Exception ex) {
Log.e("ERROR", ex.getMessage());
}
}
public void startScanning() {
try {
if (mServiceConnected) {
startScanning(mServiceConnection);
}
} catch (Exception ex) {
Log.e("ERROR", ex.getMessage());
}
}
public void stopScanning() {
try {
if (mServiceConnected) {
stopScanning(mServiceConnection);
}
} catch (Exception ex) {
Log.e("ERROR", ex.getMessage());
}
}
private void bindService() {
// if (!ensurePermission())
// return;
try {
final boolean success = ServiceProxy.bindService(this, mServiceConnection);
if (!success) {
new AlertDialog.Builder(this).setTitle(R.string.service_required_title).setMessage(R.string.service_required_message)
.setPositiveButton(R.string.service_required_store, new DialogInterface.OnClickListener() {
#Override
public void onClick(final DialogInterface dialog, final int which) {
final Intent playIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(MainActivity.NRF_BEACON_SERVICE_URL));
startActivity(playIntent);
}
}).setOnCancelListener(new DialogInterface.OnCancelListener() {
#Override
public void onCancel(final DialogInterface dialog) {
dialog.dismiss();
finish();
}
}).show();
}
} catch (Exception ex) {
Log.e("ERROR", ex.getMessage());
}
}
private void unbindService() {
try {
if (mServiceConnected) {
// Unbinding service will stop all active scanning listeners
ServiceProxy.unbindService(this, mServiceConnection);
mDatabaseHelper.resetSignalStrength();
}
} catch (Exception ex) {
Log.e("ERROR", ex.getMessage());
}
}
public void startScanning(final BeaconServiceConnection serviceConnection) {
try {
final Cursor cursor = mDatabaseHelper.getAllRegions();
while (cursor.moveToNext()) {
final UUID uuid = UUID.fromString(cursor.getString(2 /* UUID */));
final int major = cursor.getInt(3 /* MAJOR */);
final int minor = cursor.getInt(4 /* MINOR */);
final int event = cursor.getInt(6 /* EVENT */);
// We must start ranging for all beacons
serviceConnection.startRangingBeaconsInRegion(BEACON_COMPANY_ID, uuid, major, minor, this);
// And additionally start monitoring only for those with these two events set
if (event == BeaconContract.EVENT_IN_RANGE || event == BeaconContract.EVENT_OUT_OF_RANGE)
serviceConnection.startMonitoringForRegion(BEACON_COMPANY_ID, uuid, major, minor, this);
}
} catch (Exception ex) {
Log.e("ERROR", ex.getMessage());
}
}
public void stopScanning(final BeaconServiceConnection serviceConnection) {
try {
if (serviceConnection != null) {
serviceConnection.stopMonitoringForRegion(this);
serviceConnection.stopRangingBeaconsInRegion(this);
}
} catch (Exception ex) {
Log.e("ERROR", ex.getMessage());
}
}
#Override
public void onBeaconsInRegion(final Beacon[] beacons, final BeaconRegion region) {
try {
if (beacons.length > 0) {
final Cursor cursor = mDatabaseHelper.findRegion(region);
try {
if (cursor.moveToNext()) {
// Check and fire events
final int event = cursor.getInt(6 /* EVENT */);
for (final Beacon beacon : beacons) {
if (event == BeaconContract.EVENT_ON_TOUCH && Proximity.IMMEDIATE.equals(beacon.getProximity()) && Proximity.NEAR.equals(beacon.getPreviousProximity())) {
fireEvent(cursor);
break;
}
if (event == BeaconContract.EVENT_GET_NEAR && Proximity.NEAR.equals(beacon.getProximity()) && Proximity.FAR.equals(beacon.getPreviousProximity())) {
fireEvent(cursor);
break;
}
}
// Update signal strength in the database
float accuracy = 5;
for (final Beacon beacon : beacons)
if (Proximity.UNKNOWN != beacon.getProximity() && beacon.getAccuracy() < accuracy)
accuracy = beacon.getAccuracy();
accuracy = -20 * accuracy + 100;
mDatabaseHelper.updateRegionSignalStrength(cursor.getLong(0 /* _ID */), (int) accuracy);
}
} finally {
cursor.close();
}
mAdapter.swapCursor(mDatabaseHelper.getAllRegions());
}
} catch (Exception ex) {
Log.e("ERROR", ex.getMessage());
}
}
#Override
public void onEnterRegion(final BeaconRegion region) {
try {
final Cursor cursor = mDatabaseHelper.findRegion(region);
try {
if (cursor.moveToNext()) {
final int event = cursor.getInt(6 /* EVENT */);
if (event == BeaconContract.EVENT_IN_RANGE) {
fireEvent(cursor);
}
}
} finally {
cursor.close();
}
} catch (Exception ex) {
Log.e("ERROR", ex.getMessage());
}
}
#Override
public void onExitRegion(final BeaconRegion region) {
try {
final Cursor cursor = mDatabaseHelper.findRegion(region);
try {
if (cursor.moveToNext()) {
final int event = cursor.getInt(6 /* EVENT */);
if (event == BeaconContract.EVENT_OUT_OF_RANGE) {
fireEvent(cursor);
}
}
} finally {
cursor.close();
}
} catch (Exception ex) {
Log.e("ERROR", ex.getMessage());
}
}
private void fireEvent(final Cursor cursor) {
try {
final boolean enabled = cursor.getInt(9 /* ENABLED */) == 1;
if (!enabled)
return;
final int action = cursor.getInt(7 /* ACTION */);
final String actionParam = cursor.getString(8 /* ACTION PARAM */);
switch (action) {
case BeaconContract.ACTION_MONA_LISA: {
stopScanning();
// final DialogFragment dialog = new MonalisaFragment();
// dialog.show(mParentFragment.getChildFragmentManager(), "JIRNG");
break;
}
case BeaconContract.ACTION_SILENT: {
stopScanning();
// final DialogFragment dialog = new tarh();
// dialog.show(mParentFragment.getChildFragmentManager(), "JIRING");
break;
}
case BeaconContract.ACTION_ALARM: {
stopScanning();
// final DialogFragment dialog = new rest();
// dialog.show(mParentFragment.getChildFragmentManager(), "Jiring");
break;
}
case BeaconContract.ACTION_URL: {
stopScanning();
try {
final Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(actionParam));
startActivity(intent);
} catch (final ActivityNotFoundException e) {
Toast.makeText(this, R.string.no_application, Toast.LENGTH_SHORT).show();
}
break;
}
case BeaconContract.ACTION_APP: {
stopScanning();
try {
final Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setPackage(actionParam);
startActivity(intent);
} catch (final ActivityNotFoundException e) {
Toast.makeText(this, R.string.no_given_application, Toast.LENGTH_SHORT).show();
}
break;
}
case BeaconContract.ACTION_TASKER:
// switch (TaskerIntent.testStatus(getActivity())) {
// case OK:
// final TaskerIntent i = new TaskerIntent(actionParam);
final BroadcastReceiver br = new BroadcastReceiver() {
#Override
public void onReceive(final Context context, final Intent recIntent) {
// if (recIntent.getBooleanExtra(TaskerIntent.EXTRA_SUCCESS_FLAG, false))
Toast.makeText(drawermenu.this, R.string.tasker_success, Toast.LENGTH_SHORT).show();
drawermenu.this.unregisterReceiver(this);
}
};
// getActivity().registerReceiver(br, i.getCompletionFilter());
// Start the task
// getActivity().sendBroadcast(i);
break;
// case NotEnabled:
// Toast.makeText(getActivity(), R.string.tasker_disabled, Toast.LENGTH_SHORT).show();
// break;
// case AccessBlocked:
// Toast.makeText(getActivity(), R.string.tasker_external_access_denided, Toast.LENGTH_SHORT).show();
// break;
// case NotInstalled:
// Toast.makeText(getActivity(), R.string.tasker_not_installed, Toast.LENGTH_SHORT).show();
// break;
default:
Toast.makeText(this, R.string.tasker_error, Toast.LENGTH_SHORT).show();
break;
}
// break;
} catch (Exception ex) {
Log.e("ERROR", ex.getMessage());
}
}
public void onEditRegion(final long id) {
// final Intent intent = new Intent(this, BeaconsDetailsActivity.class);
// intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
// intent.putExtra(BeaconsDetailsActivity.ID, id);
// startActivity(intent);
}
public void onScannerClosedWithResult(final Beacon beacon) {
try {
mServiceConnection.stopRangingBeaconsInRegion(mScannerFragment);
mScannerFragment.dismiss();
mScannerFragment = null;
// final Cursor cursor = mDatabaseHelper.findRegionByBeacon(beacon);
minor = beacon.getMinor();
Intent intenta = new Intent(drawermenu.this, FragmentA.class);
switch (minor) {
case 99:
// startActivity(intenta);
popUp();
break;
case 246:
// startActivity(intenta);
// Toast.makeText(MainActivity.this, "246", Toast.LENGTH_LONG).show();
popUp();
break;
case 63:
popUp();
break;
case 104:
popUp();
break;
}
}
catch (Exception ex)
{
Log.e("ERROR", ex.getMessage());
}
}
private void popUp()
{
new Handler().post(new Runnable() {
#Override
public void run() {
/* Create an Intent that will start the Menu-Activity. */
Intent mainIntent = new Intent(drawermenu.this,FragmentA.class);
// mainIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
mainIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
drawermenu.this.startActivity(mainIntent);
// Splash.this.finish();
}
});
}
public void onScannerClosed() {
try {
mServiceConnection.stopRangingBeaconsInRegion(mScannerFragment);
mScannerFragment = null;
startScanning();
} catch (Exception ex) {
Log.e("ERROR", ex.getMessage());
}
}
public DatabaseHelper getDatabaseHelper() {
return mDatabaseHelper;
}
private boolean ensureBleExists() {
try {
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(this, R.string.no_ble, Toast.LENGTH_LONG).show();
return false;
}
return true;
} catch (Exception ex) {
Log.e("ERROR", ex.getMessage());
return false;
}
}
private boolean isBleEnabled() {
try {
final BluetoothManager bm = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
final BluetoothAdapter ba = bm.getAdapter();
return ba != null && ba.isEnabled();
} catch (Exception ex) {
Log.e("ERROR", ex.getMessage());
return false;
}
}
private void enableBle() {
try {
final Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
} catch (Exception ex) {
Log.e("ERROR", ex.getMessage());
}
}
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
if (id == R.id.nav_home) {
// Handle the camera action
fragment = new ProfileFragment();
} else if (id == R.id.nav_points) {
fragment = new PointFragment();
} else if (id == R.id.nav_coupons) {
fragment = new CouponFragment();
} else if (id == R.id.nav_about) {
fragment = new AboutFragment();
}
fragmentTransaction.replace(R.id.appbar, fragment,fragment.getClass().getSimpleName());
fragmentTransaction.commit();
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
}
and this is the code which error is referring to:
package com.example.niloofar.showroom;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
import no.nordicsemi.android.beacon.Beacon;
import no.nordicsemi.android.beacon.BeaconRegion;
import no.nordicsemi.android.beacon.BeaconServiceConnection;
import no.nordicsemi.android.beacon.Proximity;
/**
* Created by niloofar on 11/9/2016.
*/
public class BeaconScannerFragment extends DialogFragment implements BeaconServiceConnection.BeaconsListener {
// public class BeaconScannerFragment extends DialogFragment implements BeaconServiceConnection.BeaconsListener {
private boolean mCompleted;
#Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mCompleted = false;
}
#Override
public void onBeaconsInRegion(final Beacon[] beacons, final BeaconRegion region) {
if (!mCompleted) {
for (final Beacon beacon : beacons)
if (Proximity.IMMEDIATE == beacon.getProximity()) {
mCompleted = true;
final BeaconsFragment parentFragment = (BeaconsFragment) getParentFragment();
parentFragment.onScannerClosedWithResult(beacon);
dismiss();
break;
}
}
}
#NonNull
#Override
public Dialog onCreateDialog(final Bundle savedInstanceState) {
return new AlertDialog.Builder(getContext())
.setView(R.layout.fragment_scan).create();
}
#Override
public void onCancel(final DialogInterface dialog) {
super.onCancel(dialog);
final BeaconsFragment targetFragment = (BeaconsFragment) getParentFragment();
targetFragment.onScannerClosed();
}}
does anyone know how my problem will be solved?
This is the place where your problem occurs:
final BeaconsFragment parentFragment = (BeaconsFragment) getParentFragment();
parentFragment.onScannerClosedWithResult(beacon);
You initialize parentFragment, but the NullPointerException is thrown when you try to call onScannerClosedWithResult. This means that parentFragment is null. To solve this, you have three options. The first option is to use try-catch where you handle the NullPointerException. The second option is to make sure that getParentFragment will never return null. The third option is to fail gracefully when null is returned:
final BeaconsFragment parentFragment = (BeaconsFragment) getParentFragment();
if (parentFragment == null) {
parentFragment.onScannerClosedWithResult(beacon);
}
Related
I have tried using plugins available:
flutter_android
This includes:
Sensor
SensorEvent
SensorEventListener
SensorManager
usb_serial
So i need to talk to usb devices however the plugin usb_serial
does not meet my needs since i need to use more than the package provides.
Basically i either need to create my own plugin or i need to find a way to expose the native android.hardware.usb to flutter.
Need help i don't know what is best or how to do either.
This was a long time ago but will try to help as best as possible
Since I was not able to find anything that met my needs I needed to create my own plugin using these
import com.ftdi.j2xx.D2xxManager;
import com.ftdi.j2xx.FT_Device;
My MainActivity look like this
import android.app.ActivityManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.CountDownTimer;
import android.util.Log;
import android.widget.Toast;
import androidx.annotation.NonNull;
import com.ftdi.j2xx.D2xxManager;
import com.ftdi.j2xx.FT_Device;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugins.GeneratedPluginRegistrant;
public class MainActivity extends FlutterActivity {
private static final String TAG = "D2XX";
private static final String CHANNEL = "bridge";
private static final String EVENT_CHANNEL = "event";
private static final String INPUT_EVENT_CHANNEL = "input";
private D2xxManager m_deviceManager = null;
private FT_Device m_connectedDevice;
private CONTROLLER_ENUMS m_CONTROLLER_STATUS = CONTROLLER_ENUMS.Closed;
private int m_iDeviceCount = 0;
private List<D2xxManager.FtDeviceInfoListNode> mDeviceInfoListNode;
private CountDownTimer m_updateTimer;
private final String m_initialBitMask = "00111100";
private boolean m_input1State = false;
private boolean m_input2State = false;
private boolean m_output1State = false;
private boolean m_output2State = false;
private static boolean bRegisterBroadcast = true;
private long timeLeftInMilliseconds;
private boolean m_MountedState = false;
boolean isRunning = false;
private enum CONTROLLER_ENUMS {
OK,
Opened,
Closed,
Failed,
}
#Override
public void configureFlutterEngine(#NonNull FlutterEngine flutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine);
new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL)
.setMethodCallHandler((call, result) -> {
String strCallName = call.method.toUpperCase();
switch (strCallName) {
case "INITIALIZE": {
m_CONTROLLER_STATUS = CONTROLLER_ENUMS.OK;
boolean bConnected = Initialise();
result.success(bConnected);
}
break;
case "GETDEVICE": {
JSONObject retVal = GetDeviceList();
if (retVal != null) {
result.success(retVal.toString());
}
}
break;
case "CONNECTDEVICE": {
try {
String strSerialNumber = call.argument("SerialNumber");
if (m_connectedDevice == null) {
boolean bConnected = ConnectToDevice(strSerialNumber);
result.success(bConnected);
} else {
result.success(true);
}
} catch (Exception e) {
Log.e(TAG, "CONNECT TO DEVICE ANDROID EXC: ", e);
}
}
break;
case "SETOUTPUT": {
int output = (int) call.argument("outputNumber");
boolean state = (boolean) call.argument("state");
SetOutputs(output, state);
}
break;
case "GETINPUT": {
JSONObject retVal = CheckDeviceInputs();
if (retVal != null) {
result.success(retVal.toString());
}
}
break;
default:
break;
}
});
new EventChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), EVENT_CHANNEL).setStreamHandler(
new EventChannel.StreamHandler() {
private BroadcastReceiver usbStateChangeReceiver;
#Override
public void onListen(Object arguments, EventChannel.EventSink events) {
usbStateChangeReceiver = createUSBStateChangeReceiver(events);
IntentFilter filter = new IntentFilter();
filter.addAction("android.hardware.usb.action.USB_DEVICE_ATTACHED");
filter.addAction("android.hardware.usb.action.USB_DEVICE_DETACHED");
registerReceiver(
usbStateChangeReceiver, filter);
}
#Override
public void onCancel(Object arguments) {
unregisterReceiver(usbStateChangeReceiver);
usbStateChangeReceiver = null;
}
}
);
new EventChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), INPUT_EVENT_CHANNEL).setStreamHandler(
new EventChannel.StreamHandler() {
#Override
public void onListen(Object arguments, EventChannel.EventSink events) {
timeLeftInMilliseconds = 30000;
//timer is started when device is connected so tha android knows when to tell flutter button has
//been pressed
m_updateTimer = new CountDownTimer(timeLeftInMilliseconds, 100) {
public void onTick(long millisUntilFinished) {
isRunning = true;
JSONObject retVal = CheckDeviceInputs();
if (retVal != null) {
events.success(retVal.toString());
} else {
events.success(null);
}
}
public void onFinish() {
isRunning = false;
m_updateTimer.start();
}
}.start();
}
#Override
public void onCancel(Object arguments) {
//when event channel is closed we stop the timer then remove the method
if (m_updateTimer != null) {
isRunning = false;
m_updateTimer.cancel();
}
Log.w(TAG, "cancelling listener");
}
}
);
}
private BroadcastReceiver createUSBStateChangeReceiver(EventChannel.EventSink events) {
return new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//watches if the usb has been plugged in or not
String action = intent.getAction();
if ("android.hardware.usb.action.USB_DEVICE_DETACHED".equals(action)) {
Log.i(TAG, "Detached: ");
Toast.makeText(context, "Device detached",
Toast.LENGTH_LONG).show();
//if device usb plugs out cancel timer
m_connectedDevice = null;
events.success(false);
} else if ("android.hardware.usb.action.USB_DEVICE_ATTACHED".equals(action)) {
Log.i(TAG, "Attached:");
Toast.makeText(context, "Device attached",
Toast.LENGTH_LONG).show();
if (m_updateTimer != null) {
Log.e(TAG, "START THE TIMER: ");
m_updateTimer.start();
}
events.success(true);
}
}
};
}
// INITIALISE
private boolean Initialise() {
try {
m_deviceManager = D2xxManager.getInstance(this);
return m_deviceManager != null;
} catch (D2xxManager.D2xxException exc) {
Log.e(TAG, "Initialise: Failed to get instance");
return false;
}
}
// GET ALL CONNECTED DEVICES
private JSONObject GetDeviceList() {
// first check if the list is empty, then create the list based on what is plugged in
// for now only the first device will be connect
try {
m_iDeviceCount = m_deviceManager.createDeviceInfoList(this);
if (m_iDeviceCount == 0)
return null;
D2xxManager.FtDeviceInfoListNode firstItem = m_deviceManager.getDeviceInfoListDetail(0);
JSONObject returnData = new JSONObject();
try {
//create connected device info object to send to flutter
returnData.put("ID", firstItem.id);
returnData.put("Description", firstItem.description);
returnData.put("BCDDevice", firstItem.bcdDevice);
returnData.put("LineStatus", firstItem.lineStatus);
returnData.put("ModemStatus", firstItem.modemStatus);
returnData.put("Type", firstItem.type);
returnData.put("SerialNumber", firstItem.serialNumber);
return returnData;
} catch (JSONException e) {
e.printStackTrace();
Log.e(TAG, "GetDeviceList: Failed" + e);
return null;
}
} catch (Exception exc) {
Log.e(TAG, "GetDeviceList: Failed" + exc);
return null;
}
}
// CONNECT THE DEVICE
private boolean ConnectToDevice(String strSerialNumber) {
try {
m_connectedDevice = m_deviceManager.openBySerialNumber(this, strSerialNumber);
//m_initialBitMask
if (m_connectedDevice != null && m_connectedDevice.isOpen()) {
//printing the device details
Log.i(TAG, "ConnectToDevice: IsOpen : ");
Log.i(TAG, "ConnectToDevice: IsOpen : " + m_connectedDevice.getDeviceInfo().serialNumber);
Log.i(TAG, "ConnectToDevice: description : " + m_connectedDevice.getDeviceInfo().description);
Log.i(TAG, "ConnectToDevice: serialNumber : " + m_connectedDevice.getDeviceInfo().serialNumber);
Log.i(TAG, "ConnectToDevice: bcdDevice : " + String.valueOf(m_connectedDevice.getDeviceInfo().bcdDevice));
//setting bit mode
m_connectedDevice.setBitMode(Byte.parseByte(m_initialBitMask, 2), D2xxManager.FT_BITMODE_CBUS_BITBANG);
return true;
} else {
m_CONTROLLER_STATUS = CONTROLLER_ENUMS.Closed;
return false;
}
} catch (Exception exc) {
m_CONTROLLER_STATUS = CONTROLLER_ENUMS.Failed;
Log.e(TAG, "ConnectToDevice: Failed" + exc);
Log.i(TAG, "ConnectToDevice: IsNotOpen");
return false;
}
}
// SET OUTPUTS TO DEVICE
private void SetOutputs(int outputNumber, boolean bState) {
//if device is connected you can use this to activate relays
if (m_connectedDevice != null && m_connectedDevice.isOpen()) {
byte lByteMask = m_connectedDevice.getBitMode();
switch (outputNumber) {
//relay 1
case 1: {
if (bState) {
lByteMask |= 1;
} else {
lByteMask &= 0xFE;
}
}
break;
//relay 2
case 2: {
if (bState) {
lByteMask |= 2;
} else {
lByteMask &= 0xFD;
}
}
break;
}
//fire with new values
m_connectedDevice.setBitMode(lByteMask, D2xxManager.FT_BITMODE_CBUS_BITBANG);
}
}
// READ INTERRUPTS - Timer based
private JSONObject CheckDeviceInputs() {
JSONObject returnData = new JSONObject();
try {
if (m_connectedDevice != null && m_connectedDevice.isOpen()) {
byte inputBytes = m_connectedDevice.getBitMode();
boolean input1 = (inputBytes & 0x04) != 0x04;
boolean input2 = (inputBytes & 0x08) != 0x08;
if (input1) {
m_input1State = true;
}
if (input2) {
m_input2State = true;
}
//if input is true global will be set above then below if the local is
//not true anymore it will activate and deactivate the relays
if (!input1 && m_input1State) {
SetOutputs(2, true);
try {
//delay so relay light is seen
Thread.sleep(200);
SetOutputs(2, false);
} catch (InterruptedException ex) {
Log.e(TAG, "Set time out: ", ex);
}
m_input1State = false;
}
if (!input2 && m_input2State) {
SetOutputs(1, true);
try {
//delay so relay light is seen
Thread.sleep(200);
SetOutputs(1, false);
} catch (InterruptedException ex) {
Log.e(TAG, "Set time out: ", ex);
}
m_input2State = false;
}
returnData.put("Input1State", input1);
returnData.put("Input2State", input2);
return returnData;
} else {
return null;
}
} catch (JSONException e) {
e.printStackTrace();
Log.e(TAG, "Failed to get DeviceStatus: Failed" + e);
return null;
}
}
}
On my flutter side I create a banner that listens to the I/O
import 'dart:convert';
import 'package:covidqa/Controllers/DeviceController.dart';
import 'package:covidqa/Models/IRelayDevice.dart';
import 'package:covidqa/Models/Inputs.dart';
import 'package:covidqa/StateHandler/globals.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'dart:async';
import 'package:provider/provider.dart';
class BannerView extends StatefulWidget {
final Function(Inputs) returningInputs;
final Function(bool) connected;
BannerView(this.returningInputs, this.connected);
#override
BannerViewState createState() {
return BannerViewState();
}
}
class BannerViewState extends State<BannerView> {
DeviceController deviceController = new DeviceController();
EventChannel eventChannel = const EventChannel('event');
EventChannel inputEventChannel = const EventChannel('input');
bool init;
IRelayDevice device;
Inputs inputs;
String error;
bool hasDevice = false;
Globals globals;
bool connected = false;
bool inputState1 = false;
bool inputState2 = false;
bool outputState1 = false;
bool outputState2 = false;
_init() {
deviceController.init().then((value) {
if (value == true) {
getDevice();
}
});
}
Future<void> getDevice() async {
if (!mounted) {
return;
}
deviceController.getDevice().then((data) => setState(() {
device = data;
connectDevice();
}));
}
Future connectDevice() async {
if (!mounted) {
return;
}
if (device != null) {
deviceController.connectDevice(device).then((data) => setState(() {
widget.connected(data);
connected = data;
if (data) {
inputEventChannel
.receiveBroadcastStream()
.listen(_onInput, onError: deviceController.onError);
}
}));
} else {
getDevice();
}
}
#override
void initState() {
super.initState();
_init();
eventChannel
.receiveBroadcastStream()
.listen(_onEvent, onError: deviceController.onError);
}
void _onEvent(Object event) {
if (!mounted) {
widget.connected(false);
device = null;
connected = false;
return;
}
setState(() {
hasDevice = event;
if (!hasDevice) {
device = null;
connected = false;
widget.connected(false);
} else {
connectDevice();
}
});
}
void _onInput(Object event) {
try {
if (!mounted) {
return;
}
if (event == null) {
print("Result is null");
return;
}
Map bodyResult = jsonDecode(event);
inputs = Inputs.fromJson(bodyResult);
widget.returningInputs(inputs);
} on PlatformException catch (e) {
print("exception" + e.toString());
}
}
#override
Widget build(BuildContext context) {
globals = Provider.of<Globals>(context);
return Container(
color: connected ? Colors.green : Colors.red,
height: MediaQuery.of(context).size.height * 0.01,
);
}
}
Again this was long ago and cant remember much and the code is not the most tidy but this is the just of it good luck
I am trying to create an Android activity which sends data through the serial port as a product test. I have some code for doing so, which, so far, finds no serial ports on my device which definitely has a serial port. I intend to use this activity with a loopback connector on the serial port of the device to verify both the read and write functionalities. I have tried these two programs:
import android.app.Activity;
import com.symbol.emdk.EMDKManager;
import com.symbol.emdk.EMDKManager.EMDKListener;
import com.symbol.emdk.EMDKManager.FEATURE_TYPE;
import com.symbol.emdk.EMDKResults;
import com.symbol.emdk.serialcomm.SerialComm;
import com.symbol.emdk.serialcomm.SerialCommException;
import com.symbol.emdk.serialcomm.SerialCommManager;
import com.symbol.emdk.serialcomm.SerialCommResults;
import com.symbol.emdk.serialcomm.SerialPortInfo;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import java.util.HashMap;
import java.util.List;
public class SerialTry3 extends Activity implements EMDKListener{
private String TAG = SerialTry3.class.getSimpleName();
private EMDKManager emdkManager = null;
private SerialComm serialCommPort = null;
private SerialCommManager serialCommManager = null;
private EditText txtDataToSend = null;
private TextView txtStatus = null;
private Button btnRead = null;
private Button btnWrite = null;
private Spinner spinnerPorts = null;
public HashMap<String, SerialPortInfo> supportedPorts = null;
#Override #SuppressWarnings("SetTextI18n")
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.serial_try);
txtDataToSend = (EditText) findViewById(R.id.txtDataToSend);
txtDataToSend.setText("Serial Communication Write Data Testing.");
spinnerPorts = (Spinner)findViewById(R.id.spinnerPorts);
btnWrite = (Button) findViewById(R.id.btnWrite);
btnRead = (Button) findViewById(R.id.btnRead);
txtStatus = (TextView) findViewById(R.id.statusView);
txtStatus.setText("");
txtStatus.requestFocus();
EMDKResults results = EMDKManager.getEMDKManager(getApplicationContext(), this);
if (results.statusCode != EMDKResults.STATUS_CODE.SUCCESS) {
new AsyncStatusUpdate().execute("EMDKManager object request failed!");
}
new AsyncUiControlUpdate().execute(false);
}
#Override
public void onOpened(EMDKManager emdkManager) {
this.emdkManager = emdkManager;
Log.d(TAG, "EMDK opened");
try{
serialCommManager = (SerialCommManager) this.emdkManager.getInstance(FEATURE_TYPE.SERIALCOMM_EX);
if(serialCommManager != null) {
populatePorts();
}
else
{
new AsyncStatusUpdate().execute(FEATURE_TYPE.SERIALCOMM_EX.toString() + " Feature not supported.");
}
}
catch(Exception e)
{
Log.d(TAG, e.getMessage());
new AsyncStatusUpdate().execute(e.getMessage());
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.splash_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onDestroy() {
super.onDestroy();
deinitSerialComm();
if (emdkManager != null) {
emdkManager.release();
emdkManager = null;
}
}
#Override
protected void onPause()
{
super.onPause();
deinitSerialComm();
serialCommManager = null;
supportedPorts = null;
// Release the serialComm manager resources
if (emdkManager != null) {
emdkManager.release(FEATURE_TYPE.SERIALCOMM_EX);
}
}
#Override
protected void onResume()
{
super.onResume();
// Acquire the serialComm manager resources
if (emdkManager != null) {
serialCommManager = (SerialCommManager) emdkManager.getInstance(FEATURE_TYPE.SERIALCOMM_EX);
if (serialCommManager != null) {
populatePorts();
if (supportedPorts != null)
initSerialComm();
}
}
}
void populatePorts()
{
try {
if(serialCommManager != null) {
List<SerialPortInfo> serialPorts = serialCommManager.getSupportedPorts();
if(serialPorts.size()>0) {
supportedPorts = new HashMap<String, SerialPortInfo> ();
String[] ports = new String[serialPorts.size()];
int count = 0;
for (SerialPortInfo info : serialPorts) {
supportedPorts.put(info.getFriendlyName(), info);
ports[count] = info.getFriendlyName();
count++;
}
spinnerPorts.setAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_dropdown_item, ports));
spinnerPorts.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
//Disabling previous serial port before getting the new one
deinitSerialComm();
initSerialComm();
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
}
else
{
new AsyncStatusUpdate().execute("Failed to get available ports");
Toast.makeText(this, "Failed to get available ports, serial communication may not be supported.", Toast.LENGTH_LONG).show();
finish();
}
}
else
{
new AsyncStatusUpdate().execute("SerialCommManager is null");
}
}
catch (Exception ex)
{
Log.d(TAG, ex.getMessage());
new AsyncStatusUpdate().execute(ex.getMessage());
}
}
void initSerialComm() {
new AsyncEnableSerialComm().execute(supportedPorts.get(spinnerPorts.getSelectedItem()));
}
#Override
public void onClosed() {
if(emdkManager != null) {
emdkManager.release();
}
new AsyncStatusUpdate().execute("EMDK closed unexpectedly! Please close and restart the application.");
}
public void btnReadOnClick(View arg)
{
new AsyncReadData().execute();
}
public void btnWriteOnClick(View arg)
{
new AsyncUiControlUpdate().execute(false);
try {
String writeData = txtDataToSend.getText().toString();
int bytesWritten = serialCommPort.write(writeData.getBytes(), writeData.getBytes().length);
new AsyncStatusUpdate().execute("Bytes written: "+ bytesWritten);
} catch (SerialCommException e) {
new AsyncStatusUpdate().execute("write: "+ e.getResult().getDescription());
}
catch (Exception e) {
new AsyncStatusUpdate().execute("write: "+ e.getMessage() + "\n");
}
new AsyncUiControlUpdate().execute(true);
}
void deinitSerialComm() {
if (serialCommPort != null) {
try {
serialCommPort.disable();
serialCommPort = null;
} catch (Exception ex) {
Log.d(TAG, "deinitSerialComm disable Exception: " + ex.getMessage());
}
}
}
#SuppressWarnings("StaticFieldLeak")
private class AsyncStatusUpdate extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
return params[0];
}
#Override
protected void onPostExecute(String result) {
txtStatus.setText(result);
}
}
#SuppressWarnings("StaticFieldLeak")
private class AsyncUiControlUpdate extends AsyncTask<Boolean, Void, Boolean> {
#Override
protected Boolean doInBackground(Boolean... arg0) {
return arg0[0];
}
#Override
protected void onPostExecute(Boolean bEnable) {
btnRead.setEnabled(bEnable);
btnWrite.setEnabled(bEnable);
txtDataToSend.setEnabled(bEnable);
spinnerPorts.setEnabled(bEnable);
}
}
#SuppressWarnings("StaticFieldLeak")
private class AsyncEnableSerialComm extends AsyncTask<SerialPortInfo, Void, SerialCommResults>
{
#Override
protected SerialCommResults doInBackground(SerialPortInfo... params) {
SerialCommResults returnvar = SerialCommResults.FAILURE;
try {
serialCommPort = serialCommManager.getPort(params[0]);
} catch (Exception ex) {
ex.printStackTrace();
}
if (serialCommPort != null) {
try {
serialCommPort.enable();
returnvar = SerialCommResults.SUCCESS;
} catch (SerialCommException e) {
Log.d(TAG, e.getMessage());
e.printStackTrace();
returnvar = e.getResult();
}
}
return returnvar;
}
#Override #SuppressWarnings("SetTextI18n")
protected void onPostExecute(SerialCommResults result) {
super.onPostExecute(result);
if (result == SerialCommResults.SUCCESS) {
new AsyncStatusUpdate().execute("Serial comm channel enabled: (" + spinnerPorts.getSelectedItem().toString() + ")");
txtDataToSend.setText("Serial Communication Write Data Testing " + spinnerPorts.getSelectedItem().toString() + ".");
new AsyncUiControlUpdate().execute(true);
} else {
new AsyncStatusUpdate().execute(result.getDescription());
new AsyncUiControlUpdate().execute(false);
}
}
}
#SuppressWarnings("StaticFieldLeak")
private class AsyncReadData extends AsyncTask<Void, Void, String>
{
#Override
protected void onPreExecute() {
super.onPreExecute();
new AsyncUiControlUpdate().execute(false);
new AsyncStatusUpdate().execute("Reading..");
}
#Override
protected String doInBackground(Void... params) {
String statusText = "";
try {
byte[] readBuffer = serialCommPort.read(10000); //Timeout after 10 seconds
if (readBuffer != null) {
String tempString = new String(readBuffer);
statusText = "Data Read:\n" + tempString;
} else {
statusText = "No Data Available";
}
} catch (SerialCommException e) {
statusText = "read:" + e.getResult().getDescription();
} catch (Exception e) {
statusText = "read:" + e.getMessage();
}
return statusText;
}
#Override
protected void onPostExecute(String statusText) {
super.onPostExecute(statusText);
new AsyncUiControlUpdate().execute(true);
new AsyncStatusUpdate().execute(statusText);
}
}
}
and
import android.app.Activity;
import com.symbol.emdk.EMDKManager;
import com.symbol.emdk.EMDKManager.FEATURE_TYPE;
import com.symbol.emdk.EMDKResults;
import com.symbol.emdk.serialcomm.SerialComm;
import com.symbol.emdk.serialcomm.SerialCommException;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import com.symbol.emdk.serialcomm.SerialCommManager;
import com.symbol.emdk.serialcomm.SerialPortInfo;
import java.util.List;
public class SerialTry extends Activity implements EMDKManager.EMDKListener {
private String TAG = SerialTry.class.getSimpleName();
private EMDKManager emdkManager = null;
private SerialComm serialComm = null;
private SerialCommManager serialCommMan = null;
private EditText editText = null;
private TextView statusView = null;
private Button readButton = null;
private Button writeButton = null;
#Override #SuppressWarnings("SetTextI18n")
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.serial_try);
editText = (EditText) findViewById(R.id.editText1);
editText.setText("Serial Communication Write Data Testing.");
statusView = (TextView) findViewById(R.id.statusView);
statusView.setText("");
statusView.requestFocus();
EMDKResults results = EMDKManager.getEMDKManager(getApplicationContext(), this);
if (results.statusCode != EMDKResults.STATUS_CODE.SUCCESS) {
statusView.setText("Failed to open EMDK");
} else {
statusView.setText("Opening EMDK...");
}
//
// Get the serialComm/port object by passing a SerialPortInfo object:
addReadButtonEvents();
writeButtonEvents();
setEnabled(false);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.splash_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onDestroy() {
super.onDestroy();
if (emdkManager != null) {
emdkManager.release();
emdkManager = null;
}
}
#Override
public void onOpened(EMDKManager emdkManager) {
this.emdkManager = emdkManager;
Log.d(TAG, "EMDK opened");
try{
serialCommMan = (SerialCommManager) this.emdkManager.getInstance(EMDKManager.FEATURE_TYPE.SERIALCOMM_EX);
List<SerialPortInfo> serialPorts = serialCommMan.getSupportedPorts();
serialComm = serialCommMan.getPort(serialPorts.get(0));
System.out.println("Supported Ports::::::" + serialPorts);
Thread readThread = new Thread(new Runnable() {
#Override
public void run() {
String statusText;
if (serialComm != null) {
try{
serialComm.enable();
statusText = "Serial comm channel enabled";
setEnabled(true);
} catch(SerialCommException e){
Log.d(TAG, e.getMessage());
e.printStackTrace();
statusText = e.getMessage();
setEnabled(false);
}
} else {
statusText = FEATURE_TYPE.SERIALCOMM_EX.toString() + " Feature not supported or initilization error.";
setEnabled(false);
}
displayMessage(statusText);
}
});
readThread.start();
}
catch(Exception e)
{
Log.d(TAG, e.getMessage());
e.printStackTrace();
displayMessage(e.getMessage());
}
}
#Override
public void onClosed() {
if(emdkManager != null) {
emdkManager.release();
}
displayMessage("EMDK closed abruptly.");
}
private void addReadButtonEvents() {
readButton = (Button) findViewById(R.id.btnRead);
readButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Thread readThread = new Thread(new Runnable() {
#Override
public void run() {
setEnabled(false);
String statusText;
try {
byte[] readBuffer = serialComm.read(10000); //Timeout after 10 seconds
if(readBuffer != null) {
String tempString = new String(readBuffer);
statusText = "Data Read:\n" + tempString;
} else {
statusText = "No Data Available";
}
}catch (SerialCommException e) {
statusText ="read:"+ e.getResult().getDescription();
e.printStackTrace();
}
catch (Exception e) {
statusText = "read:"+ e.getMessage();
e.printStackTrace();
}
setEnabled(true);
displayMessage(statusText);
}
});
readThread.start();
}
});
}
#SuppressWarnings("SetTextI18n")
private void writeButtonEvents() {
writeButton = (Button) findViewById(R.id.btnWrite);
writeButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
setEnabled(false);
try {
String writeData = editText.getText().toString();
int bytesWritten = serialComm.write(writeData.getBytes(), writeData.getBytes().length);
statusView.setText("Bytes written: "+ bytesWritten);
} catch (SerialCommException e) {
statusView.setText("write: "+ e.getResult().getDescription());
}
catch (Exception e) {
statusView.setText("write: "+ e.getMessage() + "\n");
}
setEnabled(true);
}
});
}
#SuppressWarnings("SetTextI18n")
void displayMessage(String message) {
final String tempMessage = message;
runOnUiThread(new Runnable() {
public void run() {
statusView.setText(tempMessage + "\n");
}
});
}
void setEnabled(boolean enableState) {
final boolean tempState = enableState;
runOnUiThread(new Runnable() {
public void run() {
readButton.setEnabled(tempState);
writeButton.setEnabled(tempState);
editText.setEnabled(tempState);
}
});
}
}
Does the problem seem to be with my code or is there something I am not understanding about the device itself? Any help would be appreciated. Thank you for your time.
I am implementing a simple app that sends and receives data between two devices via bluetooth.
I am following the android developer's blog's bluetoothchat example, but my application seems unable to read from the inputstream of a socket.
Writing to the socket is fine. The app does not throw an error nor update the textview as it is supposed to. Any help would be appreciated. Thank you!
Main activity.java(where list of devices are shown and selected) - probably not the errored file:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.bluetooth.*;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Set;
import java.util.UUID;
public class MainActivity extends ActionBarActivity {
private final static int REQUEST_ENABLE_BT = 22;
private static final UUID MY_UUID = UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");
private static final String NAME = "Bluetooth!";
ListView listView;
ArrayList<BluetoothDevice> deviceList;
ArrayAdapter<String> arrayAdapter;
ScanReciever reciever;
BluetoothAdapter bluetooth_adapter;
Button onButton;
Button scanButton;
Button alreadyButton;
AcceptThread acceptThread;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
deviceList = new ArrayList<>();
//arrayAdapter = new ArrayAdapter<>(this, R.xml.table_item, android.R.id.text1, deviceList);
arrayAdapter = new ArrayAdapter<String>(this, R.layout.table_item);
// Set up Buttons
onButton = (Button) findViewById(R.id.onButton);
scanButton = (Button) findViewById(R.id.scanButton);
onButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
askAdapterOn();
}
});
scanButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
scanForDevices();
}
});
// Set up listview
listView = (ListView) findViewById(R.id.listView);
listView.setAdapter(arrayAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View v, int position, long id) {
callButtons(deviceList.get(position));
}
});
// Bluetooth setup.
bluetooth_adapter = BluetoothAdapter.getDefaultAdapter();
// If device is incapable of using bluetooth:
if (bluetooth_adapter == null) {
onButton.setEnabled(false);
scanButton.setEnabled(false);
}
else if (!bluetooth_adapter.isEnabled()) { // If bluetooth is off:
//Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
//startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
onButton.setEnabled(true);
scanButton.setEnabled(false);
}
else { // Bluetooth is on and ready:
onButton.setEnabled(false);
scanButton.setEnabled(true);
alreadyButton = (Button) findViewById(R.id.alreadyButton);
alreadyButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Collect current devices into a set.
Set<BluetoothDevice> pairedDevices = bluetooth_adapter.getBondedDevices();
// Pass the index of the paired device
if (pairedDevices.size() > 0) {
callButtons(pairedDevices.iterator().next()); // First element in set.
} else {
System.out.println("No paired Device!");
}
}
});
acceptThread = new AcceptThread();
acceptThread.start();
}
}
private class ScanReciever extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
System.out.println("Started");
//discovery starts, we can show progress dialog or perform other tasks
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
System.out.println("finished");
//discovery finishes, dismis progress dialog
} else if (BluetoothDevice.ACTION_FOUND.equals(action)) {
//bluetooth device found
BluetoothDevice device = (BluetoothDevice) intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
System.out.println("FOUND: " + device.getName());
deviceList.add(device);
arrayAdapter.add(device.getName()+" - Click to pair");
arrayAdapter.notifyDataSetChanged();
} else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
System.out.println("Connected~!!!!!!!!!!!!!!");
callButtons(deviceList.get(deviceList.size()-1));
}
}
};
protected void askAdapterOn() {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
protected void scanForDevices() {
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
reciever = new ScanReciever();
registerReceiver(reciever, filter);
bluetooth_adapter.startDiscovery();
}
protected void callButtons(BluetoothDevice bd) {
bluetooth_adapter.cancelDiscovery();
Intent toButton = new Intent(getApplicationContext(), buttons.class);
toButton.putExtra("selected",bd);
startActivity(toButton);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_ENABLE_BT) {
if (resultCode == RESULT_OK){
if (bluetooth_adapter.isEnabled()){
onButton.setEnabled(false);
scanButton.setEnabled(true);
}
else {
onButton.setEnabled(true);
scanButton.setEnabled(false);
}
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onDestroy() {
unregisterReceiver(reciever);
super.onDestroy();
}
private class AcceptThread extends Thread {
private final BluetoothServerSocket mmServerSocket;
public AcceptThread() {
// Use a temporary object that is later assigned to mmServerSocket,
// because mmServerSocket is final
BluetoothServerSocket tmp = null;
try {
// MY_UUID is the app's UUID string, also used by the client code
tmp = bluetooth_adapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
System.out.println("READY TO ACCEPT");
} catch (IOException e) { }
mmServerSocket = tmp;
}
public void run() {
BluetoothSocket socket = null;
// Keep listening until exception occurs or a socket is returned
while (true) {
try {
socket = mmServerSocket.accept();
} catch (IOException e) {
break;
}
// If a connection was accepted
if (socket != null) {
// Do work to manage the connection (in a separate thread)
//manageConnectedSocket(socket);
try {
mmServerSocket.close();
} catch (IOException e) { }
break;
}
}
}
/** Will cancel the listening socket, and cause the thread to finish */
public void cancel() {
try {
mmServerSocket.close();
} catch (IOException e) { }
}
}
}
Buttons.java(where the app will initiate a connection and maintain communication) - probably the file with the error:
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.util.UUID;
public class buttons extends Activity {
public static final int MESSAGE_READ = 2;
public static final int MESSAGE_WRITE = 3;
BluetoothDevice selected;
BluetoothAdapter bluetoothAdapter;
TextView tv;
Button button1;
Button button2;
Button button3;
Button unpairB;
private static final UUID MY_UUID = UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");
ConnectThread connectThread;
ConnectedThread connectedThread;
BluetoothSocket mmSocket;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.buttons);
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
selected = getIntent().getExtras().getParcelable("selected");
pair(selected);
connectedThread = null;
try {
connectedThread = new ConnectedThread(mmSocket);
connectedThread.start();
System.out.println("ConnectedThread started!");
} catch (Exception e) {
Log.e("unpair()", e.getMessage());
}
// Set up Buttons
button1 = (Button) findViewById(R.id.button1);
button2 = (Button) findViewById(R.id.button2);
button3 = (Button) findViewById(R.id.button3);
unpairB = (Button) findViewById(R.id.unpairButton);
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
buttonPressed(1);
}
});
button2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
buttonPressed(2);
}
});
button3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
buttonPressed(3);
}
});
unpairB.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
unpair(selected);
finish();
}
});
// Set up textview
tv = (TextView) findViewById(R.id.textView);
tv.setText("connected to: " + selected.getName());
}
protected void buttonPressed(int i) {
connectedThread.write(i);
tv.setText(Integer.toString(i));
}
private void pair(BluetoothDevice device) {
connectThread = new ConnectThread(device);
connectThread.start();
}
private void unpair(BluetoothDevice device) {
try {
Method m = device.getClass().getMethod("removeBond", (Class[]) null);
m.invoke(device, (Object[]) null);
} catch (Exception e) {
Log.e("unpair()", e.getMessage());
}
}
private class ConnectThread extends Thread {
private final BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device) {
// Use a temporary object that is later assigned to mmSocket,
// because mmSocket is final
BluetoothSocket tmp = null;
mmDevice = device;
// Get a BluetoothSocket to connect with the given BluetoothDevice
try {
// MY_UUID is the app's UUID string, also used by the server code
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
System.out.println("Socket was created in ConnectThread");
} catch (IOException e) { }
mmSocket = tmp;
}
public void run() {
// Cancel discovery because it will slow down the connection
// bluetoothAdapter.cancelDiscovery();
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mmSocket.connect();
} catch (IOException connectException) {
// Unable to connect; close the socket and get out
try {
mmSocket.close();
} catch (IOException closeException) { }
return;
}
// Do work to manage the connection (in a separate thread)
//manageConnectedSocket(mmSocket);
}
/** Will cancel an in-progress connection, and close the socket */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
private class ConnectedThread extends Thread {
private final BluetoothSocket bluetoothSocket;
private final InputStream inputStream;
private final OutputStream outputStream;
public ConnectedThread(BluetoothSocket socket) {
this.bluetoothSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
System.out.println("Connected to " + socket.getRemoteDevice().getName());
try {
tmpIn = bluetoothSocket.getInputStream();
tmpOut = bluetoothSocket.getOutputStream();
} catch (IOException e) {
}
inputStream = tmpIn;
outputStream = tmpOut;
}
public void run() {
byte[] buffer = new byte[1024];
int bytes;
if (inputStream == null) System.out.println("Inputstream is null");
else System.out.println("Inputstream is safe");
if (outputStream == null) System.out.println("outstream is null");
else System.out.println("Outputstream is safe");
while (true) {
try {
System.out.println("Blocking?");
bytes = inputStream.read(buffer);
System.out.println("NO");
handler.obtainMessage(MESSAGE_READ, bytes, -1,
buffer).sendToTarget();
} catch (IOException e) {
break;
}
}
}
public void write(int i) {
try {
byte[] buffer = new byte[1024];
buffer[0] = (byte) i;
outputStream.write(buffer);
outputStream.flush();
handler.obtainMessage(MESSAGE_WRITE, -1, -1,
buffer).sendToTarget();
System.out.println("Write SUCCESS!!!!!!!!!!!!!!");
} catch (IOException e) {
System.out.println("write ERRORRRRRRRRRRRRRRRRR");
}
}
public void cancel() {
try {
bluetoothSocket.close();
} catch (IOException e) {
}
}
}
private final Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_WRITE:
System.out.println("Write was broadcasted");
byte[] writeBuf = (byte[]) msg.obj;
String writeMessage = new String(Integer.toString(writeBuf[0]));
///tv.setText(writeMessage);
break;
case MESSAGE_READ:
System.out.println("Read was broadcasted");
byte[] readBuf = (byte[]) msg.obj;
String readMessage = new String(Integer.toString(readBuf[0]));
tv.setText(readMessage);
break;
}
}
};
}
Can anyone tell me how to connect a mobile and a printer via bluetooth to print a text file in android?
That is,if i click the print button from the android application,the printer has to print that corresponding file.As per my knowledge i have searched for it in Google, but i couldn't find any good samples to do it.Has anyone have at-least one sample android program to do this, it will be better to clear my chaos.
Suggestions please.
Thanks for your precious time!..
Bluetooth Printer Android Example
Create a new android project BlueToothPrinterApp in your editor.
Step 1:
Create main activity like below
com.example.BlueToothPrinterApp / BlueToothPrinterApp.java
package com.example.BlueToothPrinterApp;
import android.app.Activity;
import android.os.Bundle;
import java.io.IOException;
import java.io.OutputStream;
import android.bluetooth.BluetoothSocket;
import android.content.ContentValues;
import android.content.Intent;
import android.os.Environment;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class BlueToothPrinterApp extends Activity {
/** Called when the activity is first created. */
EditText message;
Button printbtn;
byte FONT_TYPE;
private static BluetoothSocket btsocket;
private static OutputStream btoutputstream;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
message = (EditText) findViewById(R.id.message);
printbtn = (Button) findViewById(R.id.printButton);
printbtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
connect();
}
});
}
protected void connect() {
if (btsocket == null) {
Intent BTIntent = new Intent(getApplicationContext(), BTDeviceList.class);
this.startActivityForResult(BTIntent, BTDeviceList.REQUEST_CONNECT_BT);
} else {
OutputStream opstream = null;
try {
opstream = btsocket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
btoutputstream = opstream;
print_bt();
}
}
private void print_bt() {
try {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
btoutputstream = btsocket.getOutputStream();
byte[] printformat = {
0x1B,
0× 21,
FONT_TYPE
};
btoutputstream.write(printformat);
String msg = message.getText().toString();
btoutputstream.write(msg.getBytes());
btoutputstream.write(0x0D);
btoutputstream.write(0x0D);
btoutputstream.write(0x0D);
btoutputstream.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
protected void onDestroy() {
super.onDestroy();
try {
if (btsocket != null) {
btoutputstream.close();
btsocket.close();
btsocket = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
try {
btsocket = BTDeviceList.getSocket();
if (btsocket != null) {
print_bt();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Step 2:
com.example.BlueToothPrinterApp / BTDeviceList.java
package com.example.BlueToothPrinterApp;
import java.io.IOException;
import java.util.Set;
import java.util.UUID;
import android.app.ListActivity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
public class BTDeviceList extends ListActivity {
static public final int REQUEST_CONNECT_BT = 0× 2300;
static private final int REQUEST_ENABLE_BT = 0× 1000;
static private BluetoothAdapter mBluetoothAdapter = null;
static private ArrayAdapter < String > mArrayAdapter = null;
static private ArrayAdapter < BluetoothDevice > btDevices = null;
private static final UUID SPP_UUID = UUID
.fromString(“8 ce255c0 - 200 a - 11e0 - ac64 - 0800200 c9a66″);
// UUID.fromString(“00001101-0000-1000-8000-00805F9B34FB”);
static private BluetoothSocket mbtSocket = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTitle(“Bluetooth Devices”);
try {
if (initDevicesList() != 0) {
this.finish();
return;
}
} catch (Exception ex) {
this.finish();
return;
}
IntentFilter btIntentFilter = new IntentFilter(
BluetoothDevice.ACTION_FOUND);
registerReceiver(mBTReceiver, btIntentFilter);
}
public static BluetoothSocket getSocket() {
return mbtSocket;
}
private void flushData() {
try {
if (mbtSocket != null) {
mbtSocket.close();
mbtSocket = null;
}
if (mBluetoothAdapter != null) {
mBluetoothAdapter.cancelDiscovery();
}
if (btDevices != null) {
btDevices.clear();
btDevices = null;
}
if (mArrayAdapter != null) {
mArrayAdapter.clear();
mArrayAdapter.notifyDataSetChanged();
mArrayAdapter.notifyDataSetInvalidated();
mArrayAdapter = null;
}
finalize();
} catch (Exception ex) {} catch (Throwable e) {}
}
private int initDevicesList() {
flushData();
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
Toast.makeText(getApplicationContext(), “Bluetooth not supported!!”, Toast.LENGTH_LONG).show();
return -1;
}
if (mBluetoothAdapter.isDiscovering()) {
mBluetoothAdapter.cancelDiscovery();
}
mArrayAdapter = new ArrayAdapter < String > (getApplicationContext(),
android.R.layout.simple_list_item_1);
setListAdapter(mArrayAdapter);
Intent enableBtIntent = new Intent(
BluetoothAdapter.ACTION_REQUEST_ENABLE);
try {
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
} catch (Exception ex) {
return -2;
}
Toast.makeText(getApplicationContext(), “Getting all available Bluetooth Devices”, Toast.LENGTH_SHORT)
.show();
return 0;
}
#Override
protected void onActivityResult(int reqCode, int resultCode, Intent intent) {
super.onActivityResult(reqCode, resultCode, intent);
switch (reqCode) {
case REQUEST_ENABLE_BT:
if (resultCode == RESULT_OK) {
Set < BluetoothDevice > btDeviceList = mBluetoothAdapter
.getBondedDevices();
try {
if (btDeviceList.size() > 0) {
for (BluetoothDevice device: btDeviceList) {
if (btDeviceList.contains(device) == false) {
btDevices.add(device);
mArrayAdapter.add(device.getName() + “\n” +
device.getAddress());
mArrayAdapter.notifyDataSetInvalidated();
}
}
}
} catch (Exception ex) {}
}
break;
}
mBluetoothAdapter.startDiscovery();
}
private final BroadcastReceiver mBTReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent
.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
try {
if (btDevices == null) {
btDevices = new ArrayAdapter < BluetoothDevice > (
getApplicationContext(), android.R.id.text1);
}
if (btDevices.getPosition(device) < 0) {
btDevices.add(device);
mArrayAdapter.add(device.getName() + “\n” +
device.getAddress() + “\n”);
mArrayAdapter.notifyDataSetInvalidated();
}
} catch (Exception ex) {
// ex.fillInStackTrace();
}
}
}
};
#Override
protected void onListItemClick(ListView l, View v, final int position,
long id) {
super.onListItemClick(l, v, position, id);
if (mBluetoothAdapter == null) {
return;
}
if (mBluetoothAdapter.isDiscovering()) {
mBluetoothAdapter.cancelDiscovery();
}
Toast.makeText(
getApplicationContext(), “Connecting to” + btDevices.getItem(position).getName() + “, ”
+btDevices.getItem(position).getAddress(),
Toast.LENGTH_SHORT).show();
Thread connectThread = new Thread(new Runnable() {
#Override
public void run() {
try {
boolean gotuuid = btDevices.getItem(position)
.fetchUuidsWithSdp();
UUID uuid = btDevices.getItem(position).getUuids()[0]
.getUuid();
mbtSocket = btDevices.getItem(position)
.createRfcommSocketToServiceRecord(uuid);
mbtSocket.connect();
} catch (IOException ex) {
runOnUiThread(socketErrorRunnable);
try {
mbtSocket.close();
} catch (IOException e) {
// e.printStackTrace();
}
mbtSocket = null;
return;
} finally {
runOnUiThread(new Runnable() {
#Override
public void run() {
finish();
}
});
}
}
});
connectThread.start();
}
private Runnable socketErrorRunnable = new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), “Cannot establish connection”, Toast.LENGTH_SHORT).show();
mBluetoothAdapter.startDiscovery();
}
};
#Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(0, Menu.FIRST, Menu.NONE, “Refresh Scanning”);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
switch (item.getItemId()) {
case Menu.FIRST:
initDevicesList();
break;
}
return true;
}
}
Step 3:
Edit your main.xml file and paste below code.
res/layout/main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingLeft="16dp"
android:paddingRight="16dp">
<TextView
android:id="#+id/msgtextlbl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Enter Your Message : "/>
<EditText
android:id="#+id/message"
android:layout_width="fill_parent"
android:layout_height="100dp"
android:layout_below="#+id/msgtextlbl"
android:text=""/>
<Button
android:id="#+id/printButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/message"
android:layout_centerHorizontal="true"
android:layout_marginTop="5dip"
android:text="Print"/>
</RelativeLayout>
Step 4:
Now edit your AndroidManifest.xml
Add bluetooth permission and admin permission.
AndroidManifest.xml
<?xml version=”1.0″ encoding=”utf-8″?>
<manifest
xmlns:android=”http://schemas.android.com/apk/res/android
package=”com.example.BlueToothPrinterApp”
android:versionCode=”1″
android:versionName=”1.0″>
<uses-sdk android:minSdkVersion=”14″ />
<uses-permission android:name=”android.permission.BLUETOOTH”></uses-permission>
<uses-permission android:name=”android.permission.BLUETOOTH_ADMIN”></uses-permission>
<application
android:label=”#string/app_name”
android:icon=”#drawable/ic_launcher”>
<activity
android:name=”BlueToothPrinterApp”
android:label=”#string/app_name”>
<intent-filter>
<action android:name=”android.intent.action.MAIN” />
<category android:name=”android.intent.category.LAUNCHER” />
</intent-filter>
</activity>
<activity android:name=”BTDeviceList”></activity>
</application>
</manifest>
Compile and run this application. Enter message and press print button.
You will see list of bluetooth devices. Select bluettoth printer.
Check print on your bluetooth printer.
here is the CODE Reference...
You can use this awesome lib, you can connect to any printer and print easily,
https://github.com/mazenrashed/Printooth
you can download it by:
implementation 'com.github.mazenrashed:Printooth:${LAST_VERSION}'
and use it like:
var printables = ArrayList<Printable>()
var printable = Printable.PrintableBuilder()
.setText("Hello World")
printables.add(printable)
BluetoothPrinter.printer().print(printables)
I am sending some data to an android application over UDP. Therefore i created the following UDPReceiver-Class:
package com.example.urowatch;
import java.net.*;
import java.nio.ByteBuffer;
import java.io.*;
public class UDPReceiver extends Thread
{
private DatagramSocket m_Socket;
private int m_BufferSize;
private Boolean m_End = false;
private int m_TotalLength;
private int m_Received;
private byte[] m_Buffer;
private byte[] m_Result;
private Boolean m_IsNewResult = false;
private float m_Progress;
private int m_ImageCount = 0;
private int m_FrameErrors = 0;
public UDPReceiver(String name, int port, int bufferSize) throws IOException
{
super(name);
m_Socket = new DatagramSocket(port);
m_BufferSize = bufferSize;
m_Socket.setBroadcast(true);
m_Socket.setReceiveBufferSize(m_BufferSize);
}
public void run()
{
while(!m_End)
{
try
{
byte[] buf = new byte[m_BufferSize];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
m_Socket.receive(packet);
ProcessData(packet);
}
catch (IOException e)
{
if (!m_Socket.isClosed())
e.printStackTrace();
}
}
}
private void ProcessData(DatagramPacket packet)
{
if (packet.getLength() == 4)
{
ByteBuffer bb = ByteBuffer.wrap(packet.getData());
m_TotalLength = bb.getInt();
if (m_Received != 0)
m_FrameErrors++;
m_Received = 0;
m_Buffer = new byte[m_TotalLength];
}
else if (m_Buffer != null && m_Received != m_TotalLength)
{
int length = packet.getLength();
System.arraycopy(packet.getData(), 0, m_Buffer, m_Received, length);
m_Received += length;
m_Progress = 100 * (float)m_Received/(float)m_TotalLength;
if (m_Received == m_TotalLength)
{
m_Result = new byte[m_TotalLength];
System.arraycopy(m_Buffer, 0, m_Result, 0, m_TotalLength);
m_IsNewResult = true;
m_ImageCount++;
m_Received = 0;
}
}
}
public Boolean IsNewResult()
{
return m_IsNewResult;
}
public byte[] GetResult()
{
m_IsNewResult = false;
return m_Result;
}
public float GetProgress()
{
return m_Progress;
}
public float GetRatio()
{
return 100 * (float)m_ImageCount / (float)m_FrameErrors;
}
public void stopServer()
{
m_End = true;
if (m_Socket != null)
m_Socket.close();
}
}
And i am using this class like this:
package com.example.urowatch;
import java.io.IOException;
import java.text.DecimalFormat;
import android.os.*;
import android.app.Activity;
import android.app.AlertDialog;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import android.support.v4.app.NavUtils;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.os.Build;
public class LiveActivity extends Activity {
private static ImageView m_ImageView1;
private static TextView m_TextView1;
private static DecimalFormat m_DF;
private static Context m_Context;
private UDPReceiver m_Receiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_live);
// Show the Up button in the action bar.
setupActionBar();
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
m_ImageView1 = (ImageView)findViewById(R.id.imageView1);
m_TextView1 = (TextView)findViewById(R.id.textView1);
m_Context = this;
m_DF = new DecimalFormat("00.00");
}
/**
* Set up the {#link android.app.ActionBar}, if the API is available.
*/
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void setupActionBar() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
getActionBar().setDisplayHomeAsUpEnabled(true);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.live, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// This ID represents the Home or Up button. In the case of this
// activity, the Up button is shown. Use NavUtils to allow users
// to navigate up one level in the application structure. For
// more details, see the Navigation pattern on Android Design:
//
// http://developer.android.com/design/patterns/navigation.html#up-vs-back
//
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
private static Handler MyHandler = new Handler()
{
#Override
public void handleMessage(Message msg)
{
if (msg.what == 100)
{
float[] infos = (float[])msg.obj;
m_TextView1.setText("Empfange Bild: " + m_DF.format(infos[0]) + "% (FrameErrors: " + m_DF.format(infos[1]) + "%)");
}
else if (msg.what == 101)
{
byte[] b = (byte[])msg.obj;
m_TextView1.setText("Empfange Bild: 100,00%");
m_ImageView1.setImageBitmap(BitmapFactory.decodeByteArray(b, 0, b.length));
}
else if (msg.what == 102)
{
AlertDialog.Builder b = new AlertDialog.Builder(m_Context);
b.setTitle("Fehler");
b.setMessage("Es ist folgende Exception aufgetreten:\n" + (Exception)msg.obj);
b.setNeutralButton("OK", null);
b.show();
}
}
};
#Override
public void onBackPressed() {
super.onBackPressed();
if (m_Receiver != null)
m_Receiver.stopServer();
finish();
}
#Override
public void onPause()
{
m_Receiver.stopServer();
super.onPause();
}
#Override
protected void onResume()
{
try {
m_Receiver = new UDPReceiver("UDPReceiver", 5678, 1024);
m_Receiver.start();
} catch (IOException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
AlertDialog.Builder b = new AlertDialog.Builder(this);
b.setTitle("Fehler");
b.setMessage("Es ist folgende Exception aufgetreten:\n" + e1);
b.setNeutralButton("OK", null);
b.show();
}
// Thread thread = new Thread()
// {
// #Override
// public void run()
// {
// while(true)
// {
// try {
//sleep(250);
Toast.makeText(getBaseContext(), "Runing Thread", Toast.LENGTH_SHORT).show();
Update();
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// MyHandler.sendMessage(MyHandler.obtainMessage(102, e));
// }
// }
// }
// };
// thread.start();
super.onResume();
}
public void buttonClick(View v)
{
Update();
}
private void Update()
{
if (m_Receiver != null)
{
if (m_Receiver.IsNewResult())
{
byte[] b = m_Receiver.GetResult();
MyHandler.sendMessage(MyHandler.obtainMessage(101, b));
}
else
{
float[] infos = new float[2];
infos[0] = m_Receiver.GetProgress();
infos[1] = m_Receiver.GetRatio();
MyHandler.sendMessage(MyHandler.obtainMessage(100, infos));
}
}
}
}
As you see i want to check the status of the UDPReceiver-Object (Is there a new complete byte[] ready?) by a thread. To update the GUI, the thread has to send a Message to MyHandler which will update the GUI.
In the moment i have to to click a button to raise the buttonClick-Event. Later on i want to do this in the commented thread-structure.
Now, here's my problem:
I start the Activity and everything works fine. Then i am starting to send ONE packet manually with my UDP-Sender (which works, i validated it with a C#-UDP-Receiver). The first packet get received fine. Then i send the second packet which get received, too. But from now on, my breakpoint at m_Socket.receive(packet); wont get hit anymore!
I have NO idea what this behaviour causes and it is very important for me to make this application work.
Please, if you have ANY Idea or just a guess, please let me know.