This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 8 years ago.
I have been trying to create a basic flashlight app using an image button (beginner). Where i have no syntax errors in the code but do have have some NULL pointer exception in the run time.
Here is my main activity class :-
public class FlashLight extends Activity{
Camera camera = null;
Parameters params = null;
boolean isFlashOn = false;
boolean hasFlash;
ImageButton btnSwitch = (ImageButton) findViewById(R.id.imageButton1);
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
hasFlash = getApplicationContext().getPackageManager()
.hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
if(!hasFlash)
{
AlertDialog alert = new AlertDialog.Builder(FlashLight.this).create();
alert.setTitle("Error");
alert.setMessage("Application Not Supported");
alert.setButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// closing the application
finish();
}
});
return;
}
// get the camera
getCamera();
// displaying button image
toggleButtonImage();
// Switch button click event to toggle flash on/off
btnSwitch.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (isFlashOn) {
// turn off flash
turnOffFlash();
} else {
// turn on flash
turnOnFlash();
}
}
});
}
private void getCamera() {
if(camera == null)
{
try{
camera = Camera.open();
params = camera.getParameters();
}
catch (RuntimeException e) {
Log.e("Camera Error. Failed to Open. Error: ", e.getMessage());
}
}
}
private void toggleButtonImage() {
try{
if(isFlashOn){
btnSwitch.setImageResource(R.drawable.switchon);
}else{
btnSwitch.setImageResource(R.drawable.switchoff);
}
}
catch(RuntimeException e){
Log.e("Could not toggle Button image ", e.getMessage());
}
}
private void turnOnFlash() {
try{
if (!isFlashOn) {
if (camera == null || params == null) {
return;
}
params = camera.getParameters();
params.setFlashMode(Parameters.FLASH_MODE_TORCH);
camera.setParameters(params);
camera.startPreview();
isFlashOn = true;
// changing button/switch image
toggleButtonImage();
}
}
catch(RuntimeException e){
Log.e("Could not turn on Flash ", e.getMessage());
}
}
private void turnOffFlash() {
try{
if (isFlashOn) {
if (camera == null || params == null) {
return;
}
params = camera.getParameters();
params.setFlashMode(Parameters.FLASH_MODE_OFF);
camera.setParameters(params);
camera.stopPreview();
isFlashOn = false;
// changing button/switch image
toggleButtonImage();
}
}
catch(RuntimeException e){
Log.e("Could not turn off flash ", e.getMessage());
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.flash_light, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onDestroy() {
super.onDestroy();
}
#Override
protected void onPause() {
super.onPause();
// on pause turn off the flash
turnOffFlash();
}
#Override
protected void onRestart() {
super.onRestart();
}
#Override
protected void onResume() {
super.onResume();
// on resume turn on the flash
if(hasFlash)
turnOnFlash();
}
#Override
protected void onStart() {
super.onStart();
// on starting the app get the camera params
getCamera();
}
#Override
protected void onStop() {
super.onStop();
// on stop release the camera
if (camera != null) {
camera.release();
camera = null;
}
}
}
while here is my manifest file :-
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.flashlight"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="14" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="FlashLight"
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>
</manifest>
Please, help in the identification of the following error in the logcat menu:-
02-10 23:18:23.409: E/AndroidRuntime(13237): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.flashlight/com.example.flashlight.FlashLight}: java.lang.NullPointerException
ImageButton btnSwitch gives you NULL Pointer, you don't have
setContentView(R.layout.name_of_your_activity);
Change this and it will work:
Camera camera = null;
Camera.Parameters params = null;
boolean isFlashOn = false;
boolean hasFlash;
ImageButton btnSwitch; //add this
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.name_of_your_xml_layout_for_activity);//add this
btnSwitch=(ImageButton)findViewById(R.id.imageButton1);//add this
hasFlash = getApplicationContext().getPackageManager()
.hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);...
Related
I am making my first Android App where I need to take a video of 45 secs to calculate pulse from it.
Recording video is coded the simple way, using startActivityForResult()(something similar to record video using intent). The activity to record video successfully starts but when the record button is pressed recording starts and instantly stops. I have no clue as to why. Logcat displays no error output with respect to the activity. Even, there is no mention of any of my source files in any info or error Logs in Logcat.
Here are my files
MainActivity.java
public class MainActivity extends AppCompatActivity implements SensorEventListener {
private Camera c;
private CameraView cv1;
private FrameLayout view_camera;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (!(getApplicationContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA))) {
this.finish();
System.exit(0);
}
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
VideoCapture video_capture;
Button button_symptoms = (Button)findViewById(R.id.button_symptoms);
Button button_upload_signs = (Button)findViewById(R.id.button_upload_signs);
Button button_measure_heart_rate = (Button)findViewById(R.id.button_measure_heart_rate);
Button button_measure_respiratory_rate = (Button)findViewById(R.id.button_measure_respiratory_rate);
cv1 = new CameraView(getApplicationContext(), this);
view_camera = (FrameLayout)findViewById(R.id.view_camera);
view_camera.addView(cv1);
TextView finger_on_sensor = (TextView)findViewById(R.id.text_finger_on_sensor);
finger_on_sensor.setVisibility(View.INVISIBLE);
finger_on_sensor.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View arg_view, MotionEvent arg_me) {
finger_on_sensor.setVisibility(View.INVISIBLE);
File file_video = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/video_finger.mp4");
final int VIDEO_CAPTURE = 1;
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
Intent intent_record_video = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
intent_record_video.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 45);
Uri fileUri = FileProvider.getUriForFile(MainActivity.this, "com.example.cse535a1.provider", file_video);
List<ResolveInfo> resInfoList = getApplicationContext().getPackageManager().queryIntentActivities(intent_record_video, PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo resolveInfo : resInfoList) {
String packageName = resolveInfo.activityInfo.packageName;
getApplicationContext().grantUriPermission(packageName, fileUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
intent_record_video.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
startActivityForResult(intent_record_video, VIDEO_CAPTURE);
return false;
}
});
button_symptoms.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg_view) {
Intent intent = new Intent(getApplicationContext(), Loggin_symptoms.class);
startActivity(intent);
}
});
button_upload_signs.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg_view) {
}
});
button_measure_heart_rate.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg_view) {
finger_on_sensor.setVisibility(View.VISIBLE);
}
});
button_measure_respiratory_rate.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg_view) {
SensorManager manager_sensor = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
Sensor sensor_accelerometer = manager_sensor.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
manager_sensor.registerListener(MainActivity.this, sensor_accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
}
});
}
public void setCam(Camera arg_camera) {
c = arg_camera;
}
#Override
public void onSensorChanged(SensorEvent arg_event) {
float x = arg_event.values[0];
float y = arg_event.values[1];
float z = arg_event.values[2];
Log.i("ACCELEROMETER", String.valueOf(x) + ' ' + String.valueOf(y) + ' ' + String.valueOf(z));
}
#Override
public void onAccuracyChanged(Sensor arg_sensor, int arg_accuracy) {
}
public Camera getcam() {
Camera c = null;
try { c = Camera.open(0); }
catch (Exception e) {
}
return c;
}
#Override
protected void onPause() {
super.onPause();
c.unlock();
// if (c != null) {
// c.stopPreview();
// c.release();
// c = null;
// }
}
#Override
protected void onResume() {
super.onResume();
// if (c != null) {
// c.stopPreview();
// c.release();
// c = null;
// }
// cv1 = new CameraView(getApplicationContext(), this);
// view_camera.addView(cv1);
}
#Override
protected void onDestroy() {
if (c != null) {
c.stopPreview();
c.release();
c = null;
}
super.onDestroy();
}
}
CameraView.java
public class CameraView extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder holder_surface;
private Camera camera_selected;
MainActivity act1;
public CameraView(Context arg_context, MainActivity arg_activity) {
super(arg_context);
// camera_selected = arg_camera;
act1 = arg_activity;
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
holder_surface = getHolder();
holder_surface.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
holder_surface.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder arg_holder) {
// The Surface has been created, now tell the camera where to draw the preview.
try {
// Log.i("CAMNULL", "CAM IS : " + String.valueOf(camera_selected == null));
Camera c = null;
try {
c = Camera.open(0);
} catch (Exception e) {
Log.e("CAMERA", "Camera not opened");
}
act1.setCam(c);
camera_selected = c;
camera_selected.setPreviewDisplay(arg_holder);
// camera_selected.startPreview();
// Log.i("Cam", "surface creator");
} catch (IOException e) {
// Log.d(TAG, "Error setting camera preview: " + e.getMessage());
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// empty. Take care of releasing the Camera preview in your activity.
// if (camera_selected != null) {
// camera_selected.stopPreview();
// camera_selected.release();
// camera_selected = null;
// }
}
public void surfaceChanged(SurfaceHolder arg_holder, int arg_format, int arg_width, int arg_height) {
// 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 (holder_surface.getSurface() == null){
// preview surface does not exist
return;
}
// stop preview before making changes
try {
camera_selected.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 {
camera_selected.setPreviewDisplay(holder_surface);
camera_selected.startPreview();
} catch (Exception e){
// Log.d(TAG, "Error starting camera preview: " + e.getMessage());
}
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.cse535a1">
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<application
android:requestLegacyExternalStorage="true"
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/Theme.CSE535A1">
<activity android:name=".Loggin_symptoms"></activity>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.example.cse535a1.provider"
android:exported="false"
android:grantUriPermissions="true">
<!-- ressource file to create -->
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths">
</meta-data>
</provider>
</application>
</manifest>
I am attaching images for you convenience.
Activity started and record button is pressed (i want to record a video for 45 secs).
The next instant recording stops
File file_video = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/video_finger.mp4");
final int VIDEO_CAPTURE = 1;
// StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
// StrictMode.setVmPolicy(builder.build());
Intent intent_record_video = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
intent_record_video.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 45);
Uri fileUri = FileProvider.getUriForFile(MainActivity.this, "com.example.cse535a1.provider", file_video);
// List<ResolveInfo> resInfoList = getApplicationContext().getPackageManager().queryIntentActivities(intent_record_video, PackageManager.MATCH_DEFAULT_ONLY);
// for (ResolveInfo resolveInfo : resInfoList) {
// String packageName = resolveInfo.activityInfo.packageName;
// getApplicationContext().grantUriPermission(packageName, fileUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
// }
intent_record_video.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
startActivityForResult(intent_record_video, VIDEO_CAPTURE);
This code(in my MainActivity.java file) is similar to videobasics on Android Developers. With my experience, I will say that it will work for API level 28 and not for API level 30, don't know about API 29.
I recently developed an android app that streams radio online using a URL. It has been working well in other android versions that is 6,7and 8 the ones i tested in emulators.
But last week i published the app to play store, and my reports show that it crashes in android 9 phones. It keeps on throwing java.lang.SecurityException.
I have tried what i could to resolve the error but i have failed.
The users keep reporting multiple app crashes on their phones
This is the stack trace from the play console
java.lang.RuntimeException:
at android.app.ActivityThread.handleServiceArgs (ActivityThread.java:3903)
at android.app.ActivityThread.access$1700 (ActivityThread.java:236)
at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1815)
at android.os.Handler.dispatchMessage (Handler.java:106)
at android.os.Looper.loop (Looper.java:214)
at android.app.ActivityThread.main (ActivityThread.java:7032)
at java.lang.reflect.Method.invoke (Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:494)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:965)
Caused by: java.lang.SecurityException:
at android.os.Parcel.createException (Parcel.java:1966)
at android.os.Parcel.readException (Parcel.java:1934)
at android.os.Parcel.readException (Parcel.java:1884)
at android.app.IActivityManager$Stub$Proxy.setServiceForeground (IActivityManager.java:5043)
at android.app.Service.startForeground (Service.java:695)
at com.premar.radiomunabuddu.RadioMediaPlayerService.play (RadioMediaPlayerService.java:120)
at com.premar.radiomunabuddu.RadioMediaPlayerService.onStartCommand (RadioMediaPlayerService.java:50)
at android.app.ActivityThread.handleServiceArgs (ActivityThread.java:3884)
Caused by: android.os.RemoteException:
at com.android.server.am.ActivityManagerService.enforcePermission (ActivityManagerService.java:12159)
at com.android.server.am.ActiveServices.setServiceForegroundInnerLocked (ActiveServices.java:1289)
at com.android.server.am.ActiveServices.setServiceForegroundLocked (ActiveServices.java:969)
at com.android.server.am.ActivityManagerService.setServiceForeground (ActivityManagerService.java:24839)
at android.app.IActivityManager$Stub.onTransact$setServiceForeground$ (IActivityManager.java:11378)
This is the HomeActivity.java
public class HomeActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
FancyButton listenRadio;
ImageView facebook, twitter, instagram, linkedin;
RadioSettings settings;
Context context;
public static final int REQUEST_CODE =123;
private Button stopButton = null;
private Button playButton = null;
private Button phoneCall;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ButterKnife.bind(this);
settings = new RadioSettings();
//views
phoneCall = (Button)this.findViewById(R.id.phoneBtn);
//Allow hardware audio buttons to control volume
setVolumeControlStream(AudioManager.STREAM_MUSIC);
clickListeners(); //Start click listeners
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
}
private void openFacebookProfile() {
try {
String facebookURL = getFacebookPageUrl();
Intent facebookIntent = new Intent(Intent.ACTION_VIEW);
facebookIntent.setData(Uri.parse(facebookURL));
startActivity(facebookIntent);
} catch (Exception e){
e.printStackTrace();
}
}
private String getFacebookPageUrl() {
final String facebookUrl = settings.getFacebookAddress();
String fbURL = null;
PackageManager packageManager = getPackageManager();
try {
if (packageManager != null){
Intent fbIntent = packageManager.getLaunchIntentForPackage("com.facebook.katana");
if (fbIntent != null){
int versionCode = packageManager.getPackageInfo("com.facebook.katana",0).versionCode;
if (versionCode >= 3002850){
fbURL = "fb://page/1993598950880589";
}
} else {
fbURL = facebookUrl;
}
}
else {
fbURL = facebookUrl;
}
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
fbURL = facebookUrl;
}
return fbURL;
}
private void openTwitterProfile(){
Intent intent = null;
try {
this.getPackageManager().getPackageInfo("com.twitter.android", 0);
intent = new Intent(Intent.ACTION_VIEW, Uri.parse("twitter://user?user_id=USERID"));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
} catch (Exception e){
intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://twitter.com/profilename"));
}
this.startActivity(intent);
}
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.home, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.watch_webcam: {
launchWebcam();
break;
}
case R.id.playstore_share: {
/*
Uri uri = Uri.parse("market://details?id=" + context.getPackageName());
Intent goToMarket = new Intent(Intent.ACTION_VIEW, uri);
// To count with Play market backstack, After pressing back button,
// to taken back to our application, we need to add following flags to intent.
goToMarket.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY |
Intent.FLAG_ACTIVITY_NEW_DOCUMENT |
Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
try {
startActivity(goToMarket);
} catch (ActivityNotFoundException e) {
startActivity(new Intent(Intent.ACTION_VIEW,
Uri.parse("http://play.google.com/store/apps/details?id=" + context.getPackageName())));
}
break;
*/
}
}
return super.onOptionsItemSelected(item);
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_share) {
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
String shareMessage= "\nPlease download our Radiomunnabuddu USA app from the Play Store\n\n";
shareMessage = shareMessage + "https://play.google.com/store/apps/details?id=" + BuildConfig.APPLICATION_ID +"\n\n";
shareIntent.putExtra(Intent.EXTRA_TEXT , shareMessage);
shareIntent.putExtra(Intent.EXTRA_SUBJECT, "Radio Munnabuddu USA");
startActivity(Intent.createChooser(shareIntent, "Share via..."));
}
else if (id == R.id.nav_email){
Intent emailIntent = new Intent(Intent.ACTION_SENDTO);
emailIntent.setData(Uri.parse("mailto: "+settings.getEmailAddress()));
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Radio Munnabuddu USA");
if (emailIntent.resolveActivity(getPackageManager()) != null){
startActivity(Intent.createChooser(emailIntent, "Send email via"));
}
}
else if(id == R.id.nav_report){
Intent emailIntent = new Intent(Intent.ACTION_SENDTO);
emailIntent.setData(Uri.parse("mailto: denis#premar.tech"));
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Crash or Bug report");
if (emailIntent.resolveActivity(getPackageManager()) != null){
startActivity(Intent.createChooser(emailIntent, "Send email via."));
}
}
else if(id == R.id.nav_about){
Intent aboutIntent = new Intent(HomeActivity.this, AboutActivity.class);
startActivity(aboutIntent);
}
else if(id == R.id.nav_fb){
openFacebookProfile();
}
else if(id == R.id.nav_twitter){
openTwitterProfile();
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
/**
* Listens for contact button clicks
*/
private void clickListeners(){
//Play button
playButton = (Button)findViewById(R.id.PlayButton);
playButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(getApplicationContext(),
RadioMediaPlayerService.class);
intent.putExtra(RadioMediaPlayerService.START_PLAY, true);
startService(intent);
}
});
//Stop button
stopButton = (Button)findViewById(R.id.StopButton);
stopButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//Get new MediaPlayerService activity
Intent intent = new Intent(getApplicationContext(),
RadioMediaPlayerService.class);
stopService(intent);
}
});
//Email Button click list
final View EmailPress = (Button)this.findViewById(R.id.emailBtn);
EmailPress.setOnClickListener(new View.OnClickListener() {
public void onClick(View view){
Intent emailIntent = new Intent(Intent.ACTION_SENDTO);
emailIntent.setData(Uri.parse("mailto: "+settings.getEmailAddress()));
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Radio Munnabuddu");
if (emailIntent.resolveActivity(getPackageManager()) != null){
try {
startActivity(Intent.createChooser(emailIntent, "Send email..."));
} catch (android.content.ActivityNotFoundException ex) {
Toast.makeText(HomeActivity.this, "There are no email clients installed.", Toast.LENGTH_SHORT).show();
}
}
}
});
//Website Button
final View WWWPress = (Button)this.findViewById(R.id.websiteBtn);
WWWPress.setOnClickListener(new View.OnClickListener() {
public void onClick(View view){
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(settings.getWebsiteURL())); //URL
startActivity (browserIntent);
}
});
//SMS Button
final View TxtPress = (Button)this.findViewById(R.id.txtBtn);
TxtPress.setOnClickListener(new View.OnClickListener() {
public void onClick(View view){
Uri uri = Uri.parse(settings.getSmsNumber());
Intent intent = new Intent(Intent.ACTION_SENDTO, uri);
intent.putExtra("sms_body", "Hello Presenter,");
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}
/*
if (ActivityCompat.checkSelfPermission(HomeActivity.this, Manifest.permission.SEND_SMS) != PackageManager.PERMISSION_GRANTED){
Toast.makeText(HomeActivity.this, "Please grant the permission to call", Toast.LENGTH_SHORT).show();
requestSMSPermission();
}
else {
startActivity (smsIntent);
}*/
}
});
}
/**
* Launches webcam from external URL
*/
public void launchWebcam(){
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(settings.getRadioWebcamURL()));
startActivity (browserIntent);
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE:
if ((grantResults.length > 0) && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
onCall();
} else {
Log.d("TAG", "Call Permission Not Granted");
//Toast.makeText(this, "Call Permission Not Granted", Toast.LENGTH_SHORT).show();
}
return;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
public void onCall() {
int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE);
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
this,
new String[]{Manifest.permission.CALL_PHONE},
REQUEST_CODE);
} else {
phoneCall.setOnClickListener(new View.OnClickListener() {
public void onClick(View view){
/*
String phoneNum = settings.getPhoneNumber();
Intent phoneIntent = new Intent(Intent.ACTION_CALL);
phoneIntent.setData(Uri.parse("tel:"+ phoneNum));
if (phoneIntent.resolveActivity(getPackageManager()) != null) {
startActivity(phoneIntent);
}
*/
startActivity(new Intent(Intent.ACTION_CALL).setData(Uri.parse("tel:" + settings.getPhoneNumber())));
}
});
}
}
This is the RadioMediaPlayerService.java
public class RadioMediaPlayerService extends Service implements
AudioManager.OnAudioFocusChangeListener {
//Variables
private boolean isPlaying = false;
private MediaPlayer radioPlayer; //The media player instance
private static int classID = 579; // just a number
public static String START_PLAY = "START_PLAY";
AudioManager audioManager;
//Media session
MediaSession mSession;
//Settings
RadioSettings settings = new RadioSettings();
#Override
public IBinder onBind(Intent intent) {
return null;
}
/**
* Starts the streaming service
*/
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent.getBooleanExtra(START_PLAY, false)) {
play();
}
//Request audio focus
if (!requestAudioFocus()) {
//Could not gain focus
stopSelf();
}
return Service.START_STICKY;
}
#Override
public void onCreate() {
super.onCreate();
}
/**
* Starts radio URL stream
*/
private void play() {
//Check connectivity status
if (isOnline()) {
//Check if player already streaming
if (!isPlaying) {
isPlaying = true;
//Return to the current activity
Intent intent = new Intent(this, HomeActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|
Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pi = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
// mSession.setSessionActivity(pi);
//Build and show notification for radio playing
Bitmap largeIcon = BitmapFactory.decodeResource(getResources(),
R.drawable.buddu3);
Notification notification = new NotificationCompat.Builder(this, "ID")
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setTicker("Radio Munnabuddu USA")
.setContentTitle(settings.getRadioName())
.setContentText(settings.getMainNotificationMessage())
.setSmallIcon(R.drawable.ic_radio_black_24dp)
//.addAction(R.drawable.ic_play_arrow_white_64dp, "Play", pi)
// .addAction(R.drawable.ic_pause_black_24dp, "Pause", pi)
.setLargeIcon(largeIcon)
.setContentIntent(pi)
.build();
//Get stream URL
radioPlayer = new MediaPlayer();
try {
radioPlayer.setDataSource(settings.getRadioStreamURL()); //Place URL here
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
radioPlayer.prepareAsync();
radioPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
radioPlayer.start(); //Start radio stream
}
});
startForeground(classID, notification);
//Display toast notification
Toast.makeText(getApplicationContext(), settings.getPlayNotificationMessage(),
Toast.LENGTH_LONG).show();
}
}
else {
//Display no connectivity warning
Toast.makeText(getApplicationContext(), "No internet connection",
Toast.LENGTH_LONG).show();
}
}
/**
* Stops the stream if activity destroyed
*/
#Override
public void onDestroy() {
stop();
removeAudioFocus();
}
/**
* Stops audio from the active service
*/
private void stop() {
if (isPlaying) {
isPlaying = false;
if (radioPlayer != null) {
radioPlayer.release();
radioPlayer = null;
}
stopForeground(true);
}
Toast.makeText(getApplicationContext(), "Radio stopped",
Toast.LENGTH_LONG).show();
}
/**
* Checks if there is a data or internet connection before starting the stream.
* Displays Toast warning if there is no connection
* #return online status boolean
*/
public boolean isOnline() {
ConnectivityManager cm =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnectedOrConnecting()) {
return true;
}
return false;
}
#Override
public void onAudioFocusChange(int focusChange) {
//Invoked when the audio focus of the system is updated.
switch (focusChange) {
/*
case AudioManager.AUDIOFOCUS_GAIN:
// resume playback
// if (radioPlayer == null) initMediaPlayer();
if (radioPlayer.isPlaying()){
radioPlayer.release();
stopForeground(true);
}
radioPlayer.setVolume(1.0f, 1.0f);
break;*/
case AudioManager.AUDIOFOCUS_LOSS:
// Lost focus for an unbounded amount of time: stop playback and release media player
if (radioPlayer.isPlaying()) radioPlayer.stop();
radioPlayer.release();
//radioPlayer = null;
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
// Lost focus for a short time, but we have to stop
// playback. We don't release the media player because playback
// is likely to resume
if (radioPlayer.isPlaying()) radioPlayer.pause();
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
// Lost focus for a short time, but it's ok to keep playing
// at an attenuated level
if (radioPlayer.isPlaying()) radioPlayer.setVolume(0.1f, 0.1f);
break;
}
}
/**
* AudioFocus
*/
private boolean requestAudioFocus() {
audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
int result = audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
//Focus gained
return true;
}
//Could not gain focus
return false;
}
private boolean removeAudioFocus() {
return AudioManager.AUDIOFOCUS_REQUEST_GRANTED ==
audioManager.abandonAudioFocus(this);
}
}
This is the Manifest.xml
<!--uses-permission android:name="android.permission.SEND_SMS" /-->
<uses-permission android:name="android.permission.INTERNET" />
<!--uses-permission android:name="android.permission.CALL_PHONE" /-->
<!--tools:node="remove"-->
<uses-feature
android:name="android.hardware.telephony"
android:required="false" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<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:ignore="GoogleAppIndexingWarning">
<service
android:name="com.premar.radiomunabuddu.RadioMediaPlayerService"
android:enabled="true" >
</service>
<receiver android:name="com.premar.radiomunabuddu.IntentReceiver">
<intent-filter>
<action android:name="android.media.AUDIO_BECOMING_NOISY" />
</intent-filter>
</receiver>
<activity
android:name="com.premar.radiomunabuddu.HomeActivity"
android:label="#string/app_name"
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="com.premar.radiomunabuddu.AboutActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.premar.radiomunabuddu.HomeActivity" />
</activity>
</application>
Android 9 introduced a new FOREGROUND_SERVICE permission. From the docs:
Note: Apps that target Android 9 (API level 28) or higher and use foreground services must request the FOREGROUND_SERVICE permission. This is a normal permission, so the system automatically grants it to the requesting app.
If an app that targets API level 28 or higher attempts to create a foreground service without requesting FOREGROUND_SERVICE, the system throws a SecurityException.
Just add that permission to your manifest and you should be good to go.
The setServiceForegroundInnerLocked method will check based on the targetSdkVersion level。lack FOREGROUND_SERVICE permission
code:
if (r.appInfo.targetSdkVersion >= Build.VERSION_CODES.P) {
mAm.enforcePermission(
android.Manifest.permission.FOREGROUND_SERVICE,
r.app.pid, r.appInfo.uid, "startForeground");
}
In my app there is a media player which is playing streamed url.
The player starts in oncreate method when the connection to internet is available.I have a broadcast receiver which checks the connection to the internet and notify the user. I am facing a problem here that when my app shifts from Wifi to cellular network, media player should take a little pause and starts again because the network is available again. But i'am unable to find the logic that how can i achieve this?
Here is my sample code,Kindly solve the issue?
Any help will be grateful.
Manifest:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<receiver android:name=".receivers.NetworkChangeReciever">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
Main Activity:
private BroadcastReceiver mNetworkReceiver;
static TextView tv_check_connection;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_check_connection=(TextView) findViewById(R.id.tv_check_connection);
mNetworkReceiver = new NetworkChangeReciever();
registerNetworkBroadcastForNougat();
// checkNetworkStatus();
mSelectedTrackTitle = (TextView) findViewById(R.id.selected_track_title);
nowplaying = (TextView) findViewById(R.id.nowplaying);
mPlayerControl = (ImageView) findViewById(R.id.player_control);
mPlayerControl.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
togglePlayPause();
}
});
mSelectedTrackTitle.setText("FM World Pakistan");
nowplaying.setText("Now Playing");
mPlayerControl.setImageResource(R.drawable.ic_pause_circle_filled);
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
mMediaPlayer.setDataSource(url);
mMediaPlayer.prepare();
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mMediaPlayer.start();
}
});
} catch (IOException e) {
e.printStackTrace();
nowplaying.setText("Offline");
Toast.makeText(MainActivity.this, "Radio Offline", Toast.LENGTH_LONG).show();
mPlayerControl.setImageResource(R.drawable.ic_play_circle_filled);
}
public static void dialog(boolean value){
if(value){
tv_check_connection.setText("We are back !!!");
tv_check_connection.setBackgroundResource(R.color.neton);
tv_check_connection.setTextColor(Color.WHITE);
Handler handler = new Handler();
Runnable delayrunnable = new Runnable() {
#Override
public void run() {
tv_check_connection.setVisibility(View.GONE);
}
};
handler.postDelayed(delayrunnable, 3000);
}else {
tv_check_connection.setVisibility(View.VISIBLE);
tv_check_connection.setText("Could not connect to Internet.");
tv_check_connection.setBackgroundResource(R.color.colorAccent);
tv_check_connection.setTextColor(Color.WHITE);
nowplaying.setText("Buffering...");
mPlayerControl.setImageResource(R.drawable.ic_play_circle_filled);
}
}
private void registerNetworkBroadcastForNougat() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
registerReceiver(mNetworkReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
registerReceiver(mNetworkReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}
}
protected void unregisterNetworkChanges() {
try {
unregisterReceiver(mNetworkReceiver);
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
}
private void togglePlayPause() {
if (mMediaPlayer.isPlaying()) {
mMediaPlayer.pause();
nowplaying.setText("Offline");
mPlayerControl.setImageResource(R.drawable.ic_play_circle_filled);
} else {
mMediaPlayer.start();
nowplaying.setText("Now Playing");
mPlayerControl.setImageResource(R.drawable.ic_pause_circle_filled);
}
}
#Override
protected void onDestroy() {
super.onDestroy();
unregisterNetworkChanges();
if (mMediaPlayer != null) {
if (mMediaPlayer.isPlaying()) {
mMediaPlayer.stop();
}
mMediaPlayer.release();
mMediaPlayer = null;
}
}
Receiver Class:
public class NetworkChangeReciever extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
try
{
if (isOnline(context)) {
dialog(true);
Log.e("Hi", "Online Connect Intenet ");
} else {
dialog(false);
Log.e("Sorry","Conectivity Failure !!! ");
}
} catch (NullPointerException e) {
e.printStackTrace();
}
}
private boolean isOnline(Context context) {
try {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
//should check null because in airplane mode it will be null
return (netInfo != null && netInfo.isConnected());
} catch (NullPointerException e) {
e.printStackTrace();
return false;
}
}
I found a solution as, if media player is declared as static; we can reinitialize it in dialog()
public static void dialog(boolean value){
if(value){
tv_check_connection.setText("We are back !!!");
tv_check_connection.setBackgroundResource(R.color.neton);
tv_check_connection.setTextColor(Color.WHITE);
//recreate media player
Handler handler = new Handler();
Runnable delayrunnable = new Runnable() {
#Override
public void run() {
tv_check_connection.setVisibility(View.GONE);
}
};
handler.postDelayed(delayrunnable, 3000);
}else {
tv_check_connection.setVisibility(View.VISIBLE);
tv_check_connection.setText("Could not connect to Internet.");
tv_check_connection.setBackgroundResource(R.color.colorAccent);
tv_check_connection.setTextColor(Color.WHITE);
nowplaying.setText("Buffering...");
mPlayerControl.setImageResource(R.drawable.ic_play_circle_filled);
//pause media player
}
}
I make an app to read barcode numbers and I used a surface view with a camera source in it. The app send the value to another activity which is shown as a dialog.
I make other activity as dialog but the problem the surface view is stopped. I tried many solutions until this works which is to put these lines in onCreate method .
setTheme(android.R.style.Theme_DeviceDefault_Dialog);
requestWindowFeature(Window.FEATURE_NO_TITLE);
with adding these two lines in onCreate method the surface view didn't stop and it works but the problem is the dialog shown in black screen also the parent when the dialog is shown it turns all to black. how to fix this problem.
I also modified manifest to process that and I add the following
<activity android:name=".InfoActivity"
android:excludeFromRecents="true"
android:label="#string/app_name"
android:launchMode="singleInstance"
android:theme="#style/Theme.AppCompat.Light.Dialog">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
these the whole code of the class
public class MainActivity extends AppCompatActivity {
SurfaceView surfaceView;
BarcodeDetector barcodeDetector;
CameraSource cameraSource;
TextView txtShow, itemName, itemPrice, itemQuantity;
TextView txtNameDialog, txtPriceDialog, txtQuantityDialog;
final int RequestCameraPermissionId = 1001;
String code;
RequestQueue requestQueue;
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode) {
case RequestCameraPermissionId: {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
return;
}
try {
cameraSource.start(surfaceView.getHolder());
} catch (IOException e) {
e.printStackTrace();
}
}
}
break;
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
surfaceView = (SurfaceView) findViewById(R.id.cameraPreview);
txtShow = (TextView) findViewById(R.id.txtShow);
itemName = (TextView) findViewById(R.id.itemName);
itemPrice = (TextView) findViewById(R.id.itemPrice);
itemQuantity = (TextView) findViewById(R.id.itemQuantity);
startBarcode();
}
public void startBarcode() {
barcodeDetector = new BarcodeDetector.Builder(this)
.setBarcodeFormats(Barcode.ALL_FORMATS)
.build();
cameraSource = new CameraSource.Builder(this, barcodeDetector)
.setRequestedPreviewSize(800, 600)
.setAutoFocusEnabled(true)
.build();
//Events
surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceCreated(SurfaceHolder holder) {
if (ActivityCompat.checkSelfPermission(getApplicationContext(), android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
//Make Request Runtime Permission
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.CAMERA}, RequestCameraPermissionId);
return;
}
try {
cameraSource.start(surfaceView.getHolder());
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
//Make Request Runtime Permission
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.CAMERA}, RequestCameraPermissionId);
return;
}
try {
cameraSource.start();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
cameraSource.stop();
}
});
barcodeDetector.setProcessor(new Detector.Processor<Barcode>() {
#Override
public void release() {
}
#Override
public void receiveDetections(Detector.Detections<Barcode> detections) {
final SparseArray<Barcode> qrCodes = detections.getDetectedItems();
if (qrCodes.size() != 0) {
txtShow.post(new Runnable() {
#Override
public void run() {
//stop camera
cameraSource.stop();
//create vibrate
Vibrator vibrator = (Vibrator) getApplicationContext().getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(500);
//set result for Text View
txtShow.setText(qrCodes.valueAt(0).displayValue);
final String code = txtShow.getText().toString();
// surfaceView.setTop(200);
final MediaPlayer mp = MediaPlayer.create(MainActivity.this, R.raw.barcode);
mp.start();
Button getInfo = (Button) findViewById(R.id.getInfo);
Intent intent = new Intent(MainActivity.this,InfoActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
I am following the patterns that are used in the Compass example in a new project and have most of the logic working. However, when I tap while my live card is displayed I hear the 'click' noise but my menu activity doesn't display. I think that I am missing a piece of the puzzle, but I have not been able to figure out what as of yet.
When I tap, besides the click, I also see this in logcat:
01-08 10:02:26.796: I/ActivityManager(196): START {flg=0x10008000 cmp=com.example.speeddisplay/.SpeedDisplayMenuActivity} from pid -1
So it looks like it should be starting my activity, but it doesn't show up. Here are some pieces of relevant code...although I am not sure where the issue is.
Service portion in AndroidManifest.xml:
<service
android:name="com.example.speeddisplay.service.SpeedService"
android:enabled="true"
android:icon="#drawable/ic_drive_50"
android:label="#string/app_name" >
<intent-filter>
<action android:name="com.google.android.glass.action.VOICE_TRIGGER" />
</intent-filter>
<meta-data
android:name="com.google.android.glass.VoiceTrigger"
android:resource="#xml/voiceinput_speeddisplay" />
</service>
onStartCommand method in SpeedService.java:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (Constants.DEBUG) {
Log.d(TAG, "onStartCommand");
}
if (liveCard == null) {
liveCard = timelineManager.createLiveCard(LIVE_CARD_ID);
speedRenderer = new SpeedRenderer(this, speedManager);
liveCard.setDirectRenderingEnabled(true);
liveCard.getSurfaceHolder().addCallback(speedRenderer);
// Display the options menu when the live card is tapped.
Intent menuIntent = new Intent(this, SpeedDisplayMenuActivity.class);
menuIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
liveCard.setAction(PendingIntent.getActivity(this, 0, menuIntent, 0));
liveCard.publish(PublishMode.REVEAL);
if(Constants.DEBUG){
Log.d(TAG, "liveCard published");
}
}
return START_STICKY;
}
Here is my SpeedDisplayMenuActivity.java. None of these methods are getting called.
public class SpeedDisplayMenuActivity extends Activity {
private SpeedService.SpeedBinder speedService;
private boolean mResumed;
private ServiceConnection mConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
if (Constants.DEBUG) {
Log.e("Service Stuff", "Service connected.");
}
if (service instanceof SpeedService.SpeedBinder) {
speedService = (SpeedService.SpeedBinder) service;
openOptionsMenu();
}
if (Constants.DEBUG) {
Log.e("Service Stuff", "service was an instance of " + service.getClass().getName());
}
}
#Override
public void onServiceDisconnected(ComponentName name) {
// Do nothing.
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
if(Constants.DEBUG){
Log.e("Menu", "Created.");
}
super.onCreate(savedInstanceState);
bindService(new Intent(this, SpeedService.class), mConnection, 0);
}
#Override
protected void onResume() {
if(Constants.DEBUG){
Log.e("Menu", "Resumed.");
}
super.onResume();
mResumed = true;
openOptionsMenu();
}
#Override
protected void onPause() {
if(Constants.DEBUG){
Log.e("Menu", "Paused.");
}
super.onPause();
mResumed = false;
}
#Override
public void openOptionsMenu() {
if (Constants.DEBUG) {
Log.e("Options Menu", "Open");
}
if (mResumed && speedService != null) {
if (Constants.DEBUG) {
Log.e("Options Menu", "Open with correct params");
}
super.openOptionsMenu();
} else {
if (Constants.DEBUG) {
Log.e("Options Menu", "Open with INCORRECT params");
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
if (Constants.DEBUG) {
Log.e("Options Menu", "Created");
}
getMenuInflater().inflate(R.menu.speed, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (Constants.DEBUG) {
Log.e("Options Menu", "Item Selected");
}
switch (item.getItemId()) {
// case R.id.read_aloud:
// mCompassService.readHeadingAloud();
// return true;
case R.id.stop:
if (Constants.DEBUG) {
Log.e("Options Menu", "Stop");
}
stopService(new Intent(this, SpeedService.class));
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public void onOptionsMenuClosed(Menu menu) {
if (Constants.DEBUG) {
Log.e("Options Menu", "Closed");
}
super.onOptionsMenuClosed(menu);
unbindService(mConnection);
// We must call finish() from this method to ensure that the activity
// ends either when an
// item is selected from the menu or when the menu is dismissed by
// swiping down.
finish();
}
Does anybody see what I am missing?
That is right, declaring the SpeedDisplayMenuActivity is the problem in this case.
I have seen cases where many other types of exceptions / crash that normally happens in Android environment is gracefully handled in Glass.
That is definitely good for the user experience, but makes little tough on development. Hopefully some kind of settings come in future to enable exceptions as well in future!