Java RuntimeException "Fail to connect to camera service" - java

I have looked at many questions similar to mine on stackoverflow and other websites but have not been able to find a solution for my problem. I have requested the correct permissions but I still am getting this error. At first I thought it was because I was using an AVD but even while using a phone I still get this error.
MainActivity:
package com.example.vishal.textfacialprocessing;
import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.hardware.Camera;
import android.os.Bundle;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.Toast;
import com.qualcomm.snapdragon.sdk.face.FaceData;
import com.qualcomm.snapdragon.sdk.face.FacialProcessing;
public class MainActivity extends Activity implements Camera.PreviewCallback {
Camera mCamera = null;
CameraPreview preview;
private CameraPreview mPreview = null;
private int cameraside = 1;
private int Front_Camera_Index = 1;
private int Back_Camera_Index = 0;
private static boolean switchCamera;
private boolean _qcSDKEnabled;
FacialProcessing faceProc;
Display display;
private int displayAngle;
private int numFaces;
FaceData[] faceArray = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button switchCameraButton = (Button)
findViewById(R.id.switchCamera);
switchCameraButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (cameraside == 1) {
cameraside = 0;
} else {
cameraside = 1;
}
}
});
setCamera();
}
public void setCamera ()
{
mCamera = Camera.open(cameraside);
mPreview = new CameraPreview(MainActivity.this,mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mPreview);
mCamera.setPreviewCallback(MainActivity.this);
_qcSDKEnabled = FacialProcessing.isFeatureSupported(FacialProcessing.FEATURE_LIST.FEATURE_FACIAL_PROCESSING);
}
}
CameraPreview:
package com.example.vishal.textfacialprocessing;
import android.content.Context;
import android.hardware.Camera;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.ViewGroup;
import com.qualcomm.snapdragon.sdk.face.FacialProcessing;
import java.io.IOException;
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera cameraObj;
public CameraPreview(Context context, Camera camera) {
super(context);
cameraObj = camera;
// Install a urfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
// SurfaceHolder jholder = holder;
// The Surface has been created, now tell the camera where to draw the preview.
try {
cameraObj.setPreviewDisplay(holder);
cameraObj.startPreview();
} catch (IOException e) {
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// empty. Take care of releasing the Camera preview in your activity.
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.
if (mHolder.getSurface() == null){
// preview surface does not exist
return;
}
// stop preview before making changes
try {
cameraObj.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
}
// set preview size and make any resize, rotate or
// reformatting changes here
// start preview with new settings
try {
cameraObj.setPreviewDisplay(mHolder);
cameraObj.startPreview();
} catch (Exception e){
}
}
}
Manifest:
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
Logicat:
01-02 14:27:35.261 10635-10635/com.example.vishal.textfacialprocessing E/Typeface: SANS_LOC file not found.
01-02 14:27:35.321 10635-10635/com.example.vishal.textfacialprocessing E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.vishal.textfacialprocessing, PID: 10635
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.vishal.textfacialprocessing/com.example.vishal.textfacialprocessing.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.hardware.Camera.release()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2411)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2474)
at android.app.ActivityThread.access$800(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1359)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:155)
at android.app.ActivityThread.main(ActivityThread.java:5696)
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:1029)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:824)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.hardware.Camera.release()' on a null object reference
at com.example.vishal.textfacialprocessing.MainActivity.getCameraInstance(MainActivity.java:156)
at com.example.vishal.textfacialprocessing.MainActivity.onResume(MainActivity.java:58)
at com.example.vishal.textfacialprocessing.MainActivity.onCreate(MainActivity.java:50)
at android.app.Activity.performCreate(Activity.java:5958)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1129)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2364)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2474) 
at android.app.ActivityThread.access$800(ActivityThread.java:144) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1359) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:155) 
at android.app.ActivityThread.main(ActivityThread.java:5696) 
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:1029) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:824) 

Hi Vishal you need to add following permission in menifest file
<uses-permission android:name="android.permission.CAMERA" />
If you are using the Android M permission model, you first need to check if the app has this permission during runtime, and have to prompt the user for this permission during runtime. The permission you define on your manifest will not automatically be granted on install time.
if (checkSelfPermission(Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.CAMERA},
MY_REQUEST_CODE);
}
You will need a callback for the dialog result:
#Override
public void onRequestPermissionResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == MY_REQUEST__CODE) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Now user should be able to use camera
}
else {
// Your app will not have this permission. Turn off all functions
// that require this permission or it will force close like your
// original question
}
}
}

Related

Right way of requesting permissions for location coordinates in Android 10

Below code does not work on Android 10 until you manually enable the location from settings. When I go through the Android 10 documentation, it says if you are fetching location from the visible activity, if that was the case you don't need any foreground service, that's the reason I haven't used any service here.
And also as per Android 10 guidelines, after permission getting granted I am calling getLastLocation function.
Implementation is like, on main activity I am fetching location coordinates.
Please help, where in the code am I going wrong?
MainActivity.java
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
import androidx.annotation.NonNull;
import com.google.android.material.snackbar.Snackbar;
import androidx.core.app.ActivityCompat;
import androidx.appcompat.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import java.util.Locale;
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
private static final int REQUEST_PERMISSIONS_REQUEST_CODE = 34;
private FusedLocationProviderClient mFusedLocationClient;
protected Location mLastLocation;
private String mLatitudeLabel;
private String mLongitudeLabel;
private TextView mLatitudeText;
private TextView mLongitudeText;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
mLatitudeLabel = getResources().getString(R.string.latitude_label);
mLongitudeLabel = getResources().getString(R.string.longitude_label);
mLatitudeText = (TextView) findViewById((R.id.latitude_text));
mLongitudeText = (TextView) findViewById((R.id.longitude_text));
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
}
#Override
public void onStart() {
super.onStart();
if (!checkPermissions()) {
requestPermissions();
} else {
getLastLocation();
}
}
#SuppressWarnings("MissingPermission")
private void getLastLocation() {
mFusedLocationClient.getLastLocation()
.addOnCompleteListener(this, new OnCompleteListener<Location>() {
#Override
public void onComplete(#NonNull Task<Location> task) {
if (task.isSuccessful() && task.getResult() != null) {
mLastLocation = task.getResult();
Log.d("raviraj", "lat is " +mLastLocation.getLatitude());
Log.d("raviraj", "long is " +mLastLocation.getLongitude());
mLatitudeText.setText(String.format(Locale.ENGLISH, "%s: %f",
mLatitudeLabel,
mLastLocation.getLatitude()));
mLongitudeText.setText(String.format(Locale.ENGLISH, "%s: %f",
mLongitudeLabel,
mLastLocation.getLongitude()));
} else {
Log.w("RAVIRAJ", "getLastLocation:exception" +task.getException());
showSnackbar(getString(R.string.no_location_detected));
}
}
});
}
private void showSnackbar(final String text) {
View container = findViewById(R.id.main_activity_container);
if (container != null) {
Snackbar.make(container, text, Snackbar.LENGTH_LONG).show();
}
}
private void showSnackbar(final int mainTextStringId, final int actionStringId,
View.OnClickListener listener) {
Snackbar.make(findViewById(android.R.id.content),
getString(mainTextStringId),
Snackbar.LENGTH_INDEFINITE)
.setAction(getString(actionStringId), listener).show();
}
private boolean checkPermissions() {
int permissionState = ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION);
return permissionState == PackageManager.PERMISSION_GRANTED;
}
private void startLocationPermissionRequest() {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_PERMISSIONS_REQUEST_CODE);
}
private void requestPermissions() {
boolean shouldProvideRationale =
ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION);
if (shouldProvideRationale) {
Log.i(TAG, "Displaying permission rationale to provide additional context.");
showSnackbar(R.string.permission_rationale, android.R.string.ok,
new View.OnClickListener() {
#Override
public void onClick(View view) {
// Request permission
startLocationPermissionRequest();
}
});
} else {
Log.i(TAG, "Requesting permission");
startLocationPermissionRequest();
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults) {
Log.i(TAG, "onRequestPermissionResult");
if (requestCode == REQUEST_PERMISSIONS_REQUEST_CODE) {
if (grantResults.length <= 0) {
// If user interaction was interrupted, the permission request is cancelled and you
// receive empty arrays.
Log.i(TAG, "User interaction was cancelled.");
} else if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission granted.
getLastLocation();
} else {
showSnackbar(R.string.permission_denied_explanation, R.string.settings,
new View.OnClickListener() {
#Override
public void onClick(View view) {
// Build intent that displays the App settings screen.
Intent intent = new Intent();
intent.setAction(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package",
BuildConfig.APPLICATION_ID, null);
intent.setData(uri);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
});
}
}
}
}
Manifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.android.gms.location.sample.basiclocationsample" >
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/Theme.Base" >
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="#string/google_maps_key" />
<activity
android:name=".NewMain"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
Well there is a problem. Official documentation states that it can be null in some cases
https://developer.android.com/training/location/retrieve-current
Location is turned off in the device settings. The result could be null even if the last location was previously retrieved because disabling location also clears the cache.
The device never recorded its location, which could be the case of a new device or a device that has been restored to factory settings.
Google Play services on the device has restarted, and there is no active Fused Location Provider client that has requested location after the services restarted. To avoid this situation you can create a new client and request location updates yourself. For more information, see Receiving Location Updates.
In your case you can get location only if GPS is ON. Even for last known location.
https://developer.android.com/training/location/retrieve-current#last-known
Please add this permission in AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
and add this to application tag
android:usesCleartextTraffic="true"

Why do I get ClassCastException when I extend a class?

I'm developing an app which can read data from a Bluetooth RFID Reader, but everytime i start the BluetoothActivity (it's a tabbed activity), it always shows a ClassCastException, below is my code..
BluetoothActivity class:
package com.siscaproject.sisca.Activity;
import android.net.Uri;
import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar;
import android.support.design.widget.TabLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.siscaproject.sisca.Fragment.RegisterFragment;
import com.siscaproject.sisca.Fragment.SearchFragment;
import com.siscaproject.sisca.R;
import com.siscaproject.sisca.Utilities.FamsModel;
import com.siscaproject.sisca.Utilities.TSLBluetoothDeviceActivity;
import com.siscaproject.sisca.Utilities.TSLBluetoothDeviceApplication;
import com.uk.tsl.rfid.asciiprotocol.AsciiCommander;
import com.uk.tsl.rfid.asciiprotocol.responders.LoggerResponder;
import java.util.ArrayList;
import butterknife.BindView;
import butterknife.ButterKnife;
public class BluetoothActivity extends TSLBluetoothDeviceActivity {
private SectionsPagerAdapter mSectionsPagerAdapter;
#BindView(R.id.viewpager_bluetooth) ViewPager mViewPager;
#BindView(R.id.toolbar_bluetooth) Toolbar mToolbar;
#BindView(R.id.tab_bluetooth) TabLayout mTabLayout;
private FamsModel mModel;
public AsciiCommander getCommander(){
return ((TSLBluetoothDeviceApplication) getApplication()).getCommander();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bluetooth);
ButterKnife.bind(this);
setSupportActionBar(mToolbar);
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
setupViewPager(mViewPager);
mTabLayout.setupWithViewPager(mViewPager);
AsciiCommander commander = getCommander();
// Add the LoggerResponder - this simply echoes all lines received from the reader to the log
// and passes the line onto the next responder
// This is added first so that no other responder can consume received lines before they are logged.
commander.addResponder(new LoggerResponder());
// Add a synchronous responder to handle synchronous commands
commander.addSynchronousResponder();
}
private void setupViewPager(ViewPager viewPager){
SectionsPagerAdapter adapter = new SectionsPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new RegisterFragment(), "REGISTER");
adapter.addFragment(new SearchFragment(), "SEARCH");
viewPager.setAdapter(adapter);
}
#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_bluetooth, 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.menu_item_reconnect_reader) {
return true;
}
return super.onOptionsItemSelected(item);
}
public static class PlaceholderFragment extends Fragment {
private static final String ARG_SECTION_NUMBER = "section_number";
public PlaceholderFragment() {
}
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_bluetooth, container, false);
TextView textView = (TextView) rootView.findViewById(R.id.section_label);
textView.setText(getString(R.string.section_format, getArguments().getInt(ARG_SECTION_NUMBER)));
return rootView;
}
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
private ArrayList<Fragment> fragmentList = new ArrayList<>();
private ArrayList<String> fragmentTitleList = new ArrayList<>();
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return fragmentList.get(position);
}
#Override
public int getCount() {
// Show 3 total pages.
return fragmentList.size();
}
public void addFragment(Fragment fragment, String title ){
fragmentList.add(fragment);
fragmentTitleList.add(title);
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
return fragmentTitleList.get(position);
}
}
}
TSLBluetoothDeviceActivity class:
package com.siscaproject.sisca.Utilities;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.Toast;
import com.siscaproject.sisca.BuildConfig;
import com.uk.tsl.rfid.DeviceListActivity;
import com.uk.tsl.rfid.asciiprotocol.AsciiCommander;
import java.util.Timer;
import java.util.TimerTask;
public class TSLBluetoothDeviceActivity extends AppCompatActivity {
// Debugging
private static final String TAG = "TSLBTDeviceActivity";
private static final boolean D = BuildConfig.DEBUG;
// Intent request codes
private static final int REQUEST_CONNECT_DEVICE_SECURE = 1;
private static final int REQUEST_CONNECT_DEVICE_INSECURE = 2;
private static final int REQUEST_ENABLE_BT = 3;
// Local Bluetooth adapter
private BluetoothAdapter mBluetoothAdapter = null;
private BluetoothDevice mDevice = null;
protected AsciiCommander getCommander() {
return ((TSLBluetoothDeviceApplication) getApplication()).getCommander();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Get local Bluetooth adapter
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
// Create the AsciiCommander to talk to the reader (if it doesn't already exist)
if (getCommander() == null) {
try {
TSLBluetoothDeviceApplication app = (TSLBluetoothDeviceApplication) getApplication();
AsciiCommander commander = new AsciiCommander(getApplicationContext());
app.setCommander(commander);
} catch (Exception e) {
fatalError("Unable to create AsciiCommander!");
}
}
}
// Terminate the app with the given message
private void fatalError(String message) {
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
Timer t = new Timer();
t.schedule(new TimerTask() {
public void run() {
finish();
}
}, 1800);
}
protected void bluetoothNotAvailableError(String message) {
fatalError(message);
}
#Override
public void onStart() {
super.onStart();
// If no other attempt to connect is ongoing try to connect to last used reader
// Note: When returning from the Device List activity
if (mBluetoothAdapter.isEnabled()) {
if (mDevice == null) {
// Attempt to reconnect to the last reader used
Toast.makeText(this, "Reconnecting to last used reader...", Toast.LENGTH_SHORT).show();
getCommander().connect(null);
}
} else {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
}
#Override
public void onStop() {
super.onStop();
getCommander().disconnect();
mDevice = null;
}
protected void connectToDevice(Intent deviceData, boolean secure) {
Toast.makeText(this.getApplicationContext(), "Connecting...", Toast.LENGTH_LONG).show();
// Get the device MAC address
String address = deviceData.getExtras()
.getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
// Get the BluetoothDevice object
mDevice = mBluetoothAdapter.getRemoteDevice(address);
// Attempt to connect to the device
if (mDevice != null) {
getCommander().connect(mDevice);
} else {
if (D) Log.e(TAG, "Unable to obtain BluetoothDevice!");
}
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (D)
Log.d(TAG, "selectDevice() onActivityResult: " + resultCode + " for request: " + requestCode);
switch (requestCode) {
case REQUEST_CONNECT_DEVICE_SECURE:
// When DeviceListActivity returns with a device to connect
if (resultCode == Activity.RESULT_OK) {
connectToDevice(data, true);
}
break;
case REQUEST_CONNECT_DEVICE_INSECURE:
// When DeviceListActivity returns with a device to connect
if (resultCode == Activity.RESULT_OK) {
connectToDevice(data, false);
}
break;
case REQUEST_ENABLE_BT:
// When the request to enable Bluetooth returns
if (resultCode != Activity.RESULT_OK) {
// User did not enable Bluetooth or an error occurred
Log.d(TAG, "BT not enabled");
bluetoothNotAvailableError("Bluetooth was not enabled\nApplication Quitting...");
}
}
}
public void selectDevice() {
// Launch the DeviceListActivity to see devices and do scan
Intent serverIntent = new Intent(this, DeviceListActivity.class);
startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE_INSECURE);
}
public void disconnectDevice() {
mDevice = null;
getCommander().disconnect();
}
public void reconnectDevice() {
getCommander().connect(null);
}
}
The error log:
11-21 14:47:54.836 18956-18956/com.siscaproject.sisca E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.siscaproject.sisca, PID: 18956
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.siscaproject.sisca/com.siscaproject.sisca.Activity.BluetoothActivity}: java.lang.ClassCastException: android.app.Application cannot be cast to com.siscaproject.sisca.Utilities.TSLBluetoothDeviceApplication
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2318)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2396)
at android.app.ActivityThread.access$800(ActivityThread.java:139)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1293)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:149)
at android.app.ActivityThread.main(ActivityThread.java:5257)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:609)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.ClassCastException: android.app.Application cannot be cast to com.siscaproject.sisca.Utilities.TSLBluetoothDeviceApplication
at com.siscaproject.sisca.Activity.BluetoothActivity.getCommander(BluetoothActivity.java:51)
at com.siscaproject.sisca.Utilities.TSLBluetoothDeviceActivity.onCreate(TSLBluetoothDeviceActivity.java:45)
at com.siscaproject.sisca.Activity.BluetoothActivity.onCreate(BluetoothActivity.java:57)
at android.app.Activity.performCreate(Activity.java:5411)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2270)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2396) 
at android.app.ActivityThread.access$800(ActivityThread.java:139) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1293) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:149) 
at android.app.ActivityThread.main(ActivityThread.java:5257) 
at java.lang.reflect.Method.invokeNative(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:515) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:609) 
at dalvik.system.NativeStart.main(Native Method) 
I've followed this code from an app that works fine, but when I implemented it in my project it always shows this error, I'm not sure what I'm doing wrong.
---EDIT---
TSLBluetoothDeviceApplication class:
package com.siscaproject.sisca.Utilities;
import android.app.Application;
import com.uk.tsl.rfid.asciiprotocol.AsciiCommander;
public class TSLBluetoothDeviceApplication extends Application {
private static AsciiCommander commander = null;
/// Returns the current AsciiCommander
public AsciiCommander getCommander() {
return commander;
}
/// Sets the current AsciiCommander
public void setCommander(AsciiCommander _commander) {
commander = _commander;
}
}
Android Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.siscaproject.sisca">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme"
tools:replace="android:icon">
<activity
android:name=".Activity.LoginActivity"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".Activity.BluetoothTestActivity"
android:theme="#style/StandardTheme" />
<activity
android:name=".Activity.HomeActivity"
android:label="#string/title_activity_home"
android:theme="#style/AppTheme" />
<meta-data
android:name="com.google.android.gms.vision.DEPENDENCIES"
android:value="barcode" />
<activity android:name=".Activity.QRActivity" />
<activity
android:name=".Activity.BluetoothActivity"
android:label="#string/title_activity_bluetooth"
android:theme="#style/AppTheme"></activity>
</application>
</manifest>
getApplication() inside an activity returns an object of type Application. In your case you are trying to cast this object into TSLBluetoothDeviceApplication which, as defined by you, is an Activity type class.
As I see, you are trying to call getCommander() which is defined already in your TSL activity class. I assume you want getCommander() method from another class.. Make sure which one is.
public AsciiCommander getCommander(){
return ((TSLBluetoothDeviceApplication) getApplication()).getCommander();
}
This method is already inside TSLBluetoothDeviceApplication class.. I don't know what are you trying to achieve by trying to call same method which is already in your current class.
EDIT:
After the edited post, we noticed that the class was properly implemented, just forgot to add
android:name="com.path.to.ApplicationClass" into the Manifestfile under <application/> tag.
I will let the above answer also, because it may help others
Happy coding <3
It's clear that your application class is not used. You need to add it to your xml Application tag like this:
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:name="com.siscaproject.sisca.Utilities. TSLBluetoothDeviceApplication"
android:theme="#style/AppTheme"
tools:replace="android:icon">
and the only change is adding android:name="com.siscaproject.sisca.Utilities. TSLBluetoothDeviceApplication" to the Application tag as your customized class.

Android Studio App crashes after adding code for Bluetooth Connection

Im currently working at an app for controlling an arduino via bluetooth. I added some Activitys for menus and so on. Yesterday I added a new Activity for connecting my device to the bluetooth module.
Is it even possible to connect to the device in one activity and actually controlling (sending letters) it in another Activity?
With that said the app crashes every time I try to open the activity with the bluetooth code in it. Every other Activity works without any problem.
I hope somebody can help.
Here is my Code:
MainActivity.java (the activity which will control the module):
package com.car.bluetooth.bluetoothcar;
import android.bluetooth.BluetoothAdapter;
import android.content.Intent;
import android.os.Bundle;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.CheckBox;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
#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();
//MENÜPUNKTE
if (id == R.id.action_settings) {
Intent settingsintent = new Intent(MainActivity.this,
settingsactivity.class);
startActivity(settingsintent);
return false;
}
if (id == R.id.action_connect) {
Intent connectintent = new Intent(MainActivity.this,
connectactivity.class);
startActivity(connectintent);
return false;
}
return super.onOptionsItemSelected(item);
}
//SeekBars
private SeekBar seekBarGas;
private TextView textViewGas;
private SeekBar seekBarSteering;
private TextView textViewSteering;
private CheckBox backwards_checkBox;
boolean rückwärts_var = false;
boolean safeMode;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
seekBarGas = (SeekBar) findViewById(R.id.seekBarGas);
textViewGas = (TextView) findViewById(R.id.textViewGas);
seekBarGas.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
textViewGas.setText(progress + " / " + seekBarGas.getMax());
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
seekBarGas.setProgress(0);
}
});
seekBarSteering = (SeekBar) findViewById(R.id.seekBarSteering);
textViewSteering = (TextView) findViewById(R.id.textViewSteering);
seekBarSteering.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
textViewSteering.setText(progress + " / " + seekBarSteering.getMax());
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
seekBarSteering.setProgress(3);
}
});
//GET DATA Settings
Intent safeMode_Intent = getIntent();
safeMode = safeMode_Intent.getBooleanExtra("safeMode", false);
//Rückwärts
CheckBox backwards_checkBox=(CheckBox)findViewById(R.id.backwards_checkBox);
backwards_checkBox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (((CheckBox)v).isChecked()) {
Toast.makeText(getApplicationContext(), "Rückwärts", Toast.LENGTH_SHORT).show();
rückwärts_var = true;
if (safeMode == true) {
seekBarGas.setMax(2);
}
}
else{
Toast.makeText(getApplicationContext(), "Vorwärts", Toast.LENGTH_SHORT).show();
rückwärts_var = false;
if (safeMode == true){
seekBarGas.setMax(5);
}
}
}
});
//Bluetooth
if (btAdapter == null){
Toast.makeText(getApplicationContext(), "Bluetooth wird auf diesem Gerät nicht unterstützt", Toast.LENGTH_LONG).show();
}
}
}
BT_Classic.java (the activity which connects to the module) :
package com.car.bluetooth.bluetoothcar;
import androidx.appcompat.app.AppCompatActivity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.Set;
public class BT_Classic extends AppCompatActivity {
private Button pairedButton;
private Button discoveredButton;
private Button btonButton;
private Button btoffButton;
ListView list;
private static final int REQUEST_ENABLED = 0;
private static final int REQUEST_DISCOVERABLE = 0;
BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bt__classic);
pairedButton = (Button) findViewById(R.id.pairedButton);
discoveredButton = (Button) findViewById(R.id.discoveredButton);
list = (ListView) findViewById(R.id.list) ;
//Pairing Button
pairedButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Set<BluetoothDevice> pairedDevices = btAdapter.getBondedDevices();
ArrayList<String> devices = new ArrayList<String>();
for (BluetoothDevice bt : pairedDevices){
devices.add(bt.getName());
}
ArrayAdapter arrayAdapter = new ArrayAdapter(BT_Classic.this, android.R.layout.simple_list_item_1, devices);
list.setAdapter(arrayAdapter);
}
});
discoveredButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(!btAdapter.isDiscovering()){
Intent bton = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
startActivityForResult(bton, REQUEST_DISCOVERABLE);
}
}
});
btonButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent bton = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(bton, REQUEST_ENABLED);
}
});
btoffButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
btAdapter.disable();
}
});
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.car.bluetooth.bluetoothcar">
<uses-feature android:name="android.hardware.bluetooth" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".MainActivity"
android:label="Bluetooth Car"
android:screenOrientation="landscape"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".connectactivity"
android:label="Connect"
android:screenOrientation="landscape" />
<activity
android:name=".settingsactivity"
android:label="Settings"
android:screenOrientation="landscape" />
<activity
android:name=".BT_LE"
android:label="Connect Bluetooth Low Energy"
android:screenOrientation="landscape"/>
<activity
android:name=".BT_Classic"
android:label="Connect Bluetooth Classic"
android:screenOrientation="landscape"
></activity>
</application>
build.gradle (Module:app) :
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.car.bluetooth.bluetoothcar"
minSdkVersion '16'
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.0.0-beta01'
implementation 'android.arch.navigation:navigation-fragment:1.0.0-alpha05'
implementation 'android.arch.navigation:navigation-ui:1.0.0-alpha05'
implementation 'androidx.constraintlayout:constraintlayout:1.1.2'
implementation 'com.google.android.material:material:1.0.0-beta01'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.0-alpha4'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0-alpha4'
}
Crashlog:
2018-09-12 17:25:36.957 10178-10178/com.car.bluetooth.bluetoothcar
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.car.bluetooth.bluetoothcar, PID: 10178
java.lang.RuntimeException: Unable to start activity
ComponentInfo{com.car.bluetooth.bluetoothcar/com.car.bluetooth.bluetoothcar.BT_Classic}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2830)
at
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2909)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1606)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6592)
at java.lang.reflect.Method.invoke(Native Method)
at
com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:769)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at com.car.bluetooth.bluetoothcar.BT_Classic.onCreate(BT_Classic.java:78)
at android.app.Activity.performCreate(Activity.java:6984)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1235)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2783)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2909) 
at android.app.ActivityThread.-wrap11(Unknown Source:0) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1606) 
at android.os.Handler.dispatchMessage(Handler.java:105) 
at android.os.Looper.loop(Looper.java:164) 
at android.app.ActivityThread.main(ActivityThread.java:6592) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:769) 
btonButton and btoffButton are not initialized and equals null.
You should initialize them with findViewById() like you do with pairedButton
btonButton = (Button) findViewById(R.id.put_here_btn_on_id);
btoffButton = (Button) findViewById(R.id.put_here_btn_off_id);
btonButton and btoffButton have not been initialised yet and then you are calling setonClickListener this causes NPE
Inside onCreate initialise like this:
btonButton = (Button) findViewById(R.id.btonButton);
btoffButton = (Button) findViewById(R.id.btoffButton);

NullPointerException declaring Intent in extended FragmentActivity

I've been going at this for a while. I've searched and tried everything I've seen. I cannot get this damn activity to event be declared. I have a MarkerActivity for creating markers on my map. When clicked, I want them to open an activity and pass a variable. I've tried everything and keep crashing with a NullPointerException. Code below:
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tapmap.app.tapmapapp" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" /><meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="AIzaSyAksheZLMAALUfLHKWOsfTFCz7iP_KwpCE" />
<activity
android:name=".MapsActivity"
android:label="#string/title_activity_maps" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".BarBrewry"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="#string/title_activity_bar_brewry"
android:theme="#style/FullscreenTheme" >
</activity>
<activity
android:name=".MarkerActivity"
android:label="#string/title_activity_marker">
</activity>
</application>
</manifest>
Marker.java:
package com.tapmap.app.tapmapapp;
import android.content.Intent;
import android.content.IntentSender;
import android.location.Location;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.common.api.GoogleApiClient;
public class MarkerActivity extends android.support.v4.app.FragmentActivity implements GoogleMap.OnMarkerClickListener {
public Marker myMarker;
public LatLng latLng;
public String venueid;
public String venuename;
public String[] taps;
public String address;
public Integer markid;
public void setUpMap() {
MapsActivity.mMap.setOnMarkerClickListener(this);
//googleMap.setOnInfoWindowClickListener(listener);
myMarker = MapsActivity.mMap.addMarker(new MarkerOptions()
.position(latLng)
.title(venuename)
.snippet("Check Taps/Get Directions")
.icon(BitmapDescriptorFactory.fromResource(R.drawable.tmico))
);
}
#Override
public boolean onMarkerClick(final Marker marker) {
Log.i("RetrieveFeedTask", MarkerActivity.this + "Marker Clicked" + MapsActivity.venues.get(markid).venuename);
try {
Intent bar = new Intent(MarkerActivity.this, BarBrewry.class);
// bar.putExtra("venuename", venuename);
//this.startActivity(bar);
} catch(Exception vo) {
Log.i("RetrieveFeedTask", "Error opening: " + vo.getMessage());
}
return true;
}
}
Stack trace:
9153-9153/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.NullPointerException
at android.content.ContextWrapper.getPackageName(ContextWrapper.java:135)
at android.content.ComponentName.<init>(ComponentName.java:75)
at android.content.Intent.<init>(Intent.java:3662)
at com.tapmap.app.tapmapapp.MarkerActivity.onMarkerClick(MarkerActivity.java:50)
at com.google.android.gms.maps.GoogleMap$10.zza(Unknown Source)
at com.google.android.gms.maps.internal.zzn$zza.onTransact(Unknown Source)
at android.os.Binder.transact(Binder.java:347)
at com.google.android.gms.maps.internal.bd.a(SourceFile:84)
at com.google.maps.api.android.lib6.d.as.b(Unknown Source)
at com.google.maps.api.android.lib6.gmm6.c.e.a(Unknown Source)
at com.google.maps.api.android.lib6.gmm6.n.av.a(Unknown Source)
at com.google.maps.api.android.lib6.gmm6.n.be.a(Unknown Source)
at com.google.maps.api.android.lib6.gmm6.n.bd.a(Unknown Source)
at com.google.maps.api.android.lib6.gmm6.n.bt.d(Unknown Source)
at com.google.maps.api.android.lib6.gmm6.n.ak.onSingleTapConfirmed(Unknown Source)
at com.google.maps.api.android.lib6.gmm6.h.g.onSingleTapConfirmed(Unknown Source)
at com.google.maps.api.android.lib6.gmm6.h.i.handleMessage(Unknown Source)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5103)
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:737)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
MapsActivity
package com.tapmap.app.tapmapapp;
import android.content.IntentSender;
import android.location.Location;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.common.api.GoogleApiClient;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class MapsActivity extends FragmentActivity implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener {
public static GoogleMap mMap; // Might be null if Google Play services APK is not available.
private GoogleApiClient mGoogleApiClient;
private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
public static final String TAG = MapsActivity.class.getSimpleName();
public static List<MarkerActivity> venues = new ArrayList<MarkerActivity>();
private LocationRequest mLocationRequest;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
setUpMapIfNeeded();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
// Create the LocationRequest object
mLocationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(10 * 1000) // 10 seconds, in milliseconds
.setFastestInterval(1 * 1000); // 1 second, in milliseconds
}
#Override
protected void onResume() {
super.onResume();
setUpMapIfNeeded();
mGoogleApiClient.connect();
}
#Override
protected void onPause() {
super.onPause();
if (mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
mGoogleApiClient.disconnect();
}
}
/**
* Sets up the map if it is possible to do so (i.e., the Google Play services APK is correctly
* installed) and the map has not already been instantiated.. This will ensure that we only ever
* call {#link #setUpMap()} once when {#link #mMap} is not null.
* <p/>
* If it isn't installed {#link SupportMapFragment} (and
* {#link com.google.android.gms.maps.MapView MapView}) will show a prompt for the user to
* install/update the Google Play services APK on their device.
* <p/>
* A user can return to this FragmentActivity after following the prompt and correctly
* installing/updating/enabling the Google Play services. Since the FragmentActivity may not
* have been completely destroyed during this process (it is likely that it would only be
* stopped or paused), {#link #onCreate(Bundle)} may not be called again so we should call this
* method in {#link #onResume()} to guarantee that it will be called.
*/
private void setUpMapIfNeeded() {
// Do a null check to confirm that we have not already instantiated the map.
if (mMap == null) {
// Try to obtain the map from the SupportMapFragment.
mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
.getMap();
// Check if we were successful in obtaining the map.
if (mMap != null) {
try {
setUpMap();
} catch(IOException ioe){
//nothing
}
}
}
}
/**
* This is where we can add markers or lines, add listeners or move the camera. In this case, we
* just add a marker near Africa.
* <p/>
* This should only be called once and when we are sure that {#link #mMap} is not null.
*/
private void setUpMap()throws IOException {
mMap.setMyLocationEnabled(true);
Log.i("MapsActivity","calling get locs");
try {
Log.i("RetrieveFeedTask", "Starting Call");
new RetrieveFeedTask().execute("http://fltapmap.com/get-locs.php");
} catch (Exception alle) {
Log.i("RetrieveFeedTask", "Error" + alle.getMessage());
}
}
#Override
public void onConnected(Bundle bundle) {
Log.i(TAG, "Location services connected.");
Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (location == null) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
else {
handleNewLocation(location);
}
}
private void handleNewLocation(Location location) {
Log.d(TAG, location.toString());
double currentLatitude = location.getLatitude();
double currentLongitude = location.getLongitude();
LatLng latLng = new LatLng(currentLatitude, currentLongitude);
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
CameraUpdate zoom=CameraUpdateFactory.zoomTo(10);
mMap.animateCamera(zoom);
}
#Override
public void onConnectionSuspended(int i) {
Log.i(TAG, "Location services suspended. Please reconnect.");
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
if (connectionResult.hasResolution()) {
try {
// Start an Activity that tries to resolve the error
connectionResult.startResolutionForResult(this, CONNECTION_FAILURE_RESOLUTION_REQUEST);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
} else {
Log.i(TAG, "Location services connection failed with code " + connectionResult.getErrorCode());
}
}
#Override
public void onLocationChanged(Location location) {
handleNewLocation(location);
}
}
BarBrewry is bar barebones right now just for testing
package com.tapmap.app.tapmapapp;
import com.tapmap.app.tapmapapp.util.SystemUiHider;
import android.annotation.TargetApi;
import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
public class BarBrewry extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}
Perhaps you need to implement the public void onCreate(Bundle savedInstanceState) method..
It is because you use a wrong context in that line:
Intent bar = new Intent(MarkerActivity.this, BarBrewry.class);
bar.putExtra("venuename", venuename);
this.startActivity(bar);
this is not a valid context in an inner class there. Try to use:
MarkerActivity.this.startActivity(bar);
Additionally you have to implement onCreate in your MarkerActivity, otherwise there would never exist an instance of this activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
}
I don't exactly know what you want to achieve with MarkerActivity but like Daniel Nugent mentioned in the comments, you should consider merging your MarkerActivity with MapsActivity.

NullPointerException when trying to use text to speech to speak text message out loud

I'm getting an Exception when trying to get text to speech to speak sms text upon arrival and it's giving me a NullPointerException and I can seem to figure out was it's wanting me to do or where exactly the error lies. What could possibly be my problem?
Error Log
java.lang.RuntimeException: Unable to start receiver com.fegeley.handsfreetexting.TTS: java.lang.NullPointerException
at android.app.ActivityThread.handleReceiver(ActivityThread.java:2677)
at android.app.ActivityThread.access$1800(ActivityThread.java:170)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1380)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5635)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1291)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.fegeley.handsfreetexting.TTS.speakText(TTS.java:52)
at com.fegeley.handsfreetexting.TTS.onReceive(TTS.java:74)
at android.app.ActivityThread.handleReceiver(ActivityThread.java:2669)
at android.app.ActivityThread.access$1800(ActivityThread.java:170)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1380)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5635)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1291)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107)
at dalvik.system.NativeStart.main(Native Method)
MainActivity.java
package com.fegeley.handsfreetexting;
import android.media.AudioManager;
import android.speech.tts.TextToSpeech;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.view.View;
import android.widget.Toast;
import java.util.HashMap;
import java.util.Locale;
public class MainActivity extends ActionBarActivity {
TTS tts;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tts = new TTS();
tts.giveContext(this);
}
#Override
public void onPause(){
tts.onPause();
super.onPause();
}
#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);
}
}
TTS.java
package com.fegeley.handsfreetexting;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.telephony.SmsMessage;
import java.util.HashMap;
import java.util.Locale;
/**
* Created by Kayne on 1/14/2015.
*/
public class TTS extends BroadcastReceiver {
private static Context context;
TextToSpeech tts;
public TTS(){
}
public static void giveContext(Context con){
context = con;
}
protected void onCreate(Bundle savedInstanceState){
tts = new TextToSpeech(context,
new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
if(status != TextToSpeech.ERROR){
tts.setLanguage(Locale.US);
}
}
});
}
public void onPause(){
if(tts !=null){
tts.stop();
tts.shutdown();
}
}
public void speakText(String toSpeak){
HashMap<String, String> hash = new HashMap<String,String>();
hash.put(TextToSpeech.Engine.KEY_PARAM_STREAM,
String.valueOf(AudioManager.STREAM_NOTIFICATION));
tts.speak(toSpeak, TextToSpeech.QUEUE_FLUSH, hash);
}
#Override
public void onReceive(Context context, Intent intent) {
//---get the SMS message passed in---
Bundle bundle = intent.getExtras();
SmsMessage[] msgs = null;
String str = "";
//if (bundle != null)
//{
//---retrieve the SMS message received---
Object[] pdus = (Object[]) bundle.get("pdus");
msgs = new SmsMessage[pdus.length];
for (int i=0; i<msgs.length; i++){
msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
str += "SMS from " + msgs[i].getOriginatingAddress();
str += " :";
str += msgs[i].getMessageBody().toString();
str += "\n";
//}
//---display the new SMS message---
speakText(str);
}
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.fegeley.handsfreetexting" >
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme">
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name="com.fegeley.handsfreetexting.TTS">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
</application>
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
</manifest>
Your "tts" object on Line 52 in NULL.
You seems to be initializing it in "onCreate()" of BroadcastReceiver.
protected void onCreate(Bundle savedInstanceState){
tts = new TextToSpeech(context,
new TextToSpeech.OnInitListener()
Note that BroadcastReceiver class do not have any onCreate() Activity-styled call back method.
I guess you assumed that system will invoke onCreate() of BroadcastReceiver class. That is not true for BroadcastReceiver.
You can initialize "tts" object in onReceive() as below:
public void onReceive(Context context1, Intent intent) {
//---get the SMS message passed in---
tts = new TextToSpeech(context,
new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
if(status != TextToSpeech.ERROR){
tts.setLanguage(Locale.US);
}
}
});
Also, change following line in your MainActivity.java
Remove : tts.giveContext(this); Add:TTS.giveContext(getApplicationContext());
This change is to prevent ReceiverCallNotAllowedException
You cannot instantiate a TextToSpeech object in a broadcast receiver. Your code
speakText(str);
at the end of onReceive is called before the Text To Speech call onInit thus you get speak failed not bound to TTS engine.
When an SMS arrives the system instantiate a TTS object as defined in your manifest. It has nothing to do with the tts you instantiates in your MainActivity.
You did not get NPE when your app is opened because the static declaration of context in your TTS class and you instantiate an object in your MainActivity, thus context is not null and therefore the tts object you declare in onCreate or in onReceive as AADTechnical suggested is not null.
When your app is close the tts object declared in MainActivity is destroyed thus the context member in any TTS object initiates without having one calls giveContext woud be null. And giveContext would not be called by the system when it instantiates a TTS object thus context is null and the tts object instantiates in the class is null and you get NPE.
What you need to do is to create a service class where a TTS object is instantiated and start your service in onReceive
public class SMSService extends Service
{
// instantiate a TTS object in this class
}
and
public class TTS extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
// get your SMS message
// and then start the SMSService passing the message in the intent bundle
}
}
I don't know the library but the stack trace tells that the NullPointerException occured in TTS.java on line 52:
str += "SMS from " + msgs[i].getOriginatingAddress();
That means msgs[i] is null although it was assigned one line before that:
msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
Thus createFromPdu returned null.
Since createFromPdu seems to be a framework method it is very likely that pdus[i] which you retrieved from the bundle is null.
Please make sure that you have written "pdus" into the bundle before you read them.
regards,
Max

Categories