I am beginner to Android programming, I am doing my final project and I need to develop a packet sniffing application. I found some code on internet, and am trying to extended it into my project. But getting FATAL EXCEPTION: main and following errors.
Here is the code:
public class Main extends Activity {
// Variable declarations for handling the view items in the layout.
private Button start_button;
private Button stop_button;
private Button read_button;
private EditText parameters;
// Variable declarations for handling the TCPdump process.
private TCPdump tcpdump = null;
private TCPdumpHandler tcpDumpHandler = null;
private SharedPreferences settings = null;
// Variable declarations for handling the options and reader activities.
private Intent optionsIntent = null;
private Intent readerIntent = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Associating the items in the view to the variables.
start_button = (Button) findViewById(R.id.start_button);
stop_button = (Button) findViewById(R.id.stop_button);
read_button = (Button) findViewById(R.id.read_button);
parameters = (EditText) findViewById(R.id.params_text);
// Accessing the app's preferences.
settings = getSharedPreferences(GlobalConstants.prefsName, 0);
// Extracting the TCPdump binary to the app folder.
if (RootTools.installBinary(Main.this, R.raw.tcpdump, "tcpdump") == false) {
new AlertDialog.Builder(Main.this)
.setTitle(R.string.extraction_error)
.setMessage(R.string.extraction_error_msg)
.setNeutralButton(R.string.ok, null).show();
}
// Creating a new TCPdump object.
tcpdump = new TCPdump();
// Creating a TCPdump handler for the TCPdump object created after.
tcpDumpHandler = new TCPdumpHandler(tcpdump, this, this, true);
// Obtaining the command from the options that were saved last time
// Shark was running.
tcpDumpHandler.generateCommand();
start_button.setOnClickListener(new OnClickListener() {
// Setting the action to perform when the start button is pressed.
public void onClick(View v) {
startTCPdump();
}
});
stop_button.setOnClickListener(new OnClickListener() {
// Setting the action to perform when the stop button is pressed.
public void onClick(View v) {
stopTCPdump();
}
});
read_button.setOnClickListener(new OnClickListener() {
// Setting the action to perform when the open in reader button is
// pressed.
public void onClick(View v) {
launchReader();
}
});
BroadcastReceiver connectionReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Setting the action to be performed when the network status
// changes.
if ((tcpDumpHandler.checkNetworkStatus() == false)
&& (tcpdump.getProcessStatus())) {
stopTCPdump();
new AlertDialog.Builder(Main.this)
.setTitle(
getString(R.string.network_connection_down))
.setMessage(
getString(R.string.network_connection_down_msg))
.setNeutralButton(getString(R.string.ok), null)
.show();
}
}
};
// Registering the BroadcastReceiver and associating it with the
// connectivity change event.
registerReceiver(connectionReceiver, new IntentFilter(
"android.net.conn.CONNECTIVITY_CHANGE"));
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// Setting the action to perform when returning to this activity from
// another activity which had been called.
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK && requestCode == 1) {
if (tcpdump.getProcessStatus()) {
new AlertDialog.Builder(Main.this)
.setTitle(getString(R.string.settings_changed))
.setMessage(getString(R.string.settings_changed_msg))
.setNeutralButton(getString(R.string.ok), null).show();
}
tcpDumpHandler.generateCommand();
}
}
#Override
public void onDestroy() {
// Setting the action to perform when the Android O.S. kills this
// activity.
if (tcpdump.getProcessStatus()) {
stopTCPdump();
}
}
public boolean onCreateOptionsMenu(Menu menu) {
// This code makes the activity to show a menu when the device's menu
// key is pressed.
menu.add(0, 0, 0, getString(R.string.options_text));
menu.add(0, 1, 0, getString(R.string.about_text));
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
// Setting the action to perform when an option from the menu is
// selected.
switch (item.getItemId()) {
case 0:
optionsIntent = new Intent(Main.this, Options.class);
startActivityForResult(optionsIntent, 1);
return true;
case 1:
new AlertDialog.Builder(Main.this).setTitle(R.string.about_text)
.setMessage(getString(R.string.about_shark))
.setNeutralButton(getString(R.string.ok), null).show();
return true;
}
return false;
}
/**
* Calls TCPdumpHandler to try start the packet capture.
*/
private void startTCPdump() {
if (tcpDumpHandler.checkNetworkStatus()) {
switch (tcpDumpHandler.start(parameters.getText().toString())) {
case 0:
Toast.makeText(Main.this, getString(R.string.tcpdump_started),
Toast.LENGTH_SHORT).show();
break;
case -1:
Toast.makeText(Main.this,
getString(R.string.tcpdump_already_started),
Toast.LENGTH_SHORT).show();
break;
case -2:
new AlertDialog.Builder(Main.this)
.setTitle(getString(R.string.device_not_rooted_error))
.setMessage(
getString(R.string.device_not_rooted_error_msg))
.setNeutralButton(getString(R.string.ok), null).show();
break;
case -4:
new AlertDialog.Builder(Main.this).setTitle("Error")
.setMessage(getString(R.string.command_error))
.setNeutralButton(getString(R.string.ok), null).show();
break;
case -5:
new AlertDialog.Builder(Main.this).setTitle("Error")
.setMessage(getString(R.string.outputstream_error))
.setNeutralButton(getString(R.string.ok), null).show();
break;
default:
new AlertDialog.Builder(Main.this).setTitle("Error")
.setMessage(getString(R.string.unknown_error))
.setNeutralButton(getString(R.string.ok), null).show();
}
} else {
new AlertDialog.Builder(Main.this)
.setTitle(getString(R.string.network_connection_error))
.setMessage(
getString(R.string.network_connection_error_msg))
.setPositiveButton(getString(R.string.yes),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int which) {
startActivity(new Intent(
Settings.ACTION_WIRELESS_SETTINGS));
}
}).setNegativeButton(getString(R.string.no), null)
.show();
}
}
/**
* Calls TCPdumpHandler to try to stop the packet capture.
*/
private void stopTCPdump() {
switch (tcpDumpHandler.stop()) {
case 0:
Toast.makeText(Main.this, getString(R.string.tcpdump_stoped),
Toast.LENGTH_SHORT).show();
break;
case -1:
Toast.makeText(Main.this,
getString(R.string.tcpdump_already_stoped),
Toast.LENGTH_SHORT).show();
break;
case -2:
new AlertDialog.Builder(Main.this)
.setTitle(getString(R.string.device_not_rooted_error))
.setMessage(getString(R.string.device_not_rooted_error_msg))
.setNeutralButton(getString(R.string.ok), null).show();
break;
case -4:
new AlertDialog.Builder(Main.this).setTitle("Error")
.setMessage(getString(R.string.command_error))
.setNeutralButton(getString(R.string.ok), null).show();
break;
case -5:
new AlertDialog.Builder(Main.this).setTitle("Error")
.setMessage(getString(R.string.outputstream_error))
.setNeutralButton(getString(R.string.ok), null).show();
break;
case -6:
new AlertDialog.Builder(Main.this).setTitle("Error")
.setMessage(getString(R.string.close_shell_error))
.setNeutralButton(getString(R.string.ok), null).show();
break;
case -7:
new AlertDialog.Builder(Main.this).setTitle("Error")
.setMessage(getString(R.string.process_finish_error))
.setNeutralButton(getString(R.string.ok), null).show();
default:
new AlertDialog.Builder(Main.this).setTitle("Error")
.setMessage(getString(R.string.unknown_error))
.setNeutralButton(getString(R.string.ok), null).show();
}
}
/**
* Tries to launch the reader activity.
*/
private void launchReader() {
readerIntent = new Intent(Main.this, Reader.class);
if (FileManager.checkFile(GlobalConstants.dirName,
settings.getString("fileText", "shark_capture.pcap"))) {
if (tcpdump.getProcessStatus() == false) {
startActivity(readerIntent);
} else {
new AlertDialog.Builder(Main.this)
.setTitle(getString(R.string.capture_in_progress_error))
.setMessage(
getString(R.string.capture_in_progress_error_msg))
.setPositiveButton(getString(R.string.yes),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0,
int arg1) {
stopTCPdump();
startActivity(readerIntent);
}
})
.setNegativeButton(getString(R.string.no), null).show();
}
} else {
new AlertDialog.Builder(Main.this)
.setTitle(getString(R.string.file_error))
.setMessage(getString(R.string.file_error_msg))
.setNeutralButton(getString(R.string.ok), null).show();
}
}
}
when I run this Eclipse, I receive an error in the log cat the following errors. I tried a lot of solution that has been suggested, even then I couldn't get solution.
08-21 15:38:01.483: D/AndroidRuntime(499): Shutting down VM
08-21 15:38:01.483: W/dalvikvm(499): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
08-21 15:38:01.504: E/AndroidRuntime(499): FATAL EXCEPTION: main
08-21 15:38:01.504: E/AndroidRuntime(499): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.shark/com.shark.Main}: java.lang.NullPointerException
08-21 15:38:01.504: E/AndroidRuntime(499): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
08-21 15:38:01.504: E/AndroidRuntime(499): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
08-21 15:38:01.504: E/AndroidRuntime(499): at android.app.ActivityThread.access$2300(ActivityThread.java:125)
08-21 15:38:01.504: E/AndroidRuntime(499): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
08-21 15:38:01.504: E/AndroidRuntime(499): at android.os.Handler.dispatchMessage(Handler.java:99)
08-21 15:38:01.504: E/AndroidRuntime(499): at android.os.Looper.loop(Looper.java:123)
08-21 15:38:01.504: E/AndroidRuntime(499): at android.app.ActivityThread.main(ActivityThread.java:4627)
08-21 15:38:01.504: E/AndroidRuntime(499): at java.lang.reflect.Method.invokeNative(Native Method)
08-21 15:38:01.504: E/AndroidRuntime(499): at java.lang.reflect.Method.invoke(Method.java:521)
08-21 15:38:01.504: E/AndroidRuntime(499): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
08-21 15:38:01.504: E/AndroidRuntime(499): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
08-21 15:38:01.504: E/AndroidRuntime(499): at dalvik.system.NativeStart.main(Native Method)
08-21 15:38:01.504: E/AndroidRuntime(499): Caused by: java.lang.NullPointerException
08-21 15:38:01.504: E/AndroidRuntime(499): at com.shark.TCPdumpHandler.generateCommand(TCPdumpHandler.java:322)
08-21 15:38:01.504: E/AndroidRuntime(499): at com.shark.Main.onCreate(Main.java:93)
08-21 15:38:01.504: E/AndroidRuntime(499): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
08-21 15:38:01.504: E/AndroidRuntime(499): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
08-21 15:38:01.504: E/AndroidRuntime(499): ... 11 more
I found where exactly the error is occurring. According that, the "closeShell" is returning null in the following code. which further loops back to three classes.
public class RootShell {
protected Process process = null;
protected DataOutputStream os = null;
protected DataInputStream is = null;
private boolean deviceRooted = false;
/**
* RootShell class constructor. Checks if the device is rooted.
*/
public RootShell() {
deviceRooted = checkRootStatus();
}
/**
* RootShell class destructor. Closes the shell if its not already closed.
*/
protected void finalize() {
if (process != null)
closeShell();
}
/**
* Opens a root shell and waits for commands.
*
* #return 0 Everything went OK.<br>
* -1 The shell has already been opened.<br>
* -2 The device isn't rooted.<br>
* -3 IOException when running the su command.
*/
public int openShell() {
if (process == null) {
if (deviceRooted) {
// Trying to get root access.
try {
process = Runtime.getRuntime().exec("su");
} catch (IOException e) {
return -3;
}
// Getting an output stream to the root shell for introducing
// commands.
os = new DataOutputStream(process.getOutputStream());
// Getting an input stream to the root shell for displaying
// results.
is = new DataInputStream(process.getInputStream());
return 0;
} else
return -2;
} else
return -1;
}
/**
* Runs the command in the root shell.
*
* #param command
* The command which will be executed in the root shell.
* #return 0 Everything went OK.<br>
* -1 The shell wasn't opened.<br>
* -2 The device isn't rooted.<br>
* -4 IOException when running the user command.<br>
* -5 IOException when flushing the DataOutputStream.
*/
public int runCommand(String command) {
if (process != null) {
if (deviceRooted) {
try {
os.writeBytes(command + "\n");
} catch (IOException e) {
return -4;
}
try {
os.flush();
} catch (IOException e) {
return -5;
}
return 0;
} else
return -2;
} else
return -1;
}
/**
* Closes a shell which is already open.
*
* #return -1 The shell wasn't opened.<br>
* -2 The device isn't rooted.<br>
* -6 IOException when running the exit command.<br>
* -7 InterruptedException when waiting for the process to stop.
*/
public int closeShell() {
if (process != null) {
if (deviceRooted) {
try {
os.writeBytes("exit\n");
} catch (IOException e1) {
return -6;
}
try {
process.waitFor();
} catch (InterruptedException e) {
return -7;
}
process.destroy();
process = null;
os = null;
is = null;
return 0;
} else
return -2;
} else
return -1;
}
/**
* Checks if an Android device is rooted or not.<br>
* Code borrowed from: http://www
* .stealthcopter.com/blog/2010/01/android-requesting-root-access-in
* -your-app/
*
* #return true: The device is rooted.<br>
* false: The device isn't rooted.
*/
private static boolean checkRootStatus() {
Process p;
try {
// Preform su to get root privileges
p = Runtime.getRuntime().exec("su");
// Attempt to write a file to a root-only
DataOutputStream os = new DataOutputStream(p.getOutputStream());
os.writeBytes("echo \"Do I have root?\" >/system/sd/temporary.txt\n");
// Close the terminal
os.writeBytes("exit\n");
os.flush();
try {
p.waitFor();
if (p.exitValue() != 255) {
return true;
} else {
return false;
}
} catch (InterruptedException e) {
return false;
}
} catch (IOException e) {
return false;
}
}
/**
* #return A DataInputStream to the root shell.
*/
public DataInputStream getInputStream() {
return is;
}
/**
* #return A DataOutputStream to the root shell.
*/
public DataOutputStream getOutputStream() {
return os;
}
/**
* #return true if the shell is opened.<br>
* false if the shell isn't opened.
*/
public boolean getProcessStatus() {
if (process != null)
return true;
else
return false;
}
}
I also found that, it is giving "08-22 19:05:19.701: I/System.out(275): e1java.io.IOException: Broken pipe", the it enters try catch in "closeshell".
What is R in your R.id.start_button and multiple other places?
The error refers to tcpDumpHandler.generateCommand() but you don't provide the code for it.
Related
my app is fairly simple and always works IF my IOT device is up.
i need to load a popup and show the ReScan button on the toolbar if the device cannot be found.
the app preloads IPaddress="-" and loads 2 asyncTask(s)
one uses NsdManager.DiscoveryListener to find the mDNS name and loads the IP into IPaddress
this task watches to see IPaddress change and gets the presets from the device by JSON and sets up the UI or pops up the error dialog with instructions if not found.
MY PROBLEM:
when counter >= 15 , i show the "Rescan" Button on the toolbar with setMenuVisible() then popup the error dialog but when the button in the dialog is pressed to close the dialog, the "Rescan" Button disappears again.
Also times out in about 5 seconds.
how do i get the "Rescan" Button to stay?
.
private class getSettingsFromClock extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
String mlooper = IPaddress;
Log.i(TAG, "LOG getSettingsFromClock doInBackground started ");
int counter = 0;
while ( mlooper.equals("-") ) {
mlooper = IPaddress;
try {
Thread.sleep(600);
} catch (InterruptedException e) {
e.printStackTrace();
}
counter++;
if (counter >= 15) // in normal operation counter never goes above 3
{
Log.i(TAG, "LOG getSettingsFromClock - NO IP Found, count= " + counter );
runOnUiThread(new Runnable() {
#Override
public void run() {
setMenuVisible( true, R.id.action_rescan); // show rescan button on toolbar
try { // delay is debugging only
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
//scanning failed Popup Dialog
final Dialog dialog = new Dialog(context );
dialog.setContentView(R.layout.popup);
dialog.setTitle("Scan Error");
Button button = dialog.findViewById(R.id.Button01);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
dialog.dismiss();
}
});
dialog.show();
Toast.makeText(getApplicationContext(),
"Could Not get presets from clock. \n check Clock is on and on WiFi\n and reload app.",
Toast.LENGTH_LONG).show();
}
});
break;
}
}
if( IPaddress != "-" )
{
// gets JSON here
} else
{
// add popup - IOT Not found
}
// JSON starts here
if (JSON_return != null) {
try {
// loads presets from JSON to UI here
} catch (final JSONException e) {
Log.e(TAG, "LOG, JSON parsing error: " + e.getMessage());
}
} else
{
Log.e(TAG, "LOG, Could Not get JSON from Clock.");
}
return null;
}
} // end asyncTask class
// remember to run on main thread
// NOTE; private Menu option_Menu; declared in MainActivity
// ie; setMenuVisible( true, R.id.action_rescan);
public void setMenuVisible(boolean visible, int id) {
if (option_Menu != null) {
option_Menu.findItem(id).setVisible(visible);
}
}
Mike M. had it, Thank You Mike
added onPrepareOptionsMenu()
added showRescan = visible; and invalidateOptionsMenu(); to setMenuVisible()
all work perfectly now.
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
try {
if( showRescan )
{
option_Menu.findItem(R.id.action_rescan).setVisible( true );
} else
{
option_Menu.findItem(R.id.action_rescan).setVisible( false );
}
}
catch(Exception e) {
Log.e(TAG, "onPrepareOptionsMenu error");
}
return true;
}
// when task is completed you can show your menu just by calling this method
// remember to run on main thread
// ie; setMenuVisible( true, R.id.action_rescan);
public void setMenuVisible(boolean visible, int id) {
if (option_Menu != null) {
option_Menu.findItem(id).setVisible(visible);
showRescan = visible;
invalidateOptionsMenu();
}
}
I am not much of an expert.I am using tesseract (tess-two) for developing an android application for my college project. The application crashes when I select the Nepali trained data.
*The application works only with Image selected from gallery. The image taken from camera returns empty result. So, yes! I am in big trouble here!!
Here is the snippet of the LogCat when I used eng.trainddata:
04-26 22:52:02.286 26503-26509/com.l.android.neptext I/zygote64: Do partial code cache collection, code=124KB, data=69KB
After code cache collection, code=124KB, data=69KB
Increasing code cache capacity to 512KB
04-26 22:52:02.347 26503-26520/com.l.android.neptext I/vndksupport: sphal namespace is not configured for this process. Loading /vendor/lib64/hw/gralloc.msm8996.so from the current namespace instead.
04-26 22:52:08.559 26503-26503/com.l.android.neptext D/com.l.android.neptext.MainActivity$3#2314718: onClick:
04-26 22:52:08.612 26503-26503/com.l.android.neptext D/AppTracker: App Event: stop
04-26 22:52:21.431 26503-26503/com.l.android.neptext D/AppTracker: App Event: start
04-26 22:52:21.603 26503-26589/com.l.android.neptext I/com.l.android.neptext.MainActivity$5#8074bd5: bitmap size8294400
04-26 22:52:22.232 26503-26589/com.l.android.neptext I/Tesseract(native): Initialized Tesseract API with language=eng
04-26 22:52:35.031 26503-26509/com.l.android.neptext I/zygote64: Compiler allocated 6MB to compile void android.view.ViewRootImpl.performTraversals()
04-26 22:52:39.452 26503-26503/com.l.android.neptext D/AppTracker: App Event: stop
Another snippet when I use nep.traineddata:
04-26 22:53:44.007 26764-26769/com.l.android.neptext I/zygote64: Compiler allocated 6MB to compile void android.view.ViewRootImpl.performTraversals()
04-26 22:53:44.095 26764-26780/com.l.android.neptext D/OpenGLRenderer: endAllActiveAnimators on 0x7e841e2000 (DropDownListView) with handle 0x7e7abf6840
04-26 22:53:46.978 26764-26764/com.l.android.neptext D/com.l.android.neptext.MainActivity$3#cc3f660: onClick:
04-26 22:53:47.033 26764-26764/com.l
.android.neptext D/AppTracker: App Event: stop
04-26 22:54:00.276 26764-26764/com.l.android.neptext D/AppTracker: App Event: start
04-26 22:54:00.449 26764-26815/com.l.android.neptext I/com.l.android.neptext.MainActivity$5#c8be754: bitmap size8294400
The app crashes without other error message.
Code of Project:
public class MainActivity extends AppCompatActivity {
public static Button camera,gallery,cut,copy,speech;
public static EditText text;
public static TextView textView;
public static final int GALERY_ACTION=100;
public static final int CAMERA_ACTION=101;
public static Uri imageuri=null;
Handler texthandler;
TextToSpeech t1;
Spinner spinner;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
camera=findViewById(R.id.button1);
gallery=findViewById(R.id.button2);
cut=findViewById(R.id.cut_btn);
copy=findViewById(R.id.copy_btn);
speech=findViewById(R.id.speech_btn);
text = findViewById(R.id.result_text);
textView=findViewById(R.id.textView);
spinner=findViewById(R.id.spinner);
spinner=findViewById(R.id.spinner);
List<String> categories = new ArrayList<String>();
categories.add("eng");
categories.add("nep");
// Creating adapter for spinner
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, categories);
// Drop down layout style - list view with radio button
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// attaching data adapter to spinner
spinner.setAdapter(dataAdapter);
t1=new TextToSpeech(getApplicationContext(), new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
if(status != TextToSpeech.ERROR) {
t1.setLanguage(Locale.UK);
}
}
});
texthandler=new Handler(Looper.myLooper()){
#Override
public void handleMessage(Message msg) {
String t=(String)msg.obj;
if(t==null){
Toast.makeText(getApplicationContext(),"Cannot find any letters ",Toast.LENGTH_LONG).show();
}
text = findViewById(R.id.result_text);
text.setText((String)msg.obj);
}
};
onButtonClickListiner();
//copying tranning datas
try {
MainApplication.instance.copydata("eng");
MainApplication.instance.copydata("nep");
}catch(Exception e){
Log.d("OcrManager",e.getMessage());
}
}
public void copy(View view){
text = findViewById(R.id.result_text);
Log.d(this.toString(),text.getText().toString());
ClipboardManager clipboardManager=(ClipboardManager)getApplicationContext().getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clipData=ClipData.newPlainText("label",text.getText().toString());
clipboardManager.setPrimaryClip(clipData);
Toast.makeText(MainActivity.this,"Text copied to clipbaord",Toast.LENGTH_LONG).show();
}
public void cut(View view){
text = findViewById(R.id.result_text);
Log.d(this.toString(),text.getText().toString());
ClipboardManager clipboardManager=(ClipboardManager)getApplicationContext().getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clipData=ClipData.newPlainText("label",text.getText().toString());
clipboardManager.setPrimaryClip(clipData);
text.setText("");
Toast.makeText(MainActivity.this,"Text copied to clipbaord",Toast.LENGTH_LONG).show();
}
public void speech(View view){
text = findViewById(R.id.result_text);
Log.d(this.toString(),text.getText().toString());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
t1.speak(text.getText().toString(),TextToSpeech.QUEUE_FLUSH,null,null);
} else {
t1.speak(text.getText().toString(), TextToSpeech.QUEUE_FLUSH, null);
}
Toast.makeText(this,"Speaking now",Toast.LENGTH_LONG).show();
}
private void onButtonClickListiner(){
gallery.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try{
Log.d(this.toString(), "onClick: ");
Intent galaryIntent=new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI);
startActivityForResult(galaryIntent,GALERY_ACTION);
gallery.setVisibility(View.GONE);
camera.setVisibility(View.GONE);
textView.setVisibility(View.GONE);
cut.setVisibility(View.VISIBLE);
copy.setVisibility(View.VISIBLE);
speech.setVisibility(View.VISIBLE);
text.setVisibility(View.VISIBLE);
spinner.setVisibility(View.GONE);
}catch(Exception e){
Log.d("Main actiity",e.getMessage());
}
}
});
camera.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try{
Intent cameraIntent=new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent,CAMERA_ACTION);
gallery.setVisibility(View.GONE);
camera.setVisibility(View.GONE);
textView.setVisibility(View.GONE);
cut.setVisibility(View.VISIBLE);
copy.setVisibility(View.VISIBLE);
speech.setVisibility(View.VISIBLE);
text.setVisibility(View.VISIBLE);
spinner.setVisibility(View.GONE);
}catch(Exception e){
Log.d("Main actiity",e.getMessage());
}
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, final Intent data) {
if (resultCode == RESULT_OK && data != null) {
if (requestCode == GALERY_ACTION) {
imageuri = data.getData();
try {
MainApplication.instance.showToast("Rendering Started,Please wait");
new Thread(new Runnable() {
#Override
public void run() {
Looper.prepare();
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), imageuri);
Log.i(this.toString(),"bitmap size"+bitmap.getByteCount());
OcrManager ocrManager= new OcrManager();
ocrManager.ocrStart(spinner.getSelectedItem().toString());
final String s = ocrManager.getText(bitmap);
Message m = new Message();
m.obj = s;
texthandler.sendMessage(m);
} catch (Exception e) {
Log.e("Main actiity", e.getMessage());
}
}
}).start();
} catch (Exception e) {
Log.d(this.toString(), e.getMessage());
}
}else if(requestCode==CAMERA_ACTION){
try {
MainApplication.instance.showToast("Rendering Started,Please wait");
new Thread(new Runnable() {
#Override
public void run() {
Looper.prepare();
try {
Bundle bundle=data.getExtras();
Bitmap bitmap = (Bitmap)bundle.get("data");
OcrManager ocrManager= new OcrManager();
ocrManager.ocrStart(spinner.getSelectedItem().toString());
final String s = ocrManager.getText(bitmap);
Message m = new Message();
m.obj = s;
texthandler.sendMessage(m);
} catch (Exception e) {
Log.d("Main actiity", e.getMessage());
}
}
}).start();
} catch (Exception e) {
Log.d(this.toString(), e.getMessage());
}
}
}
}
}
OCRManager Class:
public class OcrManager {
public static TessBaseAPI base=null;
public void ocrStart(String lang) {
try{
base = new TessBaseAPI();
String dataDirectory = MainApplication.instance.tessDataPathParent();
base.init(dataDirectory, lang);
}catch(Exception e){}
}
public String getText(Bitmap bitmap){
base.setImage(bitmap);
MainApplication.instance.showToast("Conversion Started");
String out=base.getUTF8Text();
MainApplication.instance.showToast("Conversion finished");
return out;
}
}
Also there is another class which copies nepali and english trained data to the storage successfully.
So, what am I doing wrong here? There is no any result when camera is used and the app crashes when nepali trained data is used with gallery source. Please help me out here. I do not want to do this again in resit.
So the other thing I had done wrong was the value of dataDirectory and just changing its value made the application a lot stable. The nep.trained data was found and initialized by the tesseract after that.
private static final String dataDirectory = Environment.getExternalStorageDirectory().getAbsolutePath() + "/com.lokensapkota.android.neptext/";
Also, if I changed the whole function in MainApplication class; which was just there to copy the trained data, to a method and ran it in background.:
private void copyAssets() {
AssetManager assetManager = getAssets();
String[] files = null;
try {
files = assetManager.list("trainneddata");
} catch (IOException e) {
Log.e("tag", "Failed to get asset file list.", e);
}
for(String filename : files) {
Log.i("files",filename);
InputStream in = null;
OutputStream out = null;
String dirout= dataDirectory + "tessdata/";
File outFile = new File(dirout, filename);
if(!outFile.exists()) {
try {
in = assetManager.open("trainneddata/"+filename);
(new File(dirout)).mkdirs();
out = new FileOutputStream(outFile);
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch (IOException e) {
Log.e("tag", "Error creating files", e);
}
}
}
}
private void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while((read = in.read(buffer)) != -1){
out.write(buffer, 0, read);
}
}
Even though the the previous MainApplication.class copied both english and nepali trained data to the app directory, the nep.traineddata failed to initialized. this method, however did the same thing but it made things work.
I have a strange problem. I'm developing an Android app which has 3 independent Async Tasks. When I try to run the app on a quad core phone there is no problem. But if I try to run the app on a dual core phone app crashes. How can I modify my tasks for dual core phones ?
Here is my code
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, mLoaderCallback);
This is the first async task. The second one is the Parse.com file upload async saveInBackground method.
public void startUpload(String fileName) {
try {
photoFile = new ParseFile(fileName, scaledData);
if (isTac) {
pictures.setPhotoFileTac(photoFile);
} else if (isCanak) {
pictures.setPhotoFileCanak(photoFile);
} else if (isYaprak) {
pictures.setPhotoFileYaprak(photoFile);
}
// pictures.save();// Telefon çekirdeğine göre 2 asenkron methodu desteklemiyor o yüzden sadece save yazılabilir fakat başarılı kontolü SaveCallback' te yakalanamaz.
pictures.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if(e == null){
Toast.makeText(getApplicationContext(),"Buluta yükleme başarılı. " , Toast.LENGTH_LONG).show();
if(pdialog != null)
{
pdialog.dismiss();//Eğer işlem başarılı ise asenkron sınıfta yaratılan progressbar ı kapat.
}
}
else{
Toast.makeText(getApplicationContext(),"Hata" +e.toString(),Toast.LENGTH_LONG).show();
}
}
});
}
catch (Exception ex)
{
Toast.makeText(getApplicationContext(),"Bağlantı Hatası !",Toast.LENGTH_LONG).show();
}
}
And the third one is the progress bar of upload process.
public class AsyncUpload extends AsyncTask<String,Void,String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pdialog = new ProgressDialog(TakePictureActivity.this);
pdialog.setMessage("Yükleniyor...");
pdialog.setIndeterminate(false);
pdialog.setCancelable(false);
pdialog.show();
}
#Override
protected String doInBackground(String... fileNames) {
return fileNames[0];
}
#Override
protected void onPostExecute(String name) {
startUpload(name);
super.onPostExecute(name);
}
}
And there is the code where I initialize upload session. (In if - else condition states the line new AsyncUpload().execute(fileName);
private void saveScaledPhoto(byte[] data) {
// Resize photo from camera byte array
pictureWidth = camera.getParameters().getPictureSize().width;
pictureHeight = camera.getParameters().getPictureSize().height;
Bitmap plantImage = BitmapFactory.decodeByteArray(data, 0, data.length);
Bitmap plantImageScaled = Bitmap.createScaledBitmap(plantImage, pictureWidth, pictureHeight, false);
pictureCache = new PictureCache();
// Override Android default landscape orientation and save portrait
Matrix matrix = new Matrix();
matrix.postRotate(90);
Bitmap rotatedScaledPlantImage = Bitmap.createBitmap(plantImageScaled, 0,
0, plantImageScaled.getWidth(), plantImageScaled.getHeight(),
matrix, true);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
rotatedScaledPlantImage.compress(Bitmap.CompressFormat.PNG, 100, bos);
scaledData = bos.toByteArray();
AlertDialog.Builder aDB = new AlertDialog.Builder(this);
aDB.setCancelable(false);
aDB.setTitle("Emin misiniz ?");
aDB.setMessage("Çektiğiniz resim analizde kullanılacaktır. Devam etmek istiyor musunuz ?.. ");
aDB.setPositiveButton("Evet", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (isTac) {
pictureCache.setByteArrayTac(scaledData);
isTac = false;
isCanak = true;
Toast.makeText(getApplicationContext(), "Taç yaprak görüntüsü alındı.", Toast.LENGTH_LONG).show();
String currentTimeStamp = getCurrentTimeStamp();
fileName = "TacYaprak";
new AsyncUpload().execute(fileName);
} else if (isCanak) {
pictureCache.setByteArrayCanak(scaledData);
isCanak = false;
isYaprak = true;
Toast.makeText(getApplicationContext(), "Çanak yaprak görüntüsü alındı.", Toast.LENGTH_LONG).show();
String currentTimeStamp = getCurrentTimeStamp();
fileName = "CanakYaprak";
new AsyncUpload().execute(fileName);
} else if (isYaprak) {
String plantTag = "A_Y";
pictureCache.setByteArrayYaprak(scaledData);
isYaprak = false;
Toast.makeText(getApplicationContext(), "Ağaç yaprağı görüntüsü alındı.", Toast.LENGTH_LONG).show();
String currentTimeStamp = getCurrentTimeStamp();
fileName = "AgacYapragi";
new AsyncUpload().execute(fileName);
}
if (!isTac && !isCanak && !isYaprak) {
finish();
}
}
});
aDB.setNegativeButton("Hayır", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
AlertDialog alertDialog = aDB.create();
alertDialog.show();
}
Here is the logcat output..
java.lang.NullPointerException
at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:482)
at com.altygtsoft.biomatch.TakePictureActivity.saveScaledPhoto(TakePictureActivity.java:202)
at com.altygtsoft.biomatch.TakePictureActivity.access$000(TakePictureActivity.java:45)
at com.altygtsoft.biomatch.TakePictureActivity$2$1$2.onPictureTaken(TakePictureActivity.java:147)
at android.hardware.Camera$EventHandler.handleMessage(Camera.java:855)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5371)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
at dalvik.system.NativeStart.main(Native Method)
Just realized my idea is too big for a comment so->
What happens if you do the following?
//Beware pseudo-code
new AsyncTask<>({
onPreExecute(){
//keep your code from before
...
}
doInBackground(Params... params){
startUpload(params[0], params[1]); //minus the done() function, plus pictures?
}
onPostExecute(){
//As I'm not sure where it fits in, if possible execute done() here.
}
}).execute(fileName, pictures); //couldn't find the decleration of pictures, so I stole the decleration of independence instead. Also maybe you need to put pictures in there, depending on where it is and how public/static.
I am working on the Bluetooth based project.I am using tabs for including different pages.While including button onclick listener the app is crashed. I referred bluetooth chat from sdk. In Setupchat() I am trying to identify buttons and assigning onclicklisteners. But the app crashed at the onclicklistner. I checked logcat Its showing null pointer exception. Here is the logcat output.
08-11 16:25:08.003: E/AndroidRuntime(16481): FATAL EXCEPTION: main
08-11 16:25:08.003: E/AndroidRuntime(16481): Process: com.dispenser, PID: 16481
08-11 16:25:08.003: E/AndroidRuntime(16481): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.dispenser/com.dispenser.MainActivity}: java.lang.NullPointerException
08-11 16:25:08.003: E/AndroidRuntime(16481): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2198)
08-11 16:25:08.003: E/AndroidRuntime(16481): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2257)
08-11 16:25:08.003: E/AndroidRuntime(16481): at android.app.ActivityThread.access$800(ActivityThread.java:139)
08-11 16:25:08.003: E/AndroidRuntime(16481): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1210)
08-11 16:25:08.003: E/AndroidRuntime(16481): at android.os.Handler.dispatchMessage(Handler.java:102)
08-11 16:25:08.003: E/AndroidRuntime(16481): at android.os.Looper.loop(Looper.java:136)
08-11 16:25:08.003: E/AndroidRuntime(16481): at android.app.ActivityThread.main(ActivityThread.java:5086)
08-11 16:25:08.003: E/AndroidRuntime(16481): at java.lang.reflect.Method.invokeNative(Native Method)
08-11 16:25:08.003: E/AndroidRuntime(16481): at java.lang.reflect.Method.invoke(Method.java:515)
08-11 16:25:08.003: E/AndroidRuntime(16481): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
08-11 16:25:08.003: E/AndroidRuntime(16481): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
08-11 16:25:08.003: E/AndroidRuntime(16481): at dalvik.system.NativeStart.main(Native Method)
08-11 16:25:08.003: E/AndroidRuntime(16481): Caused by: java.lang.NullPointerException
08-11 16:25:08.003: E/AndroidRuntime(16481): at com.dispenser.MainActivity.setupChat(MainActivity.java:223)
08-11 16:25:08.003: E/AndroidRuntime(16481): at com.dispenser.MainActivity.onStart(MainActivity.java:195)
08-11 16:25:08.003: E/AndroidRuntime(16481): at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1194)
08-11 16:25:08.003: E/AndroidRuntime(16481): at android.app.Activity.performStart(Activity.java:5258)
08-11 16:25:08.003: E/AndroidRuntime(16481): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2171)
08-11 16:25:08.003: E/AndroidRuntime(16481): ... 11 more
I know when this nullpointerexception comes. if i use the button without identify the button, The nullpointerexception raises. But I really don't know what is this. Please help me out.
This is the 195th line and 223
package com.dispenser;
import android.annotation.SuppressLint;
import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.Activity;
import android.app.FragmentTransaction;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.dispenser.adapter.TabsPagerAdapter;
public class MainActivity extends FragmentActivity implements ActionBar.TabListener, OnClickListener {
private ViewPager viewPager;
private TabsPagerAdapter mTabAdapter;
private ActionBar actionBar;
// Tab titles
private String[] tabs = { "Diagnostic", "Set" ,"Settings"};
// Debugging
private static final String TAG = "Main";
private static final boolean D = true;
// Message types sent from the BluetoothChatService Handler
public static final int MESSAGE_STATE_CHANGE = 1;
public static final int MESSAGE_READ = 2;
public static final int MESSAGE_WRITE = 3;
public static final int MESSAGE_DEVICE_NAME = 4;
public static final int MESSAGE_TOAST = 5;
// Key names received from the BluetoothChatService Handler
public static final String DEVICE_NAME = "device_name";
public static final String TOAST = "toast";
// Intent request codes
private static final int REQUEST_CONNECT_DEVICE = 1;
private static final int REQUEST_ENABLE_BT = 2;
// Layout Views
//private TextView mTitle;
private EditText mPS1,mPS2,mPS3,mFT,mFW,valve1,valve2,sPS1,sPS2,sPS3;
private Button mSendButtonOn,mEnable,mDisable,mSet;
private Button mSendButtonOff;
// Name of the connected device
private String mConnectedDeviceName;
// String buffer for outgoing messages
private StringBuffer mOutStringBuffer;
// Local Bluetooth adapter
private BluetoothAdapter mBluetoothAdapter;
// Member object for the chat services
private ChatService mChatService;
#SuppressLint("NewApi")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (D) {
Log.e(TAG, "+++ ON CREATE +++");
}
// Set up the window layout
//requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
setContentView(R.layout.activity_main);
// getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,
// R.layout.custom_title);
// Set up the custom title
// mTitle = (TextView) findViewById(R.id.title_left_text);
// mTitle.setText(R.string.app_name);
// mTitle = (TextView) findViewById(R.id.title_right_text);
// Get local Bluetooth adapter
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
// If the adapter is null, then Bluetooth is not supported
if (mBluetoothAdapter == null) {
Toast.makeText(this, "Bluetooth is not available",
Toast.LENGTH_LONG).show();
finish();
return;
}
// Initialization
viewPager = (ViewPager) findViewById(R.id.pager);
actionBar = getActionBar();
mTabAdapter = new TabsPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(mTabAdapter);
actionBar.setHomeButtonEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Adding Tabs
for (String tab_name : tabs) {
actionBar.addTab(actionBar.newTab().setText(tab_name)
.setTabListener(this));
}
/**
* on swiping the viewpager make respective tab selected
* */
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
// on changing the page
// make respected tab selected
actionBar.setSelectedNavigationItem(position);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
// on tab selected
// show respected fragment view
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.scan:
// Launch the DeviceListActivity to see devices and do scan
Intent serverIntent = new Intent(this, DeviceListActivity.class);
startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE);
return true;
case R.id.discoverable:
// Ensure this device is discoverable by others
ensureDiscoverable();
return true;
}
return false;
}
#Override
public void onStart() {
super.onStart();
if (D) {
Log.e(TAG, "++ ON START ++");
}
// If BT is not on, request that it be enabled.
// setupChat() will then be called during onActivityResult
if (!mBluetoothAdapter.isEnabled()) {
Intent enableIntent = new Intent(
BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
// Otherwise, setup the chat session
} else {
if (mChatService == null) {
setupChat();
}
}
}
private void setupChat() {
mSet=(Button) findViewById(R.id.setBtn);
Log.d(TAG, "setupChat()");
// Diagnostic
mPS1=(EditText) findViewById(R.id.ps1);
mPS2=(EditText) findViewById(R.id.ps2);
mPS3=(EditText) findViewById(R.id.ps3);
mFT=(EditText) findViewById(R.id.ft);
mFW=(EditText) findViewById(R.id.fw);
valve1=(EditText) findViewById(R.id.valve1);
valve2=(EditText) findViewById(R.id.valve2);
//Set
sPS1=(EditText) findViewById(R.id.pressure1);
sPS2=(EditText) findViewById(R.id.pressure2);
sPS3=(EditText) findViewById(R.id.pressure3);
// mSet.setOnClickListener(MainActivity.this);
// Preference
// mSendButtonOff.setOnClickListener(MainActivity.this);
// Initialize the BluetoothChatService to perform bluetooth connections
mChatService = new ChatService(this, mHandler);
// Initialize the buffer for outgoing messages
mOutStringBuffer = new StringBuffer("");
}
#Override
public synchronized void onResume() {
super.onResume();
if (D) {
Log.e(TAG, "+ ON RESUME +");
}
// Performing this check in onResume() covers the case in which BT was
// not enabled during onStart(), so we were paused to enable it...
// onResume() will be called when ACTION_REQUEST_ENABLE activity
// returns.
if (mChatService != null) {
// Only if the state is STATE_NONE, do we know that we haven't
// started already
if (mChatService.getState() == ChatService.STATE_NONE) {
// Start the Bluetooth chat services
mChatService.start();
}
}
}
#Override
public synchronized void onPause() {
super.onPause();
if (D) {
Log.e(TAG, "- ON PAUSE -");
}
}
#Override
public void onDestroy() {
super.onDestroy();
// Stop the Bluetooth chat services
if (mChatService != null) {
mChatService.stop();
}
if (D) {
Log.e(TAG, "--- ON DESTROY ---");
}
}
private void ensureDiscoverable() {
if (D) {
Log.d(TAG, "ensure discoverable");
}
if (mBluetoothAdapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
Intent discoverableIntent = new Intent(
BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(
BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);
}
}
/**
* Sends a message.
*
* #param message
* A string of text to send.
*/
private void sendMessage(String message) {
// Check that we're actually connected before trying anything
if (mChatService.getState() != ChatService.STATE_CONNECTED) {
Toast.makeText(this, R.string.not_connected, Toast.LENGTH_SHORT)
.show();
return;
}
// Check that there's actually something to send
if (message.length() > 0) {
// XXX !!!
message = message + "\r\n"; // terminate for pc bluetooth spp server
// Get the message bytes and tell the BluetoothChatService to write
byte[] send = message.getBytes();
mChatService.write(send);
// Reset out string buffer to zero and clear the edit text field
mOutStringBuffer.setLength(0);
// mOutEditText.setText(mOutStringBuffer);
}
}
// The Handler that gets information back from the BluetoothChatService
private final Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_STATE_CHANGE:
if (D) {
Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
}
switch (msg.arg1) {
case ChatService.STATE_CONNECTED:
Toast.makeText(getBaseContext(), R.string.title_connected_to+" " +mConnectedDeviceName, Toast.LENGTH_LONG).show();
// mTitle.append();
// mConversationArrayAdapter.clear();
break;
case ChatService.STATE_CONNECTING:
Toast.makeText(getBaseContext(), R.string.title_connecting, Toast.LENGTH_LONG).show();
break;
case ChatService.STATE_LISTEN:
case ChatService.STATE_NONE:
Toast.makeText(getBaseContext(), R.string.title_not_connected, Toast.LENGTH_LONG).show();
//mTitle.setText();
break;
}
break;
case MESSAGE_WRITE:
byte[] writeBuf = (byte[]) msg.obj;
// construct a string from the buffer
String writeMessage = new String(writeBuf);
// mConversationArrayAdapter.add("Me: " + writeMessage);
break;
case MESSAGE_READ:
byte[] readBuf = (byte[]) msg.obj;
// construct a string from the valid bytes in the buffer
final String readMessage = new String(readBuf, 0, 50);
// mConversationArrayAdapter.add(mConnectedDeviceName + ": "
// + readMessage);
Runnable done = new Runnable()
{
public void run()
{
String[] b=readMessage.split(",");
for(int i=0;i<b.length;i++){
// Toast.makeText(getBaseContext(), b[i], Toast.LENGTH_SHORT).show();
if(b[i].contains("PS1")){
String[] c=b[i].split("=");
if(c.length==2){
mPS1.setText(c[1]);
}
}
else if(b[i].contains("PS2")){
String[] c=b[i].split("=");
if(c.length==2){
mPS2.setText(c[1]);
}
}
else if(b[i].contains("PS3")){
String[] c=b[i].split("=");
if(c.length==2){
mPS3.setText(c[1]);
}
}
else if(b[i].contains("LPM")){
String[] c=b[i].split("=");
if(c.length==2){
mFW.setText(c[1]);
}
}
else{
}
// mPS1.append(b[i]);
}
}
};
done.run();
break;
case MESSAGE_DEVICE_NAME:
// save the connected device's name
mConnectedDeviceName = msg.getData().getString(DEVICE_NAME);
Toast.makeText(getApplicationContext(),
"Connected to " + mConnectedDeviceName,
Toast.LENGTH_SHORT).show();
break;
case MESSAGE_TOAST:
Toast.makeText(getApplicationContext(),
msg.getData().getString(TOAST), Toast.LENGTH_SHORT)
.show();
break;
}
}
};
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (D) {
Log.d(TAG, "onActivityResult " + resultCode);
}
switch (requestCode) {
case REQUEST_CONNECT_DEVICE:
// When DeviceListActivity returns with a device to connect
if (resultCode == Activity.RESULT_OK) {
// Get the device MAC address
String address = data.getExtras().getString(
DeviceListActivity.EXTRA_DEVICE_ADDRESS);
// Get the BLuetoothDevice object
BluetoothDevice device = mBluetoothAdapter
.getRemoteDevice(address);
// Attempt to connect to the device
mChatService.connect(device);
}
break;
case REQUEST_ENABLE_BT:
// When the request to enable Bluetooth returns
if (resultCode == Activity.RESULT_OK) {
// Bluetooth is now enabled, so set up a chat session
setupChat();
} else {
// User did not enable Bluetooth or an error occured
Log.d(TAG, "BT not enabled");
Toast.makeText(this, R.string.bt_not_enabled_leaving,
Toast.LENGTH_SHORT).show();
finish();
}
}
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.setBtn:
if(sPS1.getText().length()!=0){
float pressure1=Float.parseFloat(sPS1.getText().toString());
if(pressure1>0.0F && pressure1<20.0F)
sendMessage("PS1="+pressure1);
}
else{
sPS1.setError("Enter PS1");
}
if(sPS2.getText().length()!=0){
float pressure2=Float.parseFloat(sPS2.getText().toString());
if(pressure2>0.0F && pressure2<20.0F)
sendMessage("PS2="+pressure2);
}
else{
sPS2.setError("Enter PS2");
}
if(sPS3.getText().length()!=0){
float pressure3=Float.parseFloat(sPS3.getText().toString());
if(pressure3>0.0F && pressure3<20.0F)
sendMessage("PS3="+pressure3);
}
else{
sPS3.setError("Enter PS3");
}
break;
default:
break;
}
}
}
You haven't instantiated your button
To use the onClickListener() of button, you should make it's instance in java file
From question: If i use the button without identify the button
You need to do the following:
Button button = (Button) findViewById(R.id.button_identity);
Bottom Line: You should have identity either from XML or from java code.
Hope it works.
The mistake what I made is I tried to include onclicklistener in Mainactivity Instead of including each tab activity. I removed the onclick listener from MainActivity and identify the button and included onclicklistner in corresponding activity tab. Thats solved my problem.
Have a problem while developing an app based in the BluetoothChat example, but divided in 2 activities.
The main with bluetooth actions ()BTActivity
The chat (BTCommunication)
I have the BluetoothChatService too divided in the following files, but they aren't activities:
Transmission: All the Handler actions
ConnectThread
ConnectedThread
AccpetThread
The app finds de device, starts connecting it and then crashes. I'm trying to find out what i'm doing wrong comparing with the BluetoothChat App, but i don't find the problem.
07-23 10:58:43.076: D/AbsListView(17279): unregisterIRListener() is called
07-23 10:58:43.076: D/AbsListView(17279): unregisterIRListener() is called
07-23 10:58:43.086: D/BluetoothUtils(17279): isSocketAllowedBySecurityPolicy start : device null
07-23 10:58:43.086: W/BluetoothAdapter(17279): getBluetoothService() called with no BluetoothManagerCallback
07-23 10:58:43.106: E/SpannableStringBuilder(17279): SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length
07-23 10:58:43.106: E/SpannableStringBuilder(17279): SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length
07-23 10:58:43.116: D/AbsListView(17279): onDetachedFromWindow
07-23 10:58:43.116: D/AbsListView(17279): unregisterIRListener() is called
07-23 10:58:43.116: D/AbsListView(17279): onDetachedFromWindow
07-23 10:58:43.116: D/AbsListView(17279): unregisterIRListener() is called
07-23 10:58:44.527: D/AndroidRuntime(17279): Shutting down VM
07-23 10:58:44.527: W/dalvikvm(17279): threadid=1: thread exiting with uncaught exception (group=0x41d58ac8)
07-23 10:58:44.537: E/AndroidRuntime(17279): FATAL EXCEPTION: main
07-23 10:58:44.537: E/AndroidRuntime(17279): java.lang.NullPointerException
07-23 10:58:44.537: E/AndroidRuntime(17279): at com.example.btaplication.BTActivity$1.handleMessage(BTActivity.java:288)
07-23 10:58:44.537: E/AndroidRuntime(17279): at android.os.Handler.dispatchMessage(Handler.java:99)
07-23 10:58:44.537: E/AndroidRuntime(17279): at android.os.Looper.loop(Looper.java:137)
07-23 10:58:44.537: E/AndroidRuntime(17279): at android.app.ActivityThread.main(ActivityThread.java:5328)
07-23 10:58:44.537: E/AndroidRuntime(17279): at java.lang.reflect.Method.invokeNative(Native Method)
07-23 10:58:44.537: E/AndroidRuntime(17279): at java.lang.reflect.Method.invoke(Method.java:511)
07-23 10:58:44.537: E/AndroidRuntime(17279): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
07-23 10:58:44.537: E/AndroidRuntime(17279): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
07-23 10:58:44.537: E/AndroidRuntime(17279): at dalvik.system.NativeStart.main(Native Method)
07-23 10:58:55.428: I/Process(17279): Sending signal. PID: 17279 SIG: 9
/ Here the Main activity
public class BTActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final Button button1 = (Button) findViewById(R.id.boton1);
final Button button2 = (Button) findViewById(R.id.boton2);
final Button button4 = (Button) findViewById(R.id.boton4);
final Button button5 = (Button) findViewById(R.id.boton5);
button5.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
lanzarComunicacion (null);
}
});
GlobalVar.mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (GlobalVar.mBluetoothAdapter == null) {
Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).show();
finish();
return;
}
button2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
LanzarBusqueda(null);
}
});
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!GlobalVar.mBluetoothAdapter.isDiscovering()) {
Context context = getApplicationContext();
CharSequence text = "MAKING YOUR DEVICE DISCOVERABLE";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);
}
}
});
button4.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
GlobalVar.mBluetoothAdapter.disable();
Context context = getApplicationContext();
CharSequence text = "TURNING OFF BLUETOOTH";
int duration = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(context, text, 15);
toast.show();
}
});
}
#Override
public void onStart() {
super.onStart();
if (!GlobalVar.mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, GlobalVar.REQUEST_ENABLE_BT);
}
else {
if (GlobalVar.mTransmission == null) setupCaller();
}
}
#Override
public void onResume() {
super.onResume();
if (GlobalVar.mTransmission != null) {
/**Only if the state is STATE_NONE, do we know that we haven't started already*/
if (GlobalVar.mTransmission.getState() == GlobalVar.STATE_NONE) {
}
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case GlobalVar.REQUEST_CONNECT_DEVICE:
/**When DeviceListActivity returns with a device to connect*/
if (resultCode == Activity.RESULT_OK) {
connectDevice(data);
}
case GlobalVar.REQUEST_ENABLE_BT:
/**When the request to enable Bluetooth returns*/
if (resultCode == Activity.RESULT_OK) {
/**Bluetooth is now enabled, so set up a chat session*/
setupCaller();
} else {
/**User did not enable Bluetooth or an error occurred*/
Toast.makeText(this, R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show();
finish();
}
break;
}
}
private void connectDevice(Intent data) {
/**Get the device MAC address*/
String address = data.getExtras().getString(DeviceListDialog.EXTRA_DEVICE_ADDRESS);
/**Get the BluetoothDevice object*/
BluetoothDevice device = GlobalVar.mBluetoothAdapter.getRemoteDevice(address);
/**Attempt to connect to the device*/
try{
GlobalVar.mTransmission.connect(device);
}catch(Exception ex) {
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
/**Inflate the menu; this adds items to the action bar if it is present.*/
getMenuInflater().inflate(R.menu.bt, menu);
return true;
}
public void lanzarComunicacion (View view) {
Intent i = new Intent(this, BTCommunication.class);
startActivity(i);
}
public void LanzarBusqueda (View view) {
Intent serverintent = new Intent(this, DeviceListDialog.class);
startActivityForResult(serverintent, GlobalVar.REQUEST_CONNECT_DEVICE);
}
private final void setStatus(int resId) {
final ActionBar actionBar = getActionBar();
actionBar.setSubtitle(resId);
}
private final void setStatus(CharSequence subTitle) {
final ActionBar actionBar = getActionBar();
actionBar.setSubtitle(subTitle);
}
/**
* The Handler that gets information back from the Transmission
*/
private final Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case GlobalVar.MESSAGE_STATE_CHANGE:
switch (msg.arg1) {
case GlobalVar.STATE_CONNECTED:
setStatus(getString(R.string.title_connected_to, GlobalVar.mConnectedDeviceName));
GlobalVar.mConversationArrayAdapter.clear();
break;
case GlobalVar.STATE_CONNECTING:
setStatus(R.string.title_connecting);
break;
case GlobalVar.STATE_LISTEN:
case GlobalVar.STATE_NONE:
setStatus(R.string.title_not_connected);
break;
}
break;
case GlobalVar.MESSAGE_WRITE:
byte[] writeBuf = (byte[]) msg.obj;
/**construct a string from the buffer*/
String writeMessage = new String(writeBuf);
GlobalVar.mConversationArrayAdapter.add("Me: " + writeMessage);
break;
case GlobalVar.MESSAGE_READ:
byte[] readBuf = (byte[]) msg.obj;
/**construct a string from the valid bytes in the buffer*/
String readMessage = new String(readBuf, 0, msg.arg1);
GlobalVar.mConversationArrayAdapter.add(GlobalVar.mConnectedDeviceName+": " + readMessage);
break;
case GlobalVar.MESSAGE_DEVICE_NAME:
/**save the connected device's name*/
GlobalVar.mConnectedDeviceName = msg.getData().getString(GlobalVar.DEVICE_NAME);
Toast.makeText(getApplicationContext(), "Connected to " + GlobalVar.mConnectedDeviceName, Toast.LENGTH_SHORT).show();
break;
case GlobalVar.MESSAGE_TOAST:
Toast.makeText(getApplicationContext(), msg.getData().getString(GlobalVar.TOAST), Toast.LENGTH_SHORT).show();
break;
}
}
};
public void setupCaller() {
/**Initialize the Transmission to perform bluetooth connections*/
GlobalVar.mTransmission = new Transmission(this, mHandler);
}
}
/ The Chat Avtivity
public class BTCommunication extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/**Set up the window layout*/
setContentView(R.layout.chat);
/**Start the Bluetooth chat services*/
GlobalVar.mTransmission.start();
setupChat(); //PROBAMOS A LLAMAR AQUI\\
}
public void setupChat() {
/**Initialize the array adapter for the conversation thread*/
GlobalVar.mConversationArrayAdapter = new ArrayAdapter<String>(this, R.layout.message);
GlobalVar.mConversationView = (ListView) findViewById(R.id.in);
GlobalVar.mConversationView.setAdapter(GlobalVar.mConversationArrayAdapter);
/**Initialize the compose field with a listener for the return key*/
GlobalVar.mOutEditText = (EditText) findViewById(R.id.edit_text_out);
GlobalVar.mOutEditText.setOnEditorActionListener(mWriteListener);
/**Initialize the send button with a listener that for click events*/
GlobalVar.mSendButton = (Button) findViewById(R.id.button_send);
GlobalVar.mSendButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
/**Send a message using content of the edit text widget*/
TextView view = (TextView) findViewById(R.id.edit_text_out);
String message = view.getText().toString();
sendMessage(message);
}
});
/**Initialize the Transmission to perform bluetooth connections*/
//Done it in BTActivity in the function "setupCaller()"\\
/**Initialize the buffer for outgoing messages*/
GlobalVar.mOutStringBuffer = new StringBuffer("");
}
#Override
public void onDestroy() {
super.onDestroy();
/**Stop the Bluetooth chat services*/
if (GlobalVar.mTransmission != null) GlobalVar.mTransmission.stop();
}
/**
* Sends a message.
* #param message A string of text to send.
*/
public void sendMessage(String message) {
/**Check that we're actually connected before trying anything*/
if (GlobalVar.mTransmission.getState() != GlobalVar.STATE_CONNECTED) {
Toast.makeText(this, R.string.not_connected, Toast.LENGTH_SHORT).show();
return;
}
/**Check that there's actually something to send*/
if (message.length() > 0) {
/**Get the message bytes and tell the BluetoothChatService to write*/
byte[] send = message.getBytes();
GlobalVar.mTransmission.write(send);
/**Reset out string buffer to zero and clear the edit text field*/
GlobalVar.mOutStringBuffer.setLength(0);
GlobalVar. mOutEditText.setText(GlobalVar.mOutStringBuffer);
}
}
/**The action listener for the EditText widget, to listen for the return key*/
private final TextView.OnEditorActionListener mWriteListener = new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView view, int actionId, KeyEvent event) {
/**If the action is a key-up event on the return key, send the message*/
if (actionId == EditorInfo.IME_NULL && event.getAction() == KeyEvent.ACTION_UP) {
String message = view.getText().toString();
sendMessage(message);
}
return true;
}
};
}
/The Transmission file:
public class Transmission {
/**
* Constructor. Prepares a new session.
* #param context The UI Activity Context
* #param handler A Handler to send messages back to the UI Activity
*/
public Transmission(Context context, Handler handler) {
GlobalVar.mAdapter = BluetoothAdapter.getDefaultAdapter();
GlobalVar.mState = GlobalVar.STATE_NONE;
GlobalVar.mHandler = handler;
}
/**
* Set the current state of the connection
* #param state An integer defining the current connection state
*/
public synchronized void setState(int state) {
GlobalVar.mState = state;
/**Give the new state to the Handler so the UI Activity can update*/
GlobalVar.mHandler.obtainMessage(GlobalVar.MESSAGE_STATE_CHANGE, state, -1).sendToTarget();
}
/**
* Return the current connection state.
*/
public synchronized int getState() {
return GlobalVar.mState;
}
/**
* Start the chat service. Specifically start AcceptThread to begin a
* session in listening (server) mode. Called by the Activity onResume()
*/
public synchronized void start() {
/**Cancel any thread attempting to make a connection*/
if (GlobalVar.mConnectThread != null) {GlobalVar.mConnectThread.cancel(); GlobalVar.mConnectThread = null;}
/**Cancel any thread currently running a connection*/
if (GlobalVar.mConnectedThread != null) {GlobalVar.mConnectedThread.cancel(); GlobalVar.mConnectedThread = null;}
setState(GlobalVar.STATE_LISTEN);
/**Start the thread to listen on a BluetoothServerSocket*/
if (GlobalVar.mAcceptThread == null) {
GlobalVar.mAcceptThread = new AcceptThread();
GlobalVar.mAcceptThread.start();
}
}
/**
* Start the ConnectThread to initiate a connection to a remote device.
* #param device The BluetoothDevice to connect
*/
public synchronized void connect(BluetoothDevice device) {
/**Cancel any thread attempting to make a connection*/
if (GlobalVar.mState == GlobalVar.STATE_CONNECTING) {
if (GlobalVar.mConnectThread != null) {GlobalVar.mConnectThread.cancel(); GlobalVar.mConnectThread = null;}
}
/**Cancel any thread currently running a connection*/
if (GlobalVar.mConnectedThread != null) {GlobalVar.mConnectedThread.cancel(); GlobalVar.mConnectedThread = null;}
/**Start the thread to connect with the given device*/
GlobalVar.mConnectThread = new ConnectThread(device);
GlobalVar.mConnectThread.start();
setState(GlobalVar.STATE_CONNECTING);
}
/**
* Start the ConnectedThread to begin managing a Bluetooth connection
* #param socket The BluetoothSocket on which the connection was made
* #param device The BluetoothDevice that has been connected
*/
public synchronized void connected(BluetoothSocket socket, BluetoothDevice device) {
/**Cancel the thread that completed the connection*/
if (GlobalVar.mConnectThread != null) {GlobalVar.mConnectThread.cancel(); GlobalVar.mConnectThread = null;}
/**Cancel any thread currently running a connection*/
if (GlobalVar.mConnectedThread != null) {GlobalVar.mConnectedThread.cancel(); GlobalVar.mConnectedThread = null;}
/**Cancel the accept thread because we only want to connect to one device*/
if (GlobalVar.mAcceptThread != null) {
GlobalVar.mAcceptThread.cancel();
GlobalVar.mAcceptThread = null;
}
/**Start the thread to manage the connection and perform transmissions*/
GlobalVar.mConnectedThread = new ConnectedThread(socket);
GlobalVar.mConnectedThread.start();
/**Send the name of the connected device back to the UI Activity*/
Message msg = GlobalVar.mHandler.obtainMessage(GlobalVar.MESSAGE_DEVICE_NAME);
Bundle bundle = new Bundle();
bundle.putString(GlobalVar.DEVICE_NAME, device.getName());
msg.setData(bundle);
GlobalVar.mHandler.sendMessage(msg);
setState(GlobalVar.STATE_CONNECTED);
}
/**
* Stop all threads
*/
public synchronized void stop() {
if (GlobalVar.mConnectThread != null) {
GlobalVar.mConnectThread.cancel();
GlobalVar.mConnectThread = null;
}
if (GlobalVar.mConnectedThread != null) {
GlobalVar.mConnectedThread.cancel();
GlobalVar.mConnectedThread = null;
}
if (GlobalVar.mAcceptThread != null) {
GlobalVar.mAcceptThread.cancel();
GlobalVar.mAcceptThread = null;
}
setState(GlobalVar.STATE_NONE);
}
/**
* Write to the ConnectedThread in an unsynchronized manner
* #param out The bytes to write
* #see ConnectedThread#write(byte[])
*/
public void write(byte[] out) {
/**Create temporary object*/
ConnectedThread r;
/**Synchronize a copy of the ConnectedThread*/
synchronized (this) {
if (GlobalVar.mState != GlobalVar.STATE_CONNECTED) return;
r = GlobalVar.mConnectedThread;
}
/**Perform the write unsynchronized*/
r.write(out);
}
/**
* Indicate that the connection attempt failed and notify the UI Activity.
*/
public void connectionFailed() {
/**Send a failure message back to the Activity*/
Message msg = GlobalVar.mHandler.obtainMessage(GlobalVar.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(GlobalVar.TOAST, "Unable to connect device");
msg.setData(bundle);
GlobalVar.mHandler.sendMessage(msg);
/**tart the service over to restart listening mode*/
Transmission.this.start();
}
/**
* Indicate that the connection was lost and notify the UI Activity.
*/
public void connectionLost() {
/**Send a failure message back to the Activity*/
Message msg = GlobalVar.mHandler.obtainMessage(GlobalVar.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(GlobalVar.TOAST, "Device connection was lost");
msg.setData(bundle);
GlobalVar.mHandler.sendMessage(msg);
/**Start the service over to restart listening mode*/
Transmission.this.start();
}
}
/The Accept, connect and connected threads are the same as in BleutoothChat app but each one has it's own file.
07-23 10:58:44.537: E/AndroidRuntime(17279): at com.example.btaplication.BTActivity$1.handleMessage(BTActivity.java:288)
You need more condition in your Handler. It crashes because you have a null pointer in your BTActivity.
I exactly had this problem 2 weeks ago (I was trying to change text of a textview in a Handler). So, in my Handler I just put :
if(mTextView == null) {mTextView = (TextView) findViewById(R.id.tv)}
even if mTextView was define before. In that case you will be sure that your attribute is define, and you will avoid NPE
Hope it helps