I can't believe why this code not working. I tried several times but to no avail, how can I solve this problem, how are you doing it?
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"
>
<Button
android:text="Start"
android:id="#+id/StartService"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</Button>
<Button
android:text="Stop"
android:id="#+id/StopService"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</Button>
<SurfaceView
android:id="#+id/surfaceView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</SurfaceView>
</LinearLayout>
java (CameraRecorder Class)
import android.app.Activity;
import android.content.Intent;
import android.hardware.Camera;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
public class CameraRecorder extends Activity implements SurfaceHolder.Callback {
private static final String TAG = CameraRecorder.class.getSimpleName();
public static SurfaceView mSurfaceView;
public static SurfaceHolder mSurfaceHolder;
public static Camera mCamera;
public static boolean mPreviewRunning;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSurfaceView = (SurfaceView) findViewById(R.id.surfaceView1);
mSurfaceHolder = mSurfaceView.getHolder();
mSurfaceHolder.addCallback(this);
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
Button btnStart = (Button) findViewById(R.id.StartService);
btnStart.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
Intent intent = new Intent(CameraRecorder.this, RecorderService.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startService(intent);
finish();
}
});
Button btnStop = (Button) findViewById(R.id.StopService);
btnStop.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
stopService(new Intent(CameraRecorder.this, RecorderService.class));
}
});
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
}
java (RecorderService Class)
import android.app.Service;
import android.content.Intent;
import android.hardware.Camera;
import android.hardware.Camera.Size;
import android.media.MediaRecorder;
import android.os.Environment;
import android.os.IBinder;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.Toast;
import java.io.IOException;
import java.util.List;
public class RecorderService extends Service {
private static final String TAG = "RecorderService";
private SurfaceView mSurfaceView;
private SurfaceHolder mSurfaceHolder;
private static Camera mServiceCamera;
private boolean mRecordingStatus;
private MediaRecorder mMediaRecorder;
#Override
public void onCreate() {
mRecordingStatus = false;
mServiceCamera = CameraRecorder.mCamera;
mSurfaceView = CameraRecorder.mSurfaceView;
mSurfaceHolder = CameraRecorder.mSurfaceHolder;
super.onCreate();
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
if (mRecordingStatus == false)
startRecording();
return START_STICKY;
}
#Override
public void onDestroy() {
stopRecording();
mRecordingStatus = false;
super.onDestroy();
}
public boolean startRecording(){
try {
Toast.makeText(getBaseContext(), "Recording Started", Toast.LENGTH_SHORT).show();
mServiceCamera = Camera.open();
Camera.Parameters params = mServiceCamera.getParameters();
mServiceCamera.setParameters(params);
Camera.Parameters p = mServiceCamera.getParameters();
final List<Size> listPreviewSize = p.getSupportedPreviewSizes();
for (Size size : listPreviewSize) {
Log.i(TAG, String.format("Supported Preview Size (%d, %d)", size.width, size.height));
}
Size previewSize = listPreviewSize.get(0);
p.setPreviewSize(previewSize.width, previewSize.height);
mServiceCamera.setParameters(p);
try {
mServiceCamera.setPreviewDisplay(mSurfaceHolder);
mServiceCamera.startPreview();
}
catch (IOException e) {
Log.e(TAG, e.getMessage());
e.printStackTrace();
}
mServiceCamera.unlock();
mMediaRecorder = new MediaRecorder();
mMediaRecorder.setCamera(mServiceCamera);
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mMediaRecorder.setOutputFile(Environment.getExternalStorageDirectory().getPath() + "/video.mp4");
mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
mMediaRecorder.prepare();
mMediaRecorder.start();
mRecordingStatus = true;
return true;
} catch (IllegalStateException e) {
Log.d(TAG, e.getMessage());
e.printStackTrace();
return false;
} catch (IOException e) {
Log.d(TAG, e.getMessage());
e.printStackTrace();
return false;
}
}
public void stopRecording() {
Toast.makeText(getBaseContext(), "Recording Stopped", Toast.LENGTH_SHORT).show();
try {
mServiceCamera.reconnect();
} catch (IOException e) {
e.printStackTrace();
}
mMediaRecorder.stop();
mMediaRecorder.reset();
mServiceCamera.stopPreview();
mMediaRecorder.release();
mServiceCamera.release();
mServiceCamera = null;
}
}
Android Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.camerarecorder">
<uses-permission android:name="android.permission.RECORD_VIDEO" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<application android:icon="#drawable/ic_launcher_background"
android:label="#string/app_name">
<activity android:name="com.example.camerarecorder.CameraRecorder"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="com.example.camerarecorder.RecorderService"
android:enabled="true"
/>
</application>
</manifest>
I believe you haven't ask for the runtime permission
private int REQUEST_CODE_PERMISSIONS = 101;
private final String[] REQUIRED_PERMISSIONS = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.RECORD_AUDIO,
Manifest.permission.CAMERA
};
if (allPermissionsGranted()) {
startCamera(); //start camera if permission has been granted by user
} else {
ActivityCompat.requestPermissions(this, REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS);
}
Calling Permssion Context
private boolean allPermissionsGranted(){
for(String permission : REQUIRED_PERMISSIONS){
if(ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED){
return false;
}
}
return true;
}
if Permission not granted
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if(requestCode == REQUEST_CODE_PERMISSIONS){
if(allPermissionsGranted()){
startCamera();
} else{
Toast.makeText(this, "Permissions not granted by the user.", Toast.LENGTH_SHORT).show();
finish();
}
}
}
You need to implement the camera dependency in gradle file.
Related
I'm using Android Studio to make my webview app and on my website I'm using webcam.js to access the camera. When it's opening the webcam view, it's returning error "Webcam.js error : could not access webCam: PermissionDeniedError". How do I fix this?
Error picture:
webcam error
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.testabsen">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_GPS" />
<uses-permission android:name="android.permission.ACCESS_ASSISTED_GPS" />
<uses-permission android:name="android.permission.ACCESS_LOCATION" />
<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:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.TestAbsen">
<activity android:name=".MainActivity" android:theme="#style/Theme.AppCompat.DayNight.NoActionBar"></activity>
<activity
android:name=".SplashActivity"
android:theme="#style/Theme.AppCompat.Light.NoActionBar"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
MainActivity
package com.example.testabsen;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import android.Manifest;
import android.app.AlertDialog;
import android.app.DownloadManager;
import android.content.ActivityNotFoundException;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.webkit.DownloadListener;
import android.webkit.URLUtil;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;
import com.google.android.material.bottomnavigation.BottomNavigationView;
public class MainActivity extends AppCompatActivity {
WebView webView;
WebSettings webSettings;
private SwipeRefreshLayout mySwipeRefreshLayout;
private ValueCallback<Uri> mUploadMessage;
public ValueCallback<Uri[]> uploadMessage;
public static final int REQUEST_SELECT_FILE = 100;
private final static int FILECHOOSER_RESULTCODE = 1;
private WebChromeClient.CustomViewCallback mCustomViewCallback;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
checkPermission();
setContentView(R.layout.activity_main);
webView = findViewById(R.id.webView_frame);
webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setDomStorageEnabled(true);
webSettings.setUseWideViewPort(true);
webSettings.setAppCacheEnabled(false);
webSettings.getSaveFormData();
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
webSettings.getJavaScriptEnabled();
webSettings.setAllowFileAccess(true);
webSettings.setAllowContentAccess(true);
webSettings.setLoadsImagesAutomatically(true);
webView.setWebViewClient(new WebViewClient());
downloadSetting();
uploadSetting();
setMySwipeRefreshLayout();
webView.loadUrl('webviewurl');
}
final void setMySwipeRefreshLayout(){
mySwipeRefreshLayout = findViewById(R.id.swipeContainer);
mySwipeRefreshLayout.setOnRefreshListener(
new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
webView.reload();
mySwipeRefreshLayout.setRefreshing(false);
}
}
);
}
#Override
final public void onActivityResult(int requestCode, int resultCode, Intent intent)
{
super.onActivityResult(requestCode, resultCode, intent);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
{
if (requestCode == REQUEST_SELECT_FILE)
{
if (uploadMessage == null)
return;
uploadMessage.onReceiveValue(WebChromeClient.FileChooserParams.parseResult(resultCode, intent));
uploadMessage = null;
}
}
else if (requestCode == FILECHOOSER_RESULTCODE)
{
if (null == mUploadMessage)
return;
Uri result = intent == null || resultCode != MainActivity.RESULT_OK ? null : intent.getData();
mUploadMessage.onReceiveValue(result);
mUploadMessage = null;
}
else
Toast.makeText(getApplicationContext(), "Failed to Upload Image", Toast.LENGTH_LONG).show();
}
protected void downloadSetting() {
webView.setDownloadListener(new DownloadListener() {
public void onDownloadStart(String url, String userAgent, String contentDescription, String mimetype, long contentLength) {
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
String fileName = URLUtil.guessFileName(url,contentDescription,mimetype);
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS,fileName);
DownloadManager dManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
dManager.enqueue(request);
Toast.makeText(getApplicationContext(), "Downloaded", Toast.LENGTH_SHORT).show();
}
});
}
protected void uploadSetting() {
webView.setWebChromeClient(new WebChromeClient(){
final protected void openFileChooser(ValueCallback uploadMsg, String acceptType)
{
mUploadMessage = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
startActivityForResult(Intent.createChooser(i, "File Browser"), FILECHOOSER_RESULTCODE);
}
public boolean onShowFileChooser(WebView mWebView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams)
{
if (uploadMessage != null) {
uploadMessage.onReceiveValue(null);
uploadMessage = null;
}
uploadMessage = filePathCallback;
Intent intent = fileChooserParams.createIntent();
try
{
startActivityForResult(intent, REQUEST_SELECT_FILE);
} catch (ActivityNotFoundException e)
{
uploadMessage = null;
Toast.makeText(getApplicationContext() , "Cannot Open File Chooser", Toast.LENGTH_LONG).show();
return false;
}
return true;
}
protected void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture)
{
mUploadMessage = uploadMsg;
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
startActivityForResult(Intent.createChooser(intent, "File Browser"), FILECHOOSER_RESULTCODE);
}
protected void openFileChooser(ValueCallback<Uri> uploadMsg)
{
mUploadMessage = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
startActivityForResult(Intent.createChooser(i, "File Chooser"), FILECHOOSER_RESULTCODE);
}
});
}
protected void checkPermission(){
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){
if(checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED){
if(shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)){
ActivityCompat.requestPermissions(
MainActivity.this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
123
);
}else {
// Request permission
ActivityCompat.requestPermissions(
MainActivity.this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
123
);
}
}
}
}
#Override
public void onBackPressed() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setCancelable(false);
builder.setMessage("Apakah anda yakin ingin keluar?");
builder.setPositiveButton("Ya", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
//if user pressed "yes", then he is allowed to exit from application
finish();
}
});
builder.setNegativeButton("Tidak",new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
//if user select "No", just cancel this dialog and continue with app
dialog.cancel();
}
});
AlertDialog alert=builder.create();
alert.show();
}
}
I'm implementing google plus login in android. I have been following along with the tutorial
developers.google.com
In PeopleApi is when i call Plus.PeopleApi.getCurrentPerson(mGoogleApiClient) is always get null.
I have correctly configured SHA at console.developers.google.com and even filled in the consent screen
Please help, i have tried everything.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_PROFILE" />
<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" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
</application>
MainActivity file
package dailyblog.ebt.com.dailyapp;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.Scopes;
import com.google.android.gms.common.api.CommonStatusCodes;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.plus.People;
import com.google.android.gms.plus.Plus;
import com.google.android.gms.plus.PlusClient;
import com.google.android.gms.plus.model.people.Person;
import com.google.android.gms.plus.model.people.PersonBuffer;
public class MainActivity extends Activity implements View.OnClickListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, ResultCallback<People.LoadPeopleResult> {
private GoogleApiClient mGoogleApiClient;
private boolean mIntentInProgress;
private static final int RC_SIGN_IN = 0;
private boolean mSignInClicked;
private ConnectionResult mConnectionResult;
private PlusClient mPlusClient;
// Button btnsign;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGoogleApiClient = new GoogleApiClient.Builder(this).
addConnectionCallbacks(this).
addOnConnectionFailedListener(this).
addApi(Plus.API).
addScope(Plus.SCOPE_PLUS_LOGIN).
addScope(Plus.SCOPE_PLUS_PROFILE).
build();
findViewById(R.id.sign_in_button).setOnClickListener(this);
ConnectivityManager connec = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
if (connec != null &&
(connec.getNetworkInfo(1).getState() == NetworkInfo.State.CONNECTED) ||
(connec.getNetworkInfo(0).getState() == NetworkInfo.State.CONNECTED)){
Toast.makeText(getApplicationContext(), "Connected to the internet", Toast.LENGTH_LONG).show();
} else if (connec.getNetworkInfo(0).getState() == NetworkInfo.State.DISCONNECTED ||
connec.getNetworkInfo(1).getState() == NetworkInfo.State.DISCONNECTED ) {
//Not connected.
Toast.makeText(getApplicationContext(), "Not connected to the internet", Toast.LENGTH_LONG).show();
}
}
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
Log.d("onstat","sau");
}
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
#Override
public void onConnectionFailed(ConnectionResult result) {
if (!mIntentInProgress) {
// Store the ConnectionResult so that we can use it later when the user clicks
// 'sign-in'.
mConnectionResult = result;
if (mSignInClicked) {
// The user has already clicked 'sign-in' so we attempt to resolve all
// errors until the user is signed in, or they cancel.
resolveSignInError();
}
}
}
private void resolveSignInError() {
if (mConnectionResult.hasResolution()) {
try {
mIntentInProgress = true;
startIntentSenderForResult(mConnectionResult.getResolution().getIntentSender(),
RC_SIGN_IN, null, 0, 0, 0);
} catch (IntentSender.SendIntentException e) {
// The intent was canceled before it was sent. Return to the default
// state and attempt to connect to get an updated ConnectionResult.
mIntentInProgress = false;
mGoogleApiClient.connect();
}
}
}
protected void onActivityResult(int requestCode, int responseCode, Intent intent) {
if (requestCode == RC_SIGN_IN) {
if (responseCode != RESULT_OK) {
mSignInClicked = false;
}
mIntentInProgress = false;
if (!mGoogleApiClient.isConnecting()) {
mGoogleApiClient.connect();
}
}
}
#Override
public void onClick(View v) {
if (v.getId() == R.id.sign_in_button
&& !mGoogleApiClient.isConnecting()) {
mSignInClicked = true;
if(!mGoogleApiClient.isConnected())
resolveSignInError();
else {
Toast.makeText(this, "User already connected!", Toast.LENGTH_LONG).show();
}
}
}
#Override
public void onConnectionSuspended(int i) {
mGoogleApiClient.connect();
}
#Override
public void onConnected(Bundle bundle) {
mSignInClicked = false;
Toast.makeText(this, "User is connected!", Toast.LENGTH_LONG).show();
Plus.PeopleApi.loadVisible(mGoogleApiClient,null).setResultCallback(this);
String personName="Unknown";
Toast.makeText(this, "username is -> " + personName, Toast.LENGTH_LONG).show();
String email = Plus.AccountApi.getAccountName(mGoogleApiClient);
Toast.makeText(this, "email -> " + Plus.PeopleApi.getCurrentPerson(mGoogleApiClient), Toast.LENGTH_LONG).show();
if (Plus.PeopleApi.getCurrentPerson(mGoogleApiClient) != null) {
Person currentPerson = Plus.PeopleApi.getCurrentPerson(mGoogleApiClient);
personName = currentPerson.getDisplayName();
Toast.makeText(this, "username is -> " + personName, Toast.LENGTH_LONG).show();
}
}
#Override
public void onResult(People.LoadPeopleResult peopleData) {
Toast.makeText(this, "onteid!", Toast.LENGTH_LONG).show();
}
}
After searching in life cycle I have found that my application needs to use the destroy(); method. However, when I implement this the application doesn't close. I am trying to apply this to the button exitButton. If someone could direct me in the right direction then that would be great.
MainActivity.java
package com.webcraftbd.radio;
import android.os.Bundle;
import android.os.IBinder;
import android.app.Activity;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.TaskStackBuilder;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
static String radioTitle = "Android Live Radio";
static String radioStreamURL = "http://stream.infowars.com:80";
Button playButton;
Button pauseButton;
Button stopButton;
Button exitbutton;
TextView statusTextView, bufferValueTextView;
NotificationCompat.Builder notifyBuilder;
private RadioUpdateReceiver radioUpdateReceiver;
private RadioService radioServiceBinder;
//Notification
private static final int NOTIFY_ME_ID=12345;
private NotificationManager notifyMgr=null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView titleTextView = (TextView) this.findViewById(R.id.titleTextView);
titleTextView.setText(radioTitle);
playButton = (Button) this.findViewById(R.id.PlayButton);
pauseButton = (Button) this.findViewById(R.id.PauseButton);
stopButton = (Button) this.findViewById(R.id.StopButton);
playButton.setEnabled(true);
pauseButton.setEnabled(false);
stopButton.setEnabled(false);
pauseButton.setVisibility(View.INVISIBLE);
statusTextView = (TextView) this.findViewById(R.id.StatusDisplayTextView);
notifyMgr=(NotificationManager)getSystemService(NOTIFICATION_SERVICE);
showNotification();
// Bind to the service
Intent bindIntent = new Intent(this, RadioService.class);
bindService(bindIntent, radioConnection, Context.BIND_AUTO_CREATE);
startService(new Intent(this, RadioService.class));
}
public void onClickPlayButton(View view) {
radioServiceBinder.play();
}
public void onClickPauseButton(View view) {
radioServiceBinder.pause();
}
public void onClickStopButton(View view) {
radioServiceBinder.stop();
}
public void onClicexitbutton(View view) {
super.finish();
super.onDestroy();
radioServiceBinder.onDestroy();
radioServiceBinder.stop();
radioServiceBinder.stopService(getParentActivityIntent());
}
#Override
protected void onPause() {
super.onPause();
if (radioUpdateReceiver != null)
unregisterReceiver(radioUpdateReceiver);
}
#Override
protected void onResume() {
super.onResume();
/* Register for receiving broadcast messages */
if (radioUpdateReceiver == null) radioUpdateReceiver = new RadioUpdateReceiver();
registerReceiver(radioUpdateReceiver, new IntentFilter(RadioService.MODE_CREATED));
registerReceiver(radioUpdateReceiver, new IntentFilter(RadioService.MODE_DESTROYED));
registerReceiver(radioUpdateReceiver, new IntentFilter(RadioService.MODE_STARTED));
registerReceiver(radioUpdateReceiver, new IntentFilter(RadioService.MODE_PREPARED));
registerReceiver(radioUpdateReceiver, new IntentFilter(RadioService.MODE_PLAYING));
registerReceiver(radioUpdateReceiver, new IntentFilter(RadioService.MODE_PAUSED));
registerReceiver(radioUpdateReceiver, new IntentFilter(RadioService.MODE_STOPPED));
registerReceiver(radioUpdateReceiver, new IntentFilter(RadioService.MODE_COMPLETED));
registerReceiver(radioUpdateReceiver, new IntentFilter(RadioService.MODE_ERROR));
registerReceiver(radioUpdateReceiver, new IntentFilter(RadioService.MODE_BUFFERING_START));
registerReceiver(radioUpdateReceiver, new IntentFilter(RadioService.MODE_BUFFERING_END));
}
protected void onDestroy(){
super.onDestroy();
}
/* Receive Broadcast Messages from RadioService */
private class RadioUpdateReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(RadioService.MODE_CREATED)) {
showNotification();
}
else if (intent.getAction().equals(RadioService.MODE_DESTROYED)) {
clearNotification();
}
else if (intent.getAction().equals(RadioService.MODE_STARTED)) {
playButton.setEnabled(false);
pauseButton.setEnabled(false);
stopButton.setEnabled(true);
playButton.setVisibility(View.VISIBLE);
pauseButton.setVisibility(View.INVISIBLE);
updateStatus("Buffering...");
}
else if (intent.getAction().equals(RadioService.MODE_PREPARED)) {
playButton.setEnabled(true);
pauseButton.setEnabled(false);
stopButton.setEnabled(false);
playButton.setVisibility(View.VISIBLE);
pauseButton.setVisibility(View.INVISIBLE);
updateStatus("Rady");
}
else if (intent.getAction().equals(RadioService.MODE_BUFFERING_START)) {
updateStatus("Buffering...");
}
else if (intent.getAction().equals(RadioService.MODE_BUFFERING_END)) {
updateStatus("Playing");
}
else if (intent.getAction().equals(RadioService.MODE_PLAYING)) {
playButton.setEnabled(false);
pauseButton.setEnabled(true);
stopButton.setEnabled(true);
playButton.setVisibility(View.INVISIBLE);
pauseButton.setVisibility(View.VISIBLE);
showNotification();
updateStatus("Playing");
}
else if(intent.getAction().equals(RadioService.MODE_PAUSED)) {
playButton.setEnabled(true);
pauseButton.setEnabled(false);
stopButton.setEnabled(true);
playButton.setVisibility(View.VISIBLE);
pauseButton.setVisibility(View.INVISIBLE);
updateStatus("Paused");
}
else if(intent.getAction().equals(RadioService.MODE_STOPPED)) {
playButton.setEnabled(true);
pauseButton.setEnabled(false);
stopButton.setEnabled(false);
playButton.setVisibility(View.VISIBLE);
pauseButton.setVisibility(View.INVISIBLE);
updateStatus("Stopped");
clearNotification();
}
else if(intent.getAction().equals(RadioService.MODE_COMPLETED)) {
playButton.setEnabled(true);
pauseButton.setEnabled(false);
stopButton.setEnabled(false);
playButton.setVisibility(View.VISIBLE);
pauseButton.setVisibility(View.INVISIBLE);
updateStatus("Stopped");
}
else if(intent.getAction().equals(RadioService.MODE_ERROR)) {
playButton.setEnabled(true);
pauseButton.setEnabled(false);
stopButton.setEnabled(false);
playButton.setVisibility(View.VISIBLE);
pauseButton.setVisibility(View.INVISIBLE);
updateStatus("Error");
}
}
}
public void updateStatus(String status) {
try {
if(notifyBuilder!=null && notifyMgr!=null) {
notifyBuilder.setContentText(status).setWhen(0);
notifyMgr.notify(NOTIFY_ME_ID,notifyBuilder.build());
}
statusTextView.setText(status);
}
catch(Exception e) {
e.printStackTrace();
}
}
public void showNotification() {
notifyBuilder = new NotificationCompat.Builder(this).setSmallIcon(R.drawable.ic_launcher).setContentTitle(radioTitle).setContentText("");
Intent resultIntent = new Intent(this, MainActivity.class);
resultIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
resultIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
notifyBuilder.setContentIntent(resultPendingIntent);
notifyMgr = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notifyMgr.notify(NOTIFY_ME_ID, notifyBuilder.build());
}
public void clearNotification() {
notifyMgr.cancel(NOTIFY_ME_ID);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.about:
Intent i = new Intent(this, AboutActivity.class);
startActivity(i);
return true;
}
return super.onOptionsItemSelected(item);
}
// Handles the connection between the service and activity
private ServiceConnection radioConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
radioServiceBinder = ((RadioService.RadioBinder)service).getService();
}
public void onServiceDisconnected(ComponentName className) {
radioServiceBinder = null;
}
};
}
enter code here
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#4a4a4a"
tools:context=".MainActivity" >
<LinearLayout
android:id="#+id/player_header_bg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true" >
<TextView
android:id="#+id/titleTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="48dp"
android:gravity="center"
android:text="Classic Christmas Radio"
android:textAlignment="center"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#c0413b"
android:textSize="40sp" />
</LinearLayout>
<ImageView
android:id="#+id/imageView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:layout_marginBottom="120dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="110dp"
android:src="#drawable/cover" />
<TextView
android:id="#+id/StatusDisplayTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/PauseButton"
android:layout_alignLeft="#+id/imageView1"
android:layout_alignRight="#+id/imageView1"
android:gravity="center"
android:text="Unknown" />
<Button
android:id="#+id/PauseButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#id/StatusDisplayTextView"
android:layout_alignParentBottom="true"
android:layout_marginBottom="0.0dip"
android:background="#drawable/btn_pause"
android:onClick="onClickPauseButton" />
<Button
android:id="#+id/PlayButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#id/StatusDisplayTextView"
android:layout_alignParentBottom="true"
android:layout_marginBottom="0.0dip"
android:background="#drawable/btn_play"
android:onClick="onClickPlayButton" />
<Button
android:id="#+id/StopButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignRight="#id/StatusDisplayTextView"
android:layout_marginBottom="0.0dip"
android:background="#drawable/btn_stop"
android:onClick="onClickStopButton" />
<Button
android:id="#+id/exitbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/StatusDisplayTextView"
android:layout_centerHorizontal="true"
android:text="Button" />
</RelativeLayout>
RadioService.java
package com.webcraftbd.radio;
import java.io.IOException;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnInfoListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
public class RadioService extends Service implements OnErrorListener, OnCompletionListener, OnPreparedListener, OnInfoListener {
private MediaPlayer mediaPlayer;
private String radioStreamURL = MainActivity.radioStreamURL;
public static final String MODE_CREATED = "CREATED";
public static final String MODE_DESTROYED = "DESTROYED";
public static final String MODE_PREPARED = "PREPARED";
public static final String MODE_STARTED = "STARTED";
public static final String MODE_PLAYING = "PLAYING";
public static final String MODE_PAUSED = "PAUSED";
public static final String MODE_STOPPED = "STOPPED";
public static final String MODE_COMPLETED = "COMPLETED";
public static final String MODE_ERROR = "ERROR";
public static final String MODE_BUFFERING_START = "BUFFERING_START";
public static final String MODE_BUFFERING_END = "BUFFERING_END";
private boolean isPrepared = false;
private final IBinder binder = new RadioBinder();
#Override
public void onCreate() {
/* Create MediaPlayer when it starts for first time */
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnCompletionListener(this);
mediaPlayer.setOnErrorListener(this);
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.setOnInfoListener(this);
sendBroadcast(new Intent(MODE_CREATED));
}
#Override
public void onDestroy() {
super.onDestroy();
mediaPlayer.stop();
mediaPlayer.reset();
isPrepared = false;
sendBroadcast(new Intent(MODE_DESTROYED));
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
sendBroadcast(new Intent(MODE_STARTED));
/* Starts playback at first time or resumes if it is restarted */
if(mediaPlayer.isPlaying())
sendBroadcast(new Intent(MODE_PLAYING));
else if(isPrepared) {
sendBroadcast(new Intent(MODE_PAUSED));
}
else
prepare();
return Service.START_STICKY;
}
#Override
public void onPrepared(MediaPlayer _mediaPlayer) {
/* If radio is prepared then start playback */
sendBroadcast(new Intent(MODE_PREPARED));
isPrepared = true;
play();
}
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
/* When no stream found then complete the playback */
mediaPlayer.stop();
mediaPlayer.reset();
isPrepared = false;
sendBroadcast(new Intent(MODE_COMPLETED));
}
public void prepare() {
/* Prepare Async Task - starts buffering */
try {
mediaPlayer.setDataSource(radioStreamURL);
mediaPlayer.prepareAsync();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void play() {
if(isPrepared) {
mediaPlayer.start();
System.out.println("RadioService: play");
sendBroadcast(new Intent(MODE_PLAYING));
}
else
{
sendBroadcast(new Intent(MODE_STARTED));
prepare();
}
}
public void pause() {
mediaPlayer.pause();
System.out.println("RadioService: pause");
sendBroadcast(new Intent(MODE_PAUSED));
}
public void stop() {
mediaPlayer.stop();
mediaPlayer.reset();
isPrepared = false;
System.out.println("RadioService: stop");
sendBroadcast(new Intent(MODE_STOPPED));
}
#Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
/* Check when buffering is started or ended */
if(what == MediaPlayer.MEDIA_INFO_BUFFERING_START) {
sendBroadcast(new Intent(MODE_BUFFERING_START));
}
else if(what == MediaPlayer.MEDIA_INFO_BUFFERING_END) {
sendBroadcast(new Intent(MODE_BUFFERING_END));
}
return false;
}
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
sendBroadcast(new Intent(MODE_ERROR));
switch (what) {
case MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK:
Log.v("ERROR","MEDIA ERROR NOT VALID FOR PROGRESSIVE PLAYBACK " + extra);
break;
case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
Log.v("ERROR","MEDIA ERROR SERVER DIED " + extra);
break;
case MediaPlayer.MEDIA_ERROR_UNKNOWN:
Log.v("ERROR","MEDIA ERROR UNKNOWN " + extra);
break;
}
return false;
}
#Override
public IBinder onBind(Intent intent) {
return binder;
}
/* Allowing activity to access all methods of RadioService */
public class RadioBinder extends Binder {
RadioService getService() {
return RadioService.this;
}
}
}
Ok, after developing some pseudo and some logic, I have noticed that Andorid doesn't have an exit method in the way that you're hoping. When first reading the question I didn't realise that it was Android as I was multi-tasking. As you may notice, almost every android application doesn't have an exit button, and there is a reason for this. The reason being that Android is supposedly meant to load and unload applications through the OS, hence why you don't do it. If the user wanted to exit the application, they would do what they do with every other, enter the multi-tasking menu and swipe it off. Please read the following for more information: http://android.nextapp.com/site/fx/doc/exit
I am new to Android. I'm trying to create a music player which will play specific MP3 based on the count (controlled by Rc variable) and based on the button sequence (controlled by BitCount variable) should change. And I have one stop button by clicking which I should be able to stop the music.
My problem is everything is working fine when UI is on foreground but when screen goes to background then also music start running (it's OK let music be running on background) but when once again I bring my UI from background to foreground than by clicking stop button I am unable to stop the music, it runs continuously. This same problem is happening when I am rotating my mobile.
Code:
package com.example.tallite;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.app.Activity;
import android.content.SharedPreferences;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.Toast;
public class MainActivity extends Activity implements OnSeekBarChangeListener {
MediaPlayer OurSong;
public Handler handler1 = new Handler();
Button Start;
Button Stop;
Button Button21;
Button Button22;
Button StopButton;
public int GProgreess=0;
int Rc=0;
int BitCount=6;
int SeekPos=0;
int Period=500;
int BreakVar=0;
Thread myThread ;
public TextView text1,text2,text3,text4;
private SeekBar bar;
private TextView textProgress,textAction;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toast.makeText(this, "onCreate()", Toast.LENGTH_LONG).show();
text1 = (TextView)findViewById(R.id.textbit1);
text2 = (TextView)findViewById(R.id.textbit2);
text3 = (TextView)findViewById(R.id.textbit3);
text4 = (TextView)findViewById(R.id.textbit4);
Button21=(Button)findViewById(R.id.button21);
Button22=(Button)findViewById(R.id.button22);
StopButton=(Button)findViewById(R.id.buttonstop);
bar = (SeekBar)findViewById(R.id.seekBar1);
textProgress = (TextView)findViewById(R.id.textViewProgress);
OurSong=MediaPlayer.create(MainActivity.this,R.raw.a);
try {
OurSong.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
bar.setOnSeekBarChangeListener(this); // set seekbar listener.
/*handler1.post(runnable1);
stopPlaying();*/
StopButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v)
{
stopPlaying();
BitCount=5;
handler1.removeCallbacks(runnable1);
}/****End of on clk******/
});/*****End of set on clk listener*****/
Button21.setOnClickListener(new View.OnClickListener() {
public void onClick(View v)
{
stopPlaying();
Rc=0;
BitCount=13;
handler1.removeCallbacks(runnable1);
handler1.post(runnable1);
}/****End of on clk******/
});/*****End of set on clk listener*****/
Button22.setOnClickListener(new View.OnClickListener() {
public void onClick(View v)
{
stopPlaying();
Rc=0;
BitCount=15;
handler1.removeCallbacks(runnable1);
handler1.post(runnable1);
}/****End of on clk******/
});/*****End of set on clk listener*****/
}
#Override
protected void onStart() {
//the activity is become visible.
super.onStart();
/*handler1.removeCallbacks(runnable1);*/
}
#Override
protected void onPause() {
super.onPause();
}
#Override
protected void onResume() {
super.onResume();
}
#Override
protected void onStop() {
//the activity is no longer visible.
super.onStop();
Toast.makeText(this, "onStop()", Toast.LENGTH_LONG).show();
}
#Override
protected void onDestroy() {
//The activity about to be destroyed.
super.onDestroy();
Toast.makeText(this, "onDestroy()", Toast.LENGTH_LONG).show();
}
private void stopPlaying()
{
if (OurSong != null)
{
OurSong.stop();
OurSong.release();
OurSong = null;
}
}
/* private void stopPlaying()
{
OurSong.stop();
OurSong.release();
}*/
public Runnable runnable1= new Runnable() {
#Override
public void run() {
if(BitCount==13)
{
text1.setText("1");
text2.setText(""+Rc);
text3.setText(""+BitCount);
if(Rc==0||Rc==6||Rc==10)
{
stopPlaying();
OurSong=MediaPlayer.create(MainActivity.this,R.raw.a);
OurSong.start();
}
if(Rc==2||Rc==4||Rc==8||Rc==12)
{
stopPlaying();
OurSong=MediaPlayer.create(MainActivity.this,R.raw.b);
OurSong.start();
}
if(Rc==13)
{
stopPlaying();
OurSong=MediaPlayer.create(MainActivity.this,R.raw.c);
OurSong.start();
}
Rc++;
if(Rc>BitCount)
{
text4.setText(""+Rc);
Rc=0;
}
}/****End of bitcount=13****/
if(BitCount==15)
{
text1.setText("2");
text2.setText(""+Rc);
text3.setText(""+BitCount);
if(Rc==0||Rc==8||Rc==12)
{
stopPlaying();
OurSong=MediaPlayer.create(MainActivity.this,R.raw.a);
OurSong.start();
}
if(Rc==2||Rc==4||Rc==6||Rc==10||Rc==14)
{
stopPlaying();
OurSong=MediaPlayer.create(MainActivity.this,R.raw.b);
OurSong.start();
/* Toast.makeText(getApplicationContext(), "-",
Toast.LENGTH_LONG).show();*/
}
if(Rc==15)
{
stopPlaying();
OurSong=MediaPlayer.create(MainActivity.this,R.raw.c);
OurSong.start();
/*Toast.makeText(getApplicationContext(), "|",
Toast.LENGTH_LONG).show();*/
}
Rc++;
if(Rc>BitCount)
{
text4.setText(""+Rc);
Rc=0;
}
}/***End of bitcount=15***/
if(BitCount==5)
{
text1.setText("Rc"+Rc);
stopPlaying();
}
if(BitCount==6)
{
text1.setText("x"+Rc);
stopPlaying();
}
handler1.postDelayed(runnable1, Period);
}
};
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
GProgreess=progress+20;
textProgress.setText("Bit/Minute: "+(progress+20));
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
seekBar.setSecondaryProgress(seekBar.getProgress());
SeekPos=GProgreess;
Period=(int)(30000/SeekPos);
/*textProgress.setText("Period: "+Period);*/
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
When you close your app, ur activity is destroyed and hence reference to ur media player variable is lost. When you recreate ur activity you get a new set of reference and hence ur unable to stop it.
You will have to create a Service name it as MediaPlayerService which will deal with all media related actions like play, pause etc..
You can read about service over here:
http://developer.android.com/guide/components/services.html
If you want an example for media player, you can check RandomMusicPlayer, an excellent media player example provided by android in android sample projects.
Here is my implementation of MediaPlayerService
MediaPlayerService Class:
package com.cyberinsane.musicplayerlibrary;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.net.Uri;
import android.os.Binder;
import android.os.IBinder;
import android.os.PowerManager;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import android.widget.Toast;
public class MediaPlayerService extends Service implements OnCompletionListener, OnPreparedListener, OnErrorListener {
private static final int NOTIFICATION_ID = 1;
public static final String INTENT_URL = "url";
public enum MediaState {
Playing, Paused, Stopped
}
private MediaState mState = MediaState.Stopped;
private MediaPlayer mPlayer;
private NotificationManager mNotificationManager;
public String mCurrentUrl = "";
public static final String ACTION_TOGGLE_PLAYBACK = "com.cyberinsane.musicplayerlibrary.action.TOGGLE_PLAYBACK";
public static final String ACTION_PLAY = "com.cyberinsane.musicplayerlibrary.action.PLAY";
public static final String ACTION_PAUSE = "com.cyberinsane.musicplayerlibrary.action.PAUSE";
public static final String ACTION_STOP = "com.cyberinsane.musicplayerlibrary.action.STOP";
#Override
public void onCreate() {
super.onCreate();
mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null) {
String action = intent.getAction();
String url = intent.getExtras().getString(INTENT_URL);
if (url != null) {
if (!url.equals(mCurrentUrl)) {
mCurrentUrl = url;
mState = MediaState.Stopped;
relaxResources(true);
processPlayRequest();
} else {
if (action.equals(ACTION_TOGGLE_PLAYBACK)) {
processTogglePlaybackRequest();
} else if (action.equals(ACTION_PLAY)) {
processPlayRequest();
} else if (action.equals(ACTION_PAUSE)) {
processPauseRequest();
} else if (action.equals(ACTION_STOP)) {
processStopRequest(false);
}
}
}
}
return START_STICKY;
}
private void processTogglePlaybackRequest() {
if (mState == MediaState.Paused || mState == MediaState.Stopped) {
processPlayRequest();
} else {
processPauseRequest();
}
}
private void processPlayRequest() {
try {
if (mState == MediaState.Stopped) {
createMediaPlayerIfNeeded();
mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mPlayer.setDataSource(getApplicationContext(), Uri.parse(mCurrentUrl));
mPlayer.prepare();
} else if (mState == MediaState.Paused) {
mState = MediaState.Playing;
setUpAsForeground("Playing...");
if (!mPlayer.isPlaying()) {
mPlayer.start();
if (mIMediaPlayer != null) {
mIMediaPlayer.onAudioPlay();
}
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
private void processPauseRequest() {
if (mState == MediaState.Playing) {
mState = MediaState.Paused;
mPlayer.pause();
relaxResources(false);
if (mIMediaPlayer != null) {
mIMediaPlayer.onAudioPause();
}
}
}
private void processStopRequest(boolean force) {
if (mState == MediaState.Playing || mState == MediaState.Paused || force) {
mState = MediaState.Stopped;
relaxResources(true);
stopSelf();
}
}
private void createMediaPlayerIfNeeded() {
if (mPlayer == null) {
mPlayer = new MediaPlayer();
mPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
mPlayer.setOnPreparedListener(this);
mPlayer.setOnCompletionListener(this);
mPlayer.setOnErrorListener(this);
} else
mPlayer.reset();
}
private void relaxResources(boolean releaseMediaPlayer) {
stopForeground(true);
if (releaseMediaPlayer && mPlayer != null) {
mPlayer.reset();
mPlayer.release();
mPlayer = null;
}
}
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Toast.makeText(getApplicationContext(), "Media player error! Resetting.", Toast.LENGTH_SHORT).show();
Log.e("MusicPlayer", "Error: what=" + String.valueOf(what) + ", extra=" + String.valueOf(extra));
mState = MediaState.Stopped;
relaxResources(true);
if (mIMediaPlayer != null) {
mIMediaPlayer.onError();
}
return true; // true indicates we handled the error
}
#Override
public void onPrepared(MediaPlayer mp) {
mState = MediaState.Playing;
updateNotification("Playing...");
if (!mPlayer.isPlaying()) {
mPlayer.start();
if (mIMediaPlayer != null) {
mIMediaPlayer.onAudioPlay();
}
}
}
#Override
public void onCompletion(MediaPlayer mp) {
mState = MediaState.Stopped;
relaxResources(true);
stopSelf();
if (mIMediaPlayer != null) {
mIMediaPlayer.onAudioStop();
}
}
/**
* Updates the notification.
*/
private void updateNotification(String text) {
mNotificationManager.notify(NOTIFICATION_ID, buildNotification(text).build());
}
private void setUpAsForeground(String text) {
startForeground(NOTIFICATION_ID, buildNotification(text).build());
}
private NotificationCompat.Builder buildNotification(String text) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this.getApplicationContext());
builder.setSmallIcon(R.drawable.ic_launcher)
.setOngoing(true)
.setContentTitle("Cyberinsane MusicPlayer")
.setContentText(text)
.setContentIntent(
PendingIntent.getActivity(getApplicationContext(), 0, new Intent(getApplicationContext(),
MediaPlayerActivity.class), PendingIntent.FLAG_UPDATE_CURRENT))
.setContentInfo("Awesome");
return builder;
}
#Override
public void onDestroy() {
mState = MediaState.Stopped;
relaxResources(true);
}
public class LocalBinder extends Binder {
MediaPlayerService getService() {
return MediaPlayerService.this;
}
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
private final IBinder mBinder = new LocalBinder();
private IMediaPlayer mIMediaPlayer;
public MediaPlayer getMediaPlayer() {
return mPlayer;
}
public void setIMediaPlayer(IMediaPlayer mediaPlayer) {
mIMediaPlayer = mediaPlayer;
}
public MediaState getMediaState() {
return mState;
}
public boolean isPlaying() {
return (mState == MediaState.Playing);
}
public String getCurrentUrl() {
return mCurrentUrl;
}
public long duration() {
if (mPlayer != null) {
return mPlayer.getDuration();
}
return 0;
}
public long position() {
if (mPlayer != null) {
return mPlayer.getCurrentPosition();
}
return 0;
}
public void seekTo(long position) {
if (mPlayer != null) {
mPlayer.seekTo((int) position);
}
}
}
MediaPlayerActivity Class:
package com.cyberinsane.musicplayerlibrary;
import java.io.File;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
public class MediaPlayerActivity extends Activity implements IMediaPlayer {
private ImageButton mButtonPlay;
private EditText mEditTextUrl;
private SeekBar mSeekBarProgress;
private boolean mIsBound;
private String mExtStorePath;
private MediaPlayerService mMediaService;
private Handler mSeekHandler = new Handler();
private Runnable mSeekRunnable = new Runnable() {
#Override
public void run() {
seekStartUpdation();
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.media_player_activity);
mButtonPlay = (ImageButton) findViewById(R.id.buttonPlay);
mEditTextUrl = (EditText) findViewById(R.id.editTextURL);
mSeekBarProgress = (SeekBar) findViewById(R.id.seekBarMediaProgress);
mExtStorePath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator;
doBindService();
initListeners();
}
private void initListeners() {
mButtonPlay.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
String urlExt = mEditTextUrl.getText().toString();
if (urlExt != null && !urlExt.equals("")) {
String url = mExtStorePath + urlExt;
startService(new Intent(MediaPlayerService.ACTION_TOGGLE_PLAYBACK).putExtra(
MediaPlayerService.INTENT_URL, url));
}
}
});
mSeekBarProgress.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
mMediaService.seekTo(seekBar.getProgress());
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// empty
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
// empty
}
});
}
#Override
protected void onResume() {
super.onResume();
doBindService();
}
#Override
protected void onDestroy() {
super.onDestroy();
doUnbindService();
}
#Override
protected void onPause() {
super.onPause();
doUnbindService();
}
private ServiceConnection mConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName className, IBinder service) {
mMediaService = ((MediaPlayerService.LocalBinder) service).getService();
mMediaService.setIMediaPlayer(MediaPlayerActivity.this);
setControlState();
}
#Override
public void onServiceDisconnected(ComponentName className) {
mMediaService = null;
}
};
private void doBindService() {
bindService(new Intent(MediaPlayerActivity.this, MediaPlayerService.class), mConnection,
Context.BIND_AUTO_CREATE);
mIsBound = true;
}
private void doUnbindService() {
if (mIsBound) {
unbindService(mConnection);
mIsBound = false;
}
}
#Override
public void onAudioPlay() {
setPlayerState(true);
}
#Override
public void onAudioPause() {
setPlayerState(false);
}
#Override
public void onAudioStop() {
setPlayerState(false);
mSeekBarProgress.setProgress(0);
}
#Override
public void onError() {
// handle errors here
}
private void setControlState() {
if (mMediaService.isPlaying()) {
mEditTextUrl.setText(mMediaService.getCurrentUrl().replace(mExtStorePath, ""));
setPlayerState(true);
} else {
setPlayerState(false);
}
}
public void setPlayerState(boolean isPlaying) {
if (isPlaying) {
mButtonPlay.setImageResource(R.drawable.ic_pause);
mSeekBarProgress.setMax((int) mMediaService.duration());
seekStartUpdation();
} else {
mButtonPlay.setImageResource(R.drawable.ic_play);
seekStopUpdate();
}
}
public void seekStartUpdation() {
mSeekBarProgress.setProgress((int) mMediaService.position());
mSeekHandler.postDelayed(mSeekRunnable, 1000);
}
public void seekStopUpdate() {
mSeekHandler.removeCallbacks(mSeekRunnable);
}
}
Media Player Event Listener
package com.cyberinsane.musicplayerlibrary;
public interface IMediaPlayer {
public void onAudioPlay();
public void onAudioPause();
public void onAudioStop();
public void onError();
}
And finally my Manifest file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.cyberinsane.musicplayerlibrary"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.cyberinsane.musicplayerlibrary.MediaPlayerActivity"
android:label="#string/app_name"
android:launchMode="singleTask" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name="com.cyberinsane.musicplayerlibrary.MediaPlayerService"
android:exported="false" >
<intent-filter>
<action android:name="com.cyberinsane.musicplayerlibrary.action.TOGGLE_PLAYBACK" />
<action android:name="com.cyberinsane.musicplayerlibrary.action.PLAY" />
<action android:name="com.cyberinsane.musicplayerlibrary.action.PAUSE" />
<action android:name="com.cyberinsane.musicplayerlibrary.action.SKIP" />
<action android:name="com.cyberinsane.musicplayerlibrary.action.REWIND" />
<action android:name="com.cyberinsane.musicplayerlibrary.action.STOP" />
</intent-filter>
</service>
</application>
</manifest>
I want to integrate google+ sign in my android app. I have given permissions in android manifest file and also initialized plusclient object but when using sign in button I'm getting an error "Unfortunately application has stopped!".
Android manifest file is:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.abs"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="11" android:targetSdkVersion="18" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="android.permission.USE_CREDENTIALS"/>
<application
android:allowBackup="true"
android:icon="#drawable/abs_icon"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.abs.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.abs.Bank"
android:label="#string/title_activity_bank" >
</activity>
<activity
android:name="com.abs.Scheme"
android:label="#string/title_activity_scheme" >
</activity>
<activity
android:name="com.abs.Login"
android:label="#string/title_activity_login" >
</activity>
</application>
</manifest>
Mainactivity is:
package com.abs;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends Activity {
Button bank;
Button scheme;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bank = (Button) findViewById(R.id.button1);
scheme = (Button) findViewById(R.id.button2);
}
public void onClick_bank(View v){
Toast.makeText(MainActivity.this, "Searching by bank", Toast.LENGTH_SHORT).show();
Intent ibank = new Intent(v.getContext(),Bank.class);
startActivityForResult(ibank, 0);
}
public void onClick_scheme(View v){
Toast.makeText(MainActivity.this, "Searching by scheme", Toast.LENGTH_SHORT).show();
Intent ischeme = new Intent(v.getContext(),Scheme.class);
startActivityForResult(ischeme, 0);
}
public void onClick_login(View v){
Toast.makeText(MainActivity.this, "Please login with gmail id", Toast.LENGTH_SHORT).show();
Intent islog = new Intent(v.getContext(),Login.class);
startActivityForResult(islog, 0);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
Login activity for google+ sign in is given below and i have taken the code from google examples: for switching to login.class from mainactivity i had to comment onstart() because mplusclient.connect() is not working, Please help...
package com.abs;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.Scopes;
import com.google.android.gms.common.SignInButton;
import com.google.android.gms.plus.PlusClient;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.IntentSender;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
import android.widget.Toast;
public class Login extends Activity implements OnClickListener,
PlusClient.ConnectionCallbacks, PlusClient.OnConnectionFailedListener,
PlusClient.OnAccessRevokedListener {
private static final int DIALOG_GET_GOOGLE_PLAY_SERVICES = 1;
private static final int REQUEST_CODE_SIGN_IN = 1;
private static final int REQUEST_CODE_GET_GOOGLE_PLAY_SERVICES = 2;
private TextView mSignInStatus;
private PlusClient mPlusClient;
private SignInButton mSignInButton;
private View mSignOutButton;
private View mRevokeAccessButton;
private ConnectionResult mConnectionResult;
private ProgressDialog mConnectionProgressDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
mPlusClient = new PlusClient.Builder(Login.this, Login.this, Login.this)
.setActions("http://schemas.google.com/AddActivity", "http://schemas.google.com/BuyActivity")
.setScopes(Scopes.PLUS_LOGIN)
.build();
mConnectionProgressDialog = new ProgressDialog(this);
mConnectionProgressDialog.setMessage("Signing in...");
mSignInStatus = (TextView) findViewById(R.id.sign_in_status);
mSignInButton = (SignInButton) findViewById(R.id.sign_in_button);
mSignInButton.setOnClickListener(this);
mSignOutButton = findViewById(R.id.sign_out_button);
mSignOutButton.setOnClickListener(this);
mRevokeAccessButton = findViewById(R.id.revoke_access_button);
mRevokeAccessButton.setOnClickListener(this);
}
/*
#Override
public void onStart() {
super.onStart();
mPlusClient.connect();
}
#Override
public void onStop() {
mPlusClient.disconnect();
super.onStop();
}
*/
#SuppressWarnings("deprecation")
#Override
public void onClick(View view) {
switch(view.getId()) {
case R.id.sign_in_button:
if(!mPlusClient.isConnected()){
mPlusClient.connect();
}
//mPlusClient.connect();
/*
int available = GooglePlayServicesUtil.isGooglePlayServicesAvailable(Login.this);
if (available == ConnectionResult.SUCCESS) {
showDialog(DIALOG_GET_GOOGLE_PLAY_SERVICES);
return;
}
try {
mSignInStatus.setText("Signing in");
mConnectionResult.startResolutionForResult(Login.this, REQUEST_CODE_SIGN_IN);
}
catch (IntentSender.SendIntentException e) {
// Fetch a new result to start.
mPlusClient.connect();
}
*/
break;
case R.id.sign_out_button:
if (mPlusClient.isConnected()) {
mPlusClient.clearDefaultAccount();
mPlusClient.disconnect();
mPlusClient.connect();
}
else{Toast.makeText(Login.this, "You are not connected to internet", Toast.LENGTH_LONG).show();}
break;
case R.id.revoke_access_button:
if (mPlusClient.isConnected()) {
mPlusClient.revokeAccessAndDisconnect(this);
updateButtons(false /* isSignedIn */);
}
else{Toast.makeText(Login.this, "You are not connected to internet", Toast.LENGTH_LONG).show();}
break;
}
}
#Override
protected Dialog onCreateDialog(int id) {
if (id != DIALOG_GET_GOOGLE_PLAY_SERVICES) {
return super.onCreateDialog(id);
}
int available = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (available == ConnectionResult.SUCCESS) {
return null;
}
if (GooglePlayServicesUtil.isUserRecoverableError(available)) {
return GooglePlayServicesUtil.getErrorDialog(
available, Login.this, REQUEST_CODE_GET_GOOGLE_PLAY_SERVICES);
}
return new AlertDialog.Builder(this)
.setMessage("+ generic error")
.setCancelable(true)
.create();
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
Toast.makeText(Login.this, "activity result disabled", Toast.LENGTH_LONG).show();
if (requestCode == REQUEST_CODE_SIGN_IN
|| requestCode == REQUEST_CODE_GET_GOOGLE_PLAY_SERVICES) {
if (resultCode == RESULT_OK && !mPlusClient.isConnected()
&& !mPlusClient.isConnecting()) {
// This time, connect should succeed.
mPlusClient.connect();
}
}
}
#Override
public void onAccessRevoked(ConnectionResult status) {
Toast.makeText(Login.this, "Access revoke not available", Toast.LENGTH_LONG).show();
if (status.isSuccess()) {
mSignInStatus.setText("revoke access status");
} else {
mSignInStatus.setText("revoke access status error");
mPlusClient.disconnect();
}
mPlusClient.connect();
}
#Override
public void onConnected(Bundle connectionHint) {
Toast.makeText(Login.this, "Client is connected", Toast.LENGTH_LONG).show();
String currentPersonName = mPlusClient.getCurrentPerson() != null
? mPlusClient.getCurrentPerson().getDisplayName()
: "Signed in currentPersonName";
mSignInStatus.setText("signed in as you");
updateButtons(true );/* isSignedIn */
}
#Override
public void onDisconnected() {
Toast.makeText(Login.this, "Client is disconnected", Toast.LENGTH_LONG).show();
mSignInStatus.setText("Loading status");
mPlusClient.connect();
updateButtons(false );/* isSignedIn */
}
#Override
public void onConnectionFailed(ConnectionResult result) {
Toast.makeText(Login.this, "Connection failed", Toast.LENGTH_LONG).show();
mConnectionResult = result;
updateButtons(false );/* isSignedIn */
}
private void updateButtons(boolean isSignedIn) {
if (isSignedIn) {
mSignInButton.setVisibility(View.INVISIBLE);
mSignOutButton.setEnabled(true);
mRevokeAccessButton.setEnabled(true);
} else {
if (mConnectionResult == null) {
// Disable the sign-in button until onConnectionFailed is called with result.
mSignInButton.setVisibility(View.INVISIBLE);
mSignInStatus.setText("Loading status");
} else {
// Enable the sign-in button since a connection result is available.
mSignInButton.setVisibility(View.VISIBLE);
mSignInStatus.setText("Signed out");
}
mSignOutButton.setEnabled(false);
mRevokeAccessButton.setEnabled(false);
}
}
}
Thank you!!
I have been messing with the same code and finally got it running with some modifications.
According to me mPlusClient.connect(); must be called before click as it connects async and if used in the onclick it will give error.
here is my onclick() function
#Override
public void onClick(View arg0) {
int available = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (available != ConnectionResult.SUCCESS) {
showGoogleDialog();
return;
}
try {
mConnectionResult.startResolutionForResult(this, REQUEST_CODE_SIGN_IN);
} catch (IntentSender.SendIntentException e) {
mPlusClient.connect();
} catch (NullPointerException e1) {
PvrLog.d("null pointer exception");
}
}