I have 2 tabs each containing videoView. But when I switch to the second tab the video plays the audio is working, but the video doesn't plays and the view is only black. This works fine in Android 2.1 + , but it does't in 1.6 Here is my code:
TabActivity:
package com.example.tab;
import android.app.TabActivity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TabHost;
public class main extends TabActivity {
/** Called when the activity is first created. */
private TabHost tabHost;
public void onCreate( Bundle savedInstanceState){
super.onCreate(savedInstanceState);
tabHost = getTabHost();
Intent intent1 = new Intent(this, Video1.class);
Intent intent2 = new Intent(this, Video2.class);
tabHost.addTab(tabHost.newTabSpec("Tab1")
.setIndicator("Video1")
.setContent(intent1.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)));
tabHost.addTab(tabHost.newTabSpec("Tab2")
.setIndicator("Video2")
.setContent(intent2.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)));
}
}
Video1 activity:
/**
*
*/
package com.example.tab;
import android.app.Activity;
import android.content.Intent;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SurfaceHolder;
import android.view.View;
import android.widget.MediaController;
import android.widget.VideoView;
/**
* #author lyubomir.todorov
*
*/
public class Video1 extends Activity implements SurfaceHolder.Callback {
private String path = "http://xxx.xxx";
private VideoView mVideoView;
private SurfaceHolder holder;
private static final int INSERT_ID = Menu.FIRST;
private static final String TAG = "Tab";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.videoview1);
mVideoView = (VideoView) findViewById(R.id.surface_view1);
// holder = mVideoView.getHolder();
// holder.addCallback(this);
// holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(0, INSERT_ID, 0, "FullScreen");
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
Log.d(TAG, "Player re-started after device configuration change");
return true;
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
PlayVideo();
Log.d(TAG, "onResume Video1");
}
protected void onPause() {
super.onDestroy();
Log.d(TAG, "onPause Video1");
if (mVideoView != null) {
mVideoView.stopPlayback();
mVideoView.setVisibility(View.GONE);
mVideoView=null;
Log.d(TAG, "onPause1 Video1");
}
}
public void surfaceDestroyed(SurfaceHolder surfaceholder) {
holder.isCreating();
Log.d(TAG, "video1 surfaceDestroyed called");
}
public void surfaceCreated(SurfaceHolder holder) {
Log.d(TAG, "Current 1 surfaceCreated called");
Log.d(TAG, Boolean.valueOf(holder.isCreating()).toString());
// playVideo(extras.getInt(MEDIA));
}
public void PlayVideo() {
mVideoView.setVideoPath(path);
mVideoView.start();
mVideoView.setMediaController(new MediaController(this));
mVideoView.setVisibility(View.VISIBLE);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
Log.d(TAG, Boolean.valueOf(holder.isCreating()).toString());
// TODO Auto-generated method stub
Log.d(TAG, "Current video surfaceChanged called");
}
}
videoview1.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<VideoView android:id="#+id/surface_view1"
android:layout_width="320dip" android:layout_height="240dip"
/>
</LinearLayout>
Video2 activity:
/**
*
*/
package com.example.tab;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.View;
import android.widget.MediaController;
import android.widget.VideoView;
/**
* #author lyubomir.todorov
*
*/
public class Video2 extends Activity implements SurfaceHolder.Callback {
private String path = "http://xxx.xxx";
private VideoView mVideoView;
private SurfaceHolder holder;
private static final String TAG = "Tab";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.videoview2);
mVideoView = (VideoView) findViewById(R.id.surface_view2);
// holder= mVideoView.getHolder();
// holder.addCallback(this);
// holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
PlayVideo();
Log.d(TAG, "onResume Video1");
}
protected void onPause() {
super.onPause();
Log.d(TAG, "onPause Video2");
if (mVideoView!=null){
mVideoView.stopPlayback();
mVideoView.setVisibility(View.GONE);
Log.d(TAG, "onPause1 Video2");
}
}
public void surfaceDestroyed(SurfaceHolder surfaceholder) {
holder.isCreating();
Log.d(TAG, "video1 surfaceDestroyed called");
}
public void surfaceCreated(SurfaceHolder holder) {
Log.d(TAG, "Current 1 surfaceCreated called");
Log.d(TAG, Boolean.valueOf(holder.isCreating()).toString());
}
public void PlayVideo() {
mVideoView.setVisibility(View.VISIBLE);
mVideoView.bringToFront();
mVideoView.setVideoPath(path);
mVideoView.start();
mVideoView.setMediaController(new MediaController(this));
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
Log.d(TAG, Boolean.valueOf(holder.isCreating()).toString());
// TODO Auto-generated method stub
Log.d(TAG, "Current video surfaceChanged called");
}
}
videoview2.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<VideoView android:id="#+id/surface_view2"
android:layout_width="320dip" android:layout_height="240dip"
/>
</LinearLayout>
Related
I have a problem when using MediaPlayer to play video from url.
The follow of program : create an activity to play video -> press Home button -> back to app.
The requirement is video play from start, when press Home button video continuos play(only audio), and when back to app, video must play continuous(combine movie and audio).
The first, I created a MediaPlayer variable to play video. When Home button is pressed, MediaPlayer play continuous. But when back to app, video cannot displayed(black screen). So, I created other MediaPlayer variable to solved this issue. But when I using seekTo() function to seek second MediaPlayer to position of first MediaPlayer, this function is working incorrect.
import java.io.IOException;
import com.example.videotest.R;
import android.app.Activity;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnBufferingUpdateListener;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.media.MediaPlayer.OnSeekCompleteListener;
import android.media.MediaPlayer.OnVideoSizeChangedListener;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.Window;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.Toast;
public class PlayVideoActivity extends Activity implements OnClickListener,SurfaceHolder.Callback, FGMediaController.MediaPlayerControl {
SurfaceView videoSurface,videoSurfaceFullscreen,videoSurfaceSmallsceen;
MediaPlayer player, backupPlayer;
FGMediaController controller;
LinearLayout llControllerBar;
public boolean isFullscreen = false;
int videoDuration;
int videoCurrent;
SurfaceHolder viewHolder = null;
boolean isPaused = false;
String videoUrl = "http://cdn-smatopi.tv-bank.com/movie/867/867-32/867-32-2015042306-D3/hls/hls3/867-32-2015042306-D3-HLS3.m3u8";
Button btnSeek, btnRelease;
int currentPos = 30000;
boolean videoPrepared = false;
boolean backupPrepared = false;
boolean mVideoSizeIsSet = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.playvideo);
btnSeek = (Button) findViewById(R.id.btnSeek);
btnRelease = (Button) findViewById(R.id.btnRelease);
videoSurface = (SurfaceView)findViewById(getResources().getIdentifier("vvVideo", "id", getPackageName()));
SurfaceHolder videoHolder = videoSurface.getHolder();
videoHolder.addCallback(this);
player = new MediaPlayer();
backupPlayer = new MediaPlayer();
controller = new FGMediaController(this);
try {
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
player.setDataSource(this, Uri.parse(videoUrl));
player.prepareAsync();
//backupPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
//backupPlayer.setDataSource(this, Uri.parse(videoUrl));
//backupPlayer.prepareAsync();
} catch (Exception e) {
e.printStackTrace();
}
btnSeek.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Log.e("Huhu",currentPos + "");
backupPlayer.seekTo(currentPos);
}
});
btnRelease.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
backupPlayer.stop();
backupPlayer.release();
}
});
player.setOnBufferingUpdateListener(new OnBufferingUpdateListener() {
public void onBufferingUpdate(MediaPlayer mp, int percent) {
}
});
player.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
controller.setMediaPlayer(PlayVideoActivity.this);
controller.setAnchorView((FrameLayout) findViewById(PlayVideoActivity.this.getResources().getIdentifier("videoSurfaceContainer", "id", PlayVideoActivity.this.getPackageName())));
player.start();
}
});
}
#Override
public void onDestroy(){
//backupPlayer.release();
player.release();
super.onDestroy();
}
#Override
public void onResume(){
Log.e("Surface Created","OnResume");
super.onResume();
}
// Implement SurfaceHolder.Callback
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
Log.e("Surface Created","Surface Created! " + holder);
if(viewHolder != null){
viewHolder = holder;
backupPlayer = new MediaPlayer();
try {
backupPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
backupPlayer.setDataSource(this, Uri.parse(videoUrl));
backupPlayer.prepareAsync();
backupPlayer.setDisplay(holder);
backupPlayer.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
backupPrepared = true;
backupPlayer.start();
}
});
backupPlayer.setOnVideoSizeChangedListener(new OnVideoSizeChangedListener() {
#Override
public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
// TODO Auto-generated method stub
if (width == 0 || height == 0){
Toast.makeText(getApplicationContext(),"Width = 0 Height = 0"+ mp.getDuration(), Toast.LENGTH_LONG).show();
}else{
if(backupPrepared){
backupPrepared = false;
currentPos = player.getCurrentPosition();
player.reset();
Toast.makeText(getApplicationContext(),"Seek To "+ backupPlayer.getCurrentPosition() + " | " + backupPlayer.isPlaying() + "|" + currentPos, Toast.LENGTH_LONG).show();
Log.e("Huhu","Seek To "+ backupPlayer.getCurrentPosition() + " | " + backupPlayer.isPlaying() + "|" + currentPos);
backupPlayer.seekTo(currentPos); // If you set currentPos = 20000ms or 30000ms backupPlayer can to seek, but if you set currentPos = 10000ms backupPlayer cannot seek !
}
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}else{
player.setDisplay(holder);
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
Log.e("Surface Created","surfaceDestroyed! " + player.getCurrentPosition());
viewHolder = holder;
}
// End MediaPlayer.OnPreparedListener
// Implement VideoMediaController.MediaPlayerControl
#Override
public boolean canPause() {
return true;
}
#Override
public boolean canSeekBackward() {
return true;
}
#Override
public boolean canSeekForward() {
return true;
}
#Override
public int getBufferPercentage() {
return 0;
}
#Override
public int getCurrentPosition() {
//Log.printLog(Log.ERROR, "CURRENT :"+player.getCurrentPosition());
int current = 0;
try{
current = player.getCurrentPosition();
}catch(Exception e){
e.printStackTrace();
}
return current;
}
#Override
public int getDuration() {
int duration = 0;
try{
duration = player.getDuration();
}catch(Exception e){
e.printStackTrace();
}
return duration;
}
#Override
public boolean isPlaying() {
boolean isPlaying = false;
try{
isPlaying = player.isPlaying();
}catch(Exception e){
e.printStackTrace();
}
return isPlaying;
}
#Override
public void pause() {
player.pause();
}
#Override
public void seekTo(int i) {
player.seekTo(i);
}
#Override
public void start() {
player.start();
}
#Override
public boolean isFullScreen() {
return isFullscreen;
}
#Override
public void toggleFullScreen() {
// TODO Auto-generated method stub
}
#Override
public void doBackPressed() {
// TODO Auto-generated method stub
}
#Override
public void onClick(View v) {
}
}
I am making simple app to display video and plaing audio playback if activity is in background.
My app works fine if i just turn screen off/on.
It crashes when I resume my app after brawsing another application.
Log cat show no error.
import android.app.Activity;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import com.squareup.otto.Subscribe;
public class MainActivity
extends Activity
implements android.view.SurfaceHolder.Callback {
private SurfaceView surfaceViewFrame;
private SurfaceHolder holder;
private Bundle extras;
private static final String TAG = "log_tag";
private boolean b = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
surfaceViewFrame = (SurfaceView) findViewById(R.id.surfaceView);
surfaceViewFrame.setClickable(false);
holder = surfaceViewFrame.getHolder();
holder.addCallback(this);
}
#Subscribe
public void attachPlayer(MediaPlayer player) {
player.setDisplay(holder);
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
public void surfaceCreated(SurfaceHolder holder) {
startService(new Intent(this, MediaPlayerService.class));
}
public void surfaceDestroyed(SurfaceHolder holder) {
}
#Override
protected void onStart() {
super.onStart();
BusProvider.getInstance().register(this);
}
#Override
protected void onStop() {
super.onStop();
BusProvider.getInstance().unregister(this);
}
Service
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.IBinder;
import android.util.Log;
import java.io.IOException;
public class MediaPlayerService
extends Service
implements MediaPlayer.OnPreparedListener,
MediaPlayer.OnCompletionListener,
MediaPlayer.OnSeekCompleteListener {
private static final String TAG = "MediaService";
private static final String ACTION_PLAY = "com.example.action.PLAY";
private MediaPlayer player;
public String[]
video_path =
{"https://ellovidsout.s3.amazonaws.com/1265/9/1422967594.mp4.m3u8", "https://ellovidsout.s3.amazonaws.com/1260/9/1422887544.mp4.m3u8"};
#Override
public void onCreate() {
super.onCreate();
player = new MediaPlayer();
player.setOnPreparedListener(this);
player.setOnCompletionListener(this);
player.setOnSeekCompleteListener(this);
player.setScreenOnWhilePlaying(true);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
playVideo();
Notification note = new Notification(
R.drawable.ic_launcher, "Can you hear the music?", System.currentTimeMillis()
);
Intent i = new Intent(this, MediaPlayerService.class);
i.setFlags(
Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP
);
PendingIntent pi = PendingIntent.getActivity(
this, 0, i, 0
);
note.setLatestEventInfo(
this, "Fake Player", "Now Playing: \"Ummmm, Nothing\"", pi
);
note.flags |= Notification.FLAG_NO_CLEAR;
startForeground(1337, note);
return super.onStartCommand(intent, flags, startId);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
super.onDestroy();
player.stop();
player.release();
player = null;
}
private Thread playback = new Thread(
new Runnable() {
public void run() {
try {
try {
player.setDataSource(
MediaPlayerService.this, Uri.parse(
video_path[0]
)
);
player.prepareAsync();
} catch (IOException e) {
Log.e(TAG, "Error while playing video: " + e.getMessage());
}
} catch (IllegalArgumentException e) {
Log.e(TAG, "Error while playing video: " + e.getMessage());
}
}
}
);
private void playVideo() {
if (player!=null&&!playback.isAlive()) playback.start();
}
public void onPrepared(MediaPlayer mp) {
if (!player.isPlaying()) {
player.start();
BusProvider.getInstance()
.post(player);
}
}
public void onCompletion(MediaPlayer mp) {
try {
player.setDataSource(
MediaPlayerService.this, Uri.parse(
video_path[0]
)
);
} catch (IOException e) {
Log.e(TAG, "Error while playing video: " + e.getMessage());
}
player.prepareAsync();
}
public void onSeekComplete(MediaPlayer mp) {
}
}
you missed in onStop:
#Override
protected void onStop() {
holder.removeCallback(this);
super.onStop();
}
please add the crash report
I have an app which just plays the same video in loop. Everything works as expected, except for one thing:
I want to stop the playback if I press the back button, but I am not able to get it to work. My activity simply ignore that I press it and instead I get an ANR. I thought that using onBackPressed() should handle this case.
Can anyone tell me, what I am doing wrong???
Here is my code:
package dk.test.videoplayer;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnBufferingUpdateListener;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.media.MediaPlayer.OnVideoSizeChangedListener;
import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Toast;
public class MainActivity extends Activity implements
OnBufferingUpdateListener, OnCompletionListener, OnPreparedListener, OnVideoSizeChangedListener, SurfaceHolder.Callback, OnClickListener {
private SurfaceView mSurfaceView = null;
private SurfaceHolder mSurfaceHolder = null;
private String videoPath;
private MediaPlayer mMediaPlayer = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
System.out.println("onCreate called");
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN |
WindowManager.LayoutParams.TYPE_APPLICATION_PANEL |
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON |
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD |
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE);
mSurfaceView = new SurfaceView(this);
setContentView(mSurfaceView);
mSurfaceView.setOnClickListener(this);
mSurfaceHolder = mSurfaceView.getHolder();
mSurfaceHolder.addCallback(this);
videoPath = "android.resource://dk.beatpro.videoplayer/raw/demo_video";
try {
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setOnBufferingUpdateListener(this);
mMediaPlayer.setOnCompletionListener(this);
mMediaPlayer.setOnPreparedListener(this);
mMediaPlayer.setOnVideoSizeChangedListener(this);
mMediaPlayer.setScreenOnWhilePlaying(true);
}
catch (Exception e) {
System.out.println(e.toString());
}
}
#Override
protected void onResume() {
super.onResume();
System.out.println("onResume called");
}
#Override
public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
}
#Override
public void onPrepared(MediaPlayer mp) {
System.out.println("onPrepared called");
if (!mMediaPlayer.isPlaying())
mMediaPlayer.start();
}
#Override
public void onCompletion(MediaPlayer mp) {
System.out.println("onCompletion() called");
playVideo();
}
#Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
System.out.println("onPause() called");
releaseMediaPlayer();
}
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
releaseMediaPlayer();
}
public void surfaceCreated(SurfaceHolder holder) {
System.out.println("surfaceCreated() called");
mMediaPlayer.setDisplay(mSurfaceHolder);
playVideo();
}
private void playVideo() {
System.out.println("playVideo() called");
try {
mMediaPlayer.reset();
mMediaPlayer.setDataSource(this, Uri.parse(videoPath));
mMediaPlayer.setDisplay(mSurfaceHolder);
mMediaPlayer.prepareAsync();
}
catch (Exception e) {
System.out.println(e.toString());
}
}
private void releaseMediaPlayer() {
if (mMediaPlayer != null) {
if (mMediaPlayer.isPlaying())
mMediaPlayer.stop();
mMediaPlayer.release();
mMediaPlayer = null;
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
System.out.println("surfaceChanged() called");
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
System.out.println("surfaceDestroyed() called");
}
#Override
public void onBackPressed() {
System.out.println("onBackPressed() called");
releaseMediaPlayer();
super.onBackPressed();
}
#Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
Toast.makeText(this, "Touch event", Toast.LENGTH_SHORT).show();
return super.onTouchEvent(event);
}
#Override
public void onClick(View v) {
System.out.println("onClick() called");
Toast.makeText(this, "Click click", Toast.LENGTH_SHORT).show();
}
}
Call super.onBackPressed(); before your code in onBackPressed(..)
#Override
public void onBackPressed() {
super.onBackPressed();
System.out.println("onBackPressed() called");
releaseMediaPlayer();
}
Just call super.onBackPressed before releasing media player.
EDIT:
Also try removing the
mMediaPlayer=null;
statement in your releaseMediaPlayer() method.
I am making an app that uses touchless gestures to turn off and on the flashilight in my Android app. It turns on just fine, but I can't get it to turn back off. Thanks in advance for any help.
Here is my MainActivity.java
package com.proximitysensorapp.primo.app;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.widget.TextView;
import java.io.IOException;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
public class MainActivity extends Activity implements SensorEventListener, Callback
{
SensorManager sm;
Sensor s;
TextView et1;
Intent Activitynew;
Camera camera;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
public void TurnOn(View view)
{
if (FlashAvailable() && camera != null)
{
Parameters p = camera.getParameters();
p.setFlashMode(Parameters.FLASH_MODE_TORCH);
camera.setParameters(p);
//camera.startPreview();
try
{
camera.setPreviewDisplay(surfaceHolder);
}
catch (IOException e) {
e.printStackTrace();
}
}
}
public void TurnOff(View view) {
if (FlashAvailable() && camera != null) {
Parameters p = camera.getParameters();
p.setFlashMode(Parameters.FLASH_MODE_OFF);
camera.setParameters(p);
//camera.stopPreview();
}
}
#SuppressWarnings("deprecation")
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sm = (SensorManager) getSystemService(SENSOR_SERVICE);
s = sm.getDefaultSensor(Sensor.TYPE_PROXIMITY);
sm.registerListener(this, s, SensorManager.SENSOR_DELAY_NORMAL);
Activitynew = new Intent(MainActivity.this, Activity2.class);
surfaceView = (SurfaceView) this.findViewById(R.id.surface1);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
#Override
public void onResume()
{
super.onResume();
try {
camera = Camera.open();
} catch (Exception e) {
//---exception handling here---
Log.d("Flashlight", e.toString());
}
}
#Override
public void onPause() {
super.onPause();
TurnOff(null);
camera.release();
}
private Boolean FlashAvailable() {
return getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
}
#Override
public void onAccuracyChanged(Sensor arg0, int arg1)
{
}
#Override
public void onSensorChanged(SensorEvent event)
{
if (event.sensor.getType() == Sensor.TYPE_PROXIMITY)
{
int temp = (int) event.values[0];
if (temp==1)
{
TurnOff(null);
}
else if (temp==0)
{
TurnOn(null);
}
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
}
you should add
mCamera.stopPreview();
mCamera.release();
inside your turnoff method
I am making a "Defend the castle" style android application. The game is complete, however I just need help closing my surfaceview and starting a new activity for when the the player has lost the game.
The condition for losing the game is just a boolean variable in my GameThread class. The variable is called "lost" and is by default set to false. When the life of the castle drops below 1, lost is set to true and a sound effect plays.
Ideally, I would like to stop the currently looping sound effects and open a new activity (which is already made and working) upon lost=true.
The main activity is as follows:
import android.app.Activity;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
public class MainActivity extends Activity {
Button btn_startGame;
Activity activity;
GameView mGameView;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
activity = this;
setContentView(R.layout.main);
btn_startGame = (Button) findViewById(R.id.btnStartGame);
btn_startGame.setOnClickListener(new OnClickListener() {
//#Override
public void onClick(View v) {
mGameView = new GameView(activity);
setContentView(mGameView);
mGameView.mThread.doStart();
}
});
}
#Override
public boolean onTouchEvent(MotionEvent event) {
try {
mGameView.mThread.onTouch(event);
} catch(Exception e) {}
return true;
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
// ignore orientation/keyboard change
super.onConfigurationChanged(newConfig);
}
}
The surfaceview is created in this class called GameView:
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.SurfaceHolder.Callback;
public class GameView extends SurfaceView implements Callback {
Context mContext;
GameThread mThread;
public GameView(Context context) {
super(context);
this.mContext = context;
getHolder().addCallback(this);
mThread = new GameThread(getHolder(), mContext, new Handler() {
#Override
public void handleMessage(Message m) {
// Use for pushing back messages.
}
});
setFocusable(true);
}
//#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
Log.d(this.getClass().toString(), "in SurfaceChanged()");
}
//#Override
public void surfaceCreated(SurfaceHolder holder) {
Log.d(this.getClass().toString(), "in SurfaceCreated()");
mThread.running = true;
mThread.start();
}
//#Override
public void surfaceDestroyed(SurfaceHolder holder) {
Log.d(this.getClass().toString(), "in SurfaceDestroyed()");
boolean retry = true;
mThread.running = false;
while (retry) {
try {
mThread.join();
retry = false;
} catch (InterruptedException e) {
}
GameThread.music.stop();
GameThread.groan1.stop();
GameThread.groan2.stop();
GameThread.walk.stop();
GameThread.music.release();
GameThread.groan1.release();
GameThread.groan2.release();
GameThread.walk.release();
GameThread.shoot.release();
}
}
}
The GameThread class contains all of the drawing, the logic and all a run method (below).
#Override
public void run() {
// check if condition here
if(lost){
mContext.runOnUiThread(new Runnable() {
#Override
public void run() {
//start Activity here
Intent intent = new Intent(mContext, LoseActivity.class);
mContext.startActivity(intent);
}
});
}
else{
if (running == true) {
while (running) {
Canvas c = null;
try {
c = mHolder.lockCanvas();
if (width == 0) {
width = c.getWidth();
height = c.getHeight();
player.x = 50;
player.y = 45;
}
synchronized (mHolder) {
long now = System.currentTimeMillis();
update();
draw(c);
ifps++;
if (now > (mLastTime + 1000)) {
mLastTime = now;
fps = ifps;
ifps = 0;
}
}
} finally {
if (c != null) {
mHolder.unlockCanvasAndPost(c);
}
}
}
}
}
The activity that I want to start is called LoseActivity.class. Thank you in advance for any and all help. If anybody needs any further code/explanations, I will be more than happy to post it.
Use runOnUiThread for starting Activity from Thread as:
Change your main Activity as:
public class MainActivity extends Activity {
Button btn_startGame;
Activity activity;
GameView mGameView;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
activity = this;
setContentView(R.layout.main);
btn_startGame = (Button) findViewById(R.id.btnStartGame);
btn_startGame.setOnClickListener(new OnClickListener() {
//#Override
public void onClick(View v) {
mGameView = new GameView(activity,MainActivity.this);
setContentView(mGameView);
mGameView.mThread.doStart();
}
});
}
///your code.....
Change your GameView class as:
public class GameView extends SurfaceView implements Callback {
Context mContext;
Activity contextx;
GameThread mThread;
public GameView(Context context,Activity contextx) {
super(context);
this.mContext = context;
this.contextx=contextx;
getHolder().addCallback(this);
mThread = new GameThread(getHolder(), mContext, new Handler() {
#Override
public void handleMessage(Message m) {
// Use for pushing back messages.
}
});
setFocusable(true);
}
//your code here..........
#Override
public void run() {
// check if condition here
if(lost){
contextx.runOnUiThread(new Runnable() {
#Override
public void run() {
//start Activity here
Intent intent = new Intent(contextx, LoseActivity.class);
contextx.startActivity(intent);
}
});
}
else{
//your code here.........