Lock Screen Player Controls and Meta Data - java

I'm trying to use MediaSessionCompat in order to add lock screen player controls and meta data for my app. Everything I tried doesn't work. The lock screen doesn't show any controls or meta data while playing. Please see my current code below and any help is appreciated.
StreamService.java:
public class StreamService extends Service implements MediaPlayer.OnCuePointReceivedListener, MediaPlayer.OnStateChangedListener,
MediaPlayer.OnInfoListener, AudioManager.OnAudioFocusChangeListener {
private WifiManager.WifiLock wifiLock;
private static String LOG_TAG = "StreamService";
public static final String BROADCAST_PLAYER_STATE = "com.test.BROADCAST_PLAYER_STATE";
public static final String BROADCAST_PLAYER_META = "com.test.BROADCAST_PLAYER_META";
public static final String BROADCAST_PLAYER_ALBUM = "com.test.BROADCAST_PLAYER_ALBUM";
public static final int NOTIFICATION_ID = 999999;
private MediaSessionCompat mediaSession;
private boolean audioInterrupted = false;
public StreamService() {
}
#Override
public void onCreate(){
super.onCreate();
setupMediaPlayer();
setupMediaSession();
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public boolean onUnbind(Intent intent){
releasePlayer();
return false;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_NOT_STICKY;
}
private void setupMediaPlayer() {
// Recreate player
Bundle playerSettings = (BrandedApplication.getContext().getmTritonPlayer() == null) ? null : BrandedApplication.getContext().getmTritonPlayer().getSettings();
Bundle inputSettings = createPlayerSettings();
if (!Utility.bundleEquals(inputSettings, playerSettings)) {
releasePlayer();
createPlayer(inputSettings);
}
// Start the playback
play();
}
private void setupMediaSession() {
ComponentName receiver = new ComponentName(getPackageName(), RemoteReceiver.class.getName());
mediaSession = new MediaSessionCompat(this, "StreamService", receiver, null);
mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS |
MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
mediaSession.setPlaybackState(new PlaybackStateCompat.Builder()
.setState(PlaybackStateCompat.STATE_PAUSED, 0, 0)
.setActions(PlaybackStateCompat.ACTION_PLAY_PAUSE | PlaybackStateCompat.ACTION_PLAY | PlaybackStateCompat.ACTION_PAUSE)
.build());
mediaSession.setMetadata(new MediaMetadataCompat.Builder()
.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, "Test Artist")
.putString(MediaMetadataCompat.METADATA_KEY_ALBUM, "Test Album")
.putString(MediaMetadataCompat.METADATA_KEY_TITLE, "Test Track Name")
.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, 10000)
.putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART,
BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
//.putString(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE, "Test Artist")
.build());
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
audioManager.requestAudioFocus(new AudioManager.OnAudioFocusChangeListener() {
#Override
public void onAudioFocusChange(int focusChange) {
// Ignore
}
}, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
mediaSession.setActive(true);
}
synchronized private void play() {
audioInterrupted = false;
BrandedApplication.getContext().getmTritonPlayer().play();
if(wifiLock != null) {
wifiLock.acquire();
}
if(mediaSession != null) {
mediaSession.setPlaybackState(new PlaybackStateCompat.Builder()
.setState(PlaybackStateCompat.STATE_PLAYING, 0, 1.0f)
.setActions(PlaybackStateCompat.ACTION_PLAY_PAUSE).build());
}
}
synchronized private void stop() {
BrandedApplication.getContext().getmTritonPlayer().stop();
if(wifiLock != null) {
wifiLock.release();
}
if(mediaSession != null) {
mediaSession.setPlaybackState(new PlaybackStateCompat.Builder()
.setState(PlaybackStateCompat.STATE_PAUSED, 0, 0.0f)
.setActions(PlaybackStateCompat.ACTION_PLAY_PAUSE).build());
}
}
private void createPlayer(Bundle settings)
{
BrandedApplication.getContext().setmTritonPlayer(new TritonPlayer(this, settings));
wifiLock = ((WifiManager) getSystemService(Context.WIFI_SERVICE))
.createWifiLock(WifiManager.WIFI_MODE_FULL, "mylock");
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
int result = audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN);
BrandedApplication.getContext().getmTritonPlayer().setOnCuePointReceivedListener(this);
BrandedApplication.getContext().getmTritonPlayer().setOnInfoListener(this);
BrandedApplication.getContext().getmTritonPlayer().setOnStateChangedListener(this);
}
protected void releasePlayer() {
if (BrandedApplication.getContext().getmTritonPlayer() != null) {
if(BrandedApplication.getContext().isPlaying()) {
stop();
}
BrandedApplication.getContext().getmTritonPlayer().release();
BrandedApplication.getContext().setmTritonPlayer(null);
}
stopForeground(true);
}
protected Bundle createPlayerSettings() {
// Player Settings
Bundle settings = new Bundle();
// AAC
settings.putString(TritonPlayer.SETTINGS_STATION_MOUNT, getResources().getString(R.string.station_stream_mount) + "AAC");
// MP3
//settings.putString(TritonPlayer.SETTINGS_STATION_MOUNT, mountID);
settings.putString(TritonPlayer.SETTINGS_STATION_BROADCASTER, getResources().getString(R.string.app_name));
settings.putString(TritonPlayer.SETTINGS_STATION_NAME, getResources().getString(R.string.app_name));
return settings;
}
#Override
public void onCuePointReceived(MediaPlayer mediaPlayer, Bundle bundle) {
//System.out.println("TRITON PLAYER BUNDLE " + bundle);
String trackName = "";
String artistName = "";
if(bundle != null) {
if(bundle.containsKey("cue_title") && bundle.containsKey("track_artist_name")) {
if (!bundle.getString("cue_title").isEmpty()) {
trackName = bundle.getString("cue_title");
}
if (!bundle.getString("track_artist_name").isEmpty()) {
artistName = bundle.getString("track_artist_name");
}
}
}
// broadcast out the meta data
Intent i = new Intent(BROADCAST_PLAYER_META);
i.putExtra("trackName", trackName);
i.putExtra("artistName", artistName);
sendBroadcast(i);
// send notification and start as foreground service
PendingIntent pi = PendingIntent.getActivity(getApplicationContext(), 0, new Intent(getApplicationContext(), MainActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);
Bitmap icon = BitmapFactory.decodeResource(getResources(),
R.drawable.logo);
String tickerString = "";
String contentString = "Playing";
if(!artistName.isEmpty() && !trackName.isEmpty()) {
tickerString = artistName + " - " + trackName;
contentString += ": " + artistName + " - " + trackName;
}
Intent pauseIntent = new Intent(BROADCAST_PLAYER_PAUSE);
PendingIntent pausePendingIntent = PendingIntent.getBroadcast(this, 0, pauseIntent, 0);
NotificationCompat.Builder notification = new NotificationCompat.Builder(this)
.setContentTitle(getResources().getString(R.string.app_name))
.setTicker(tickerString)
.setContentText(contentString)
.setSmallIcon(R.drawable.ic_launcher)
//.setAutoCancel(true)
//.setLargeIcon(
// Bitmap.createScaledBitmap(icon, 128, 128, false))
.addAction(R.drawable.ic_media_pause, "Pause", pausePendingIntent)
.setContentIntent(pi)
.setStyle(new android.support.v7.app.NotificationCompat.MediaStyle()
//.setShowActionsInCompactView(0)
.setMediaSession(mediaSession.getSessionToken()))
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setOngoing(true);
//notification.setPriority(Notification.PRIORITY_MIN);
notification.setPriority(Notification.PRIORITY_DEFAULT);
startForeground(NOTIFICATION_ID, notification.build());
}
#Override
public void onInfo(MediaPlayer mediaPlayer, int i, int i1) {
}
#Override
public void onStateChanged(MediaPlayer mediaPlayer, int state) {
Log.i(LOG_TAG, "onStateChanged: " + TritonPlayer.debugStateToStr(state));
// broadcast out the player state
Intent i = new Intent(BROADCAST_PLAYER_STATE);
i.putExtra("state", state);
sendBroadcast(i);
}
#Override
public void onAudioFocusChange(int focusChange) {
switch (focusChange) {
case AudioManager.AUDIOFOCUS_GAIN:
// resume playback
System.out.println("AUDIO FOCUS GAIN");
if(audioInterrupted) {
audioInterrupted = false;
if (BrandedApplication.getContext().getmTritonPlayer() == null) {
setupMediaPlayer();
} else if (!BrandedApplication.getContext().isPlaying()) {
setupMediaPlayer();
}
}
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
case AudioManager.AUDIOFOCUS_LOSS:
System.out.println("AUDIO FOCUS LOSS");
// Lost focus for an unbounded amount of time: stop playback and release media player
if (BrandedApplication.getContext().isPlaying()) {
audioInterrupted = true;
releasePlayer();
}
break;
}
}
#Override
public void onDestroy() {
System.out.println("SERVICE STOPPED");
releasePlayer();
mediaSession.release();
}
}
And here's RemoteReceiver.java:
public class RemoteReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())) {
final KeyEvent event = intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
if (event != null && event.getAction() == KeyEvent.ACTION_DOWN) {
switch (event.getKeyCode()) {
case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
context.startService(new Intent(context, StreamService.class));
break;
}
}
}
}
}

Okay, from the additional information you provided, I believe I know what the issue is. In Android 5.0 Lock Screen Controls were removed. They are now implemented via the Notification API. So try adding the following to your notification builder.
notification.setStyle(new NotificationCompat.MediaStyle()
.setShowActionsInCompactView(0)
.setMediaSession(mediaSession));
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
That should place it on your lock screen. I would also suggest changing the Notification.PRIORITY_DEFAULT as well as include an action to your notification otherwise you won't be able to control the playback.

I know this post is late but if anyone is still facing the issue.This will show up in your lock screen also.
Here is the code for notification builder class-
import android.annotation.SuppressLint;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.media.MediaPlayer;
import android.media.session.MediaSessionManager;
import android.os.Build;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.annotation.RequiresApi;
import android.support.v4.app.NotificationCompat;
import android.support.v4.media.session.MediaControllerCompat;
import android.support.v4.media.session.MediaSessionCompat;
import android.util.Log;
import org.json.JSONException;
public class MediaPlayerService extends Service {
private static final String CHANNEL_ID = "my_channel_01";
public static final String ACTION_PLAY = "action_play";
public static final String ACTION_PAUSE = "action_pause";
public static final String ACTION_NEXT = "action_next";
public static final String ACTION_PREVIOUS = "action_previous";
public static final String ACTION_STOP = "action_stop";
public static final String ACTION_NOTHING = "action_previous";
private NotificationManager notificationManager;
NotificationManager mNotificationManager;
private MediaPlayer mMediaPlayer;
private MediaSessionManager mManager;
private MediaSessionCompat mSession;
private MediaControllerCompat mController;
private MediaPlayerService mService;
String title = null;
String description = null;
#Override
public IBinder onBind(Intent intent) {
return null;
}
private void handleIntent(Intent intent) {
if (intent == null || intent.getAction() == null)
return;
String action = intent.getAction();
if (action.equalsIgnoreCase(ACTION_PLAY)) {
mController.getTransportControls().play();
} else if (action.equalsIgnoreCase(ACTION_PAUSE)) {
mController.getTransportControls().pause();
} else if (action.equalsIgnoreCase(ACTION_PREVIOUS)) {
mController.getTransportControls().skipToPrevious();
} else if (action.equalsIgnoreCase(ACTION_NEXT)) {
mController.getTransportControls().skipToNext();
} else if (action.equalsIgnoreCase(ACTION_STOP)) {
mController.getTransportControls().stop();
}
}
private NotificationCompat.Action generateAction(int icon, String title, String intentAction) {
Intent intent = new Intent(getApplicationContext(), MediaPlayerService.class);
intent.setAction(intentAction);
PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(), 1, intent, 0);
return new NotificationCompat.Action.Builder(icon, title, pendingIntent).build();
}
#SuppressLint("ServiceCast")
private void buildNotification(NotificationCompat.Action action) {
title = ""; // add variable to get current playing song title here
description =""; // add variable to get current playing song description here
Intent notificationIntent = new Intent(getApplicationContext(), HomeActivity.class); //specify which activity should be opened when widget is clicked (other than buttons)
PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, notificationIntent, 0);
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// Notification channels are only supported on Android O+.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
//method to create channel if android version is android. Descrition below
createNotificationChannel();
}
Intent intent = new Intent(getApplicationContext(), MediaPlayerService.class);
intent.setAction(ACTION_STOP);
PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(), 1, intent, 0);
final NotificationCompat.Builder builder;
//condition to check if music is playing
//if music is playing widget cant be dismissed on swipe
if(<add your method to check play status here>)
{
builder = new NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.logo2b)
.setLargeIcon(BitmapFactory.decodeResource(getApplication().getResources(), R.mipmap.ic_launcher))
.setContentTitle(title)
.setContentText(description)
.setDeleteIntent(pendingIntent)
.setContentIntent(contentIntent)
.setChannelId(CHANNEL_ID)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setOnlyAlertOnce(true)
.setColor(getResources().getColor(R.color.colorPrimary))
.setOngoing(true) //set this to true if music is playing widget cant be dismissed on swipe
.setStyle(new android.support.v4.media.app.NotificationCompat.MediaStyle()
// show only play/pause in compact view
.setShowActionsInCompactView(0, 1, 2));
}
//else if music is not playing widget can be dismissed on swipe
else
{
builder = new NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.logo2b)
.setLargeIcon(BitmapFactory.decodeResource(getApplication().getResources(), R.mipmap.ic_launcher))
.setContentTitle(title)
.setContentText(description)
.setDeleteIntent(pendingIntent)
.setContentIntent(contentIntent)
.setChannelId(CHANNEL_ID)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setOnlyAlertOnce(true)
.setColor(getResources().getColor(R.color.colorPrimary))
.setStyle(new android.support.v4.media.app.NotificationCompat.MediaStyle()
// show only play/pause in compact view
.setShowActionsInCompactView(0, 1, 2));
}
builder.addAction(generateAction(R.drawable.ic_skip_previous_white_24dp, "Previous", ACTION_PREVIOUS));
builder.addAction(action);
builder.addAction(generateAction(R.drawable.ic_skip_next_white_24dp, "Next", ACTION_NEXT));
//style.setShowActionsInCompactView(0,1,2);
// builder.setColor(getResources().getColor(R.color.app_orange_color));
notificationManager.notify(1, builder.build());
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (mManager == null) {
try {
initMediaSessions();
} catch (RemoteException e) {
e.printStackTrace();
}
}
handleIntent(intent);
return super.onStartCommand(intent, flags, startId);
}
private void initMediaSessions() throws RemoteException {
mMediaPlayer = new MediaPlayer();
mSession = new MediaSessionCompat(getApplicationContext(), "simple player session");
mController = new MediaControllerCompat(getApplicationContext(), mSession.getSessionToken());
mSession.setCallback(new MediaSessionCompat.Callback() {
#Override
public void onPlay() {
super.onPlay();
//add you code for play button click here
//replace your drawable id that shows pauseicon buildNotification(generateAction(R.drawable.uamp_ic_pause_white_24dp, "Pause", ACTION_PAUSE));
}
#Override
public void onPause() {
super.onPause();
//add you code for pause button click here
//replace your drawable id that shows play icon buildNotification(generateAction(R.drawable.uamp_ic_play_arrow_white_24dp, "Play", ACTION_PLAY));
}
#Override
public void onSkipToNext() {
super.onSkipToNext();
//add you code for next button click here
buildNotification(generateAction(R.drawable.uamp_ic_pause_white_24dp, "Pause", ACTION_PAUSE));
}
#Override
public void onSkipToPrevious() {
super.onSkipToPrevious();
//add you code for previous button click here
buildNotification(generateAction(R.drawable.uamp_ic_pause_white_24dp, "Pause", ACTION_PAUSE));
}
#Override
public void onStop() {
super.onStop();
Log.e("MediaPlayerService", "onStop");
//Stop media player and dismiss widget here
NotificationManager notificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancel(1);
Intent intent = new Intent(getApplicationContext(), MediaPlayerService.class);
stopService(intent);
}
#Override
public void onSeekTo(long pos) {
super.onSeekTo(pos);
}
}
);
}
#Override
public boolean onUnbind(Intent intent) {
mSession.release();
return super.onUnbind(intent);
}
//method to create notification channel on android Oreo and above
#RequiresApi(Build.VERSION_CODES.O)
private void createNotificationChannel() {
int notifyID = 1;
CharSequence name = "Player Widget";// The user-visible name of the channel. This channel name will be shown in settings.
if (notificationManager.getNotificationChannel(CHANNEL_ID) == null) {
NotificationChannel notificationChannel =
new NotificationChannel(CHANNEL_ID, name, NotificationManager.IMPORTANCE_LOW);
notificationManager.createNotificationChannel(notificationChannel);
}
}
}
And fire these intents for actions to update widget when play status is changed from within the app:
Play-
//to change widgets current action button to play
Intent intent = new Intent(getApplicationContext(), MediaPlayerService.class);
intent.setAction(MediaPlayerService.ACTION_PAUSE);
startService(intent);
Pause-
//to change widgets current action button to pause
Intent intent = new Intent(getApplicationContext(), MediaPlayerService.class);
intent.setAction(MediaPlayerService.ACTION_PLAY);
startService(intent);
Excuse me if there are any unwanted import.All the best.

Related

Android Java start service from fragment

i am facing issue to start a service from fragment on a button click.
below is overview of Service class
public class FtpServiceDownload1 extends Service {
IBinder mBinder = new LocalBinder();
static String LOG_TAG = "Background Service 001";
private Handler customHandler = new Handler();
private Handler checkServiceHandler = new Handler();
long timeInMilliseconds = 0L;
long timeSwapBuff = 0L;
long updatedTime = 0L;
private long startTime = 0L;
public boolean isFtpConnected(){
if(ftpHelperObj!=null){
return ftpHelperObj.ftp.isConnected();
}
return false;
}
public FtpHelperObject ftpHelperObj;
//#Nullable
#Override
public IBinder onBind(Intent intent) {
Log.e(LOG_TAG,"binded called");
return mBinder;
}
public class LocalBinder extends Binder {
public FtpServiceDownload1 getServerInstance() {
return FtpServiceDownload1.this;
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//TO DO WORK
return(START_NOT_STICKY);
}
String NOTIFICATION_CHANNEL_ID = "com.form.lasertrac.ftpquery";
String channelName = "My Background Service";
static Notification notification = null;
static NotificationChannel notificationChannel = null;
static NotificationManager notificationManager = null;
static NotificationCompat.Builder notificationBuilder = null;
int id = 1;
private void startMyOwnForeground(){
notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_NONE);
notificationChannel.setLightColor(Color.BLUE);
notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
assert notificationManager != null;
notificationManager.createNotificationChannel(notificationChannel);
notificationBuilder = new NotificationCompat.Builder(getApplicationContext(), NOTIFICATION_CHANNEL_ID);
notification = notificationBuilder.setOngoing(true)
.setSmallIcon(R.mipmap.ic_launcher_lasertrac)
.setContentTitle("FTP Query in background.")
.setPriority(NotificationManager.IMPORTANCE_MIN)
.setCategory(Notification.CATEGORY_SERVICE)
.build();
startForeground(id, notification);
}
void notifyNotification(String msg){
notificationBuilder.setContentText("FTP Check "+msg);
notificationBuilder.setContentTitle("FTP Check Service ");
Date d = Calendar.getInstance().getTime();
notificationBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(FunctionsHelper.onlyForTimeFormatterView.format(d)+" "+msg));
Notification notification = notificationBuilder.getNotification();
notification.flags = Notification.FLAG_ONGOING_EVENT;
notificationManager.notify(id, notification);
}
}
and below code in my fragment to start service
btn_service_load_data.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent mIntent2 = new Intent(getContext(), FtpServiceDownload1.class);
getContext().bindService(mIntent2, mConnectionFtpQuery, getContext().BIND_AUTO_CREATE);
getContext().startService(mIntent2);
}
});
FtpServiceDownload1 mServiceFtpQueryService ;
boolean mBoundedFtpQuery ;
ServiceConnection mConnectionFtpQuery = new ServiceConnection() {
#Override
public void onServiceDisconnected(ComponentName name) {
Toast.makeText(getContext(), "Ftp Query Service is disconnected", Toast.LENGTH_LONG).show();
mBoundedFtpQuery = false;
mServiceFtpQueryService = null;
}
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
Toast.makeText(getContext(), "Ftp Query service started", Toast.LENGTH_LONG).show();
mBoundedFtpQuery = true;
FtpServiceDownload1.LocalBinder mLocalBinder = (FtpServiceDownload1.LocalBinder) service;
mServiceFtpQueryService = mLocalBinder.getServerInstance();
}
};
my purpose is to start some service for particular work and stop it after work done.
when i click to start service, my application hangs and doesn't respond, if i call this service from my MainActivity class like below, it works
#Override
protected void onStart() {
super.onStart();
Intent mIntent2 = new Intent(this, FtpServiceDownload1.class);
bindService(mIntent2, mConnectionFtpQuery, BIND_AUTO_CREATE);
startService(mIntent2);
}

android service always running and notify user when needed

I need a service to make a notification whenever the user is in a moving car.
I use ActivityRecognition to find out when the user is in a car.the issue is I need my service to run even when the app is destroyed or removed by the user.
I tried running the service on a different process but after a few minutes the service stops working.I also tried using foreground service but I had the same issue with that to.
this is my service class.
public class SpeedCheckerService extends Service {
private final String CHANNEL_ID = "my_channel";
private static SpeedCheckerService speedCheckerService;
private ActivityRecognitionClient mActivityRecognitionClient;
private boolean started = false;
Date lastNotification;
CountDownTimer countDownTimer;
Intent intent;
#Override
public void onCreate() {
createNotificationChannel();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(final Intent intent, int flags, int startId) {
this.intent=intent;
countDownTimer = new CountDownTimer(99999999,1000 * 60 * 1) {
#Override
public void onTick(long l) {
recognizeActivity();
}
#Override
public void onFinish() {
countDownTimer.start();
}
}.start();
return START_STICKY;
}
String detectedActivitiesToJson(ArrayList<DetectedActivity> detectedActivitiesList) {
Type type = new TypeToken<ArrayList<DetectedActivity>>() {}.getType();
System.out.println(detectedActivitiesList.toString());
if ((detectedActivitiesList.size()>=1)&&(detectedActivitiesList.get(0).getType() == DetectedActivity.STILL) && (detectedActivitiesList.get(0).getConfidence()) >= 60){
if(lastNotification!=null){
Calendar calendar = Calendar.getInstance();
calendar.setTime(lastNotification);
calendar.add(Calendar.MINUTE,5);
Date newDate = calendar.getTime();
calendar.clear();
System.out.println(lastNotification.toString());
System.out.println(newDate.toString());
if(newDate.after(calendar.getTime()) == true)
return null;
}
speedCheckerService.makeNotification();
lastNotification = Calendar.getInstance().getTime();
}
return new Gson().toJson(detectedActivitiesList, type);
}
public void makeNotification() {
createNotificationChannel();
Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("title")
.setContentText("text")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setContentIntent(pendingIntent)
.setSmallIcon(R.drawable.mapbox_logo_icon)
.setColor(Color.parseColor("#00ff00"))
.setAutoCancel(true);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(70, builder.build());
}
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = "guardian";
String description = "alerting user";
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
channel.setDescription(description);
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
}
public void recognizeActivity() {
if((mActivityRecognitionClient==null)&&(!started))
{
mActivityRecognitionClient = new ActivityRecognitionClient(this);
mActivityRecognitionClient.requestActivityUpdates(0, PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
started = true;
}
speedCheckerService =this;
if(ActivityRecognitionResult.hasResult(intent))
{
ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(intent);
ArrayList<DetectedActivity> detectedActivities = (ArrayList) result.getProbableActivities();
detectedActivitiesToJson(detectedActivities);
}
}
}
I would greatly appreciate if you can help me with my problem
Use foreground service instead of normal service and do the below changes
public class SampleService extends Service {
private NotificationManager mNotificationManager;
/**
* The identifier for the notification displayed for the foreground service.
*/
private static final int NOTIFICATION_ID = 1231234;
static void startService(Context context, String message) {
Intent startIntent = new Intent(context, SampleService.class);
startIntent.putExtra("inputExtra", message);
ContextCompat.startForegroundService(context, startIntent);
}
static void stopService(Context context) {
Intent stopIntent = new Intent(context, SampleService.class);
context.stopService(stopIntent);
}
private void createNotificationChannel() {
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
CharSequence name = "Sample Notification";
// Create the channel for the notification
NotificationChannel mChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, name,
NotificationManager.IMPORTANCE_DEFAULT);
mChannel.setSound(null, null);
// Set the Notification Channel for the Notification Manager.
notificationManager.createNotificationChannel(mChannel);
}
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
Log.d("Service", "onCreate");
createNotificationChannel();
mNotificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("Service", "onStartCommand");
startForeground(NOTIFICATION_ID, getNotification(message);
**// This is important, When your service got killed it will try to restart //the service. But some android vendor phones are restricted this autostart**
return START_REDELIVER_INTENT;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d("Service", "Service Destroyed");
}
#Override
public void onTaskRemoved(Intent rootIntent) {
Log.e("Service", "onTaskRemoved");
super.onTaskRemoved(rootIntent);
}
private Notification getNotification(String contentMessage) {
String title = getString(R.string.notification_title,
DateFormat.getDateTimeInstance().format(new Date()));
NotificationCompat.Builder builder = new NotificationCompat.Builder(this,
NOTIFICATION_CHANNEL_ID).setContentTitle(title).setContentText(contentMessage)
.setSmallIcon(R.drawable.notification)
.setOngoing(true)
.setPriority(Notification.PRIORITY_MAX)
.setTicker(contentMessage)
.setAutoCancel(false)
.setWhen(System.currentTimeMillis());
return builder.build();
}
/**
* Returns true if this is a foreground service.
*
* #param context The {#link Context}.
*/
public boolean serviceIsRunningInForeground(Context context) {
ActivityManager manager = (ActivityManager) context.getSystemService(
Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(
Integer.MAX_VALUE)) {
if (getClass().getName().equals(service.service.getClassName())){
if (service.foreground){
return true;
}
}
}
return false;
}
}
You should use Foreground Service if you want service running even your app is in background or closed
https://androidwave.com/foreground-service-android-example/

AudioPlaybackCapture (Android 10) not working and recording empty sounds

I tried to use new AudioPlaybackCapture method to record some media in an android 10 device. But unfortunately my code which uses this API does not seem to be working well.
Here I used an activity which starts a separate service for media recording. That service is registered to a broadcast receiver to start and stop recordings. And the broadcast intents are fired using my main activity via button clicks (start, stop)
No exceptions are printed. Also the file is created at the desired location. But with no content (0bytes). All the required manifest and runtime permissions are given. What i'm doing wrong here.
Here is my service
public class MediaCaptureService extends Service {
public static final String ACTION_ALL = "ALL";
public static final String ACTION_START = "ACTION_START";
public static final String ACTION_STOP = "ACTION_STOP";
public static final String EXTRA_RESULT_CODE = "EXTRA_RESULT_CODE";
public static final String EXTRA_ACTION_NAME = "ACTION_NAME";
private static final int RECORDER_SAMPLERATE = 8000;
private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_MONO;
private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;
NotificationCompat.Builder _notificationBuilder;
NotificationManager _notificationManager;
private String NOTIFICATION_CHANNEL_ID = "ChannelId";
private String NOTIFICATION_CHANNEL_NAME = "Channel";
private String NOTIFICATION_CHANNEL_DESC = "ChannelDescription";
private int NOTIFICATION_ID = 1000;
private static final String ONGING_NOTIFICATION_TICKER = "RecorderApp";
int BufferElements2Rec = 1024; // want to play 2048 (2K) since 2 bytes we use only 1024
int BytesPerElement = 2; // 2 bytes in 16bit format
AudioRecord _recorder;
private boolean isRecording = false;
private MediaProjectionManager _mediaProjectionManager;
private MediaProjection _mediaProjection;
Intent _callingIntent;
public MediaCaptureService() {
}
#Override
public void onCreate() {
super.onCreate();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//Call Start foreground with notification
Intent notificationIntent = new Intent(this, MediaCaptureService.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
_notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_foreground))
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentTitle("Starting Service")
.setContentText("Starting monitoring service")
.setTicker(ONGING_NOTIFICATION_TICKER)
.setContentIntent(pendingIntent);
Notification notification = _notificationBuilder.build();
NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, NOTIFICATION_CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);
channel.setDescription(NOTIFICATION_CHANNEL_DESC);
_notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
_notificationManager.createNotificationChannel(channel);
startForeground(NOTIFICATION_ID, notification);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
_mediaProjectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);
}
}
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
_callingIntent = intent;
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_ALL);
registerReceiver(_actionReceiver, filter);
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void startRecording(Intent intent) {
//final int resultCode = intent.getIntExtra(EXTRA_RESULT_CODE, 0);
_mediaProjection = _mediaProjectionManager.getMediaProjection(-1, intent);
startRecording(_mediaProjection);
}
#TargetApi(29)
private void startRecording(MediaProjection mediaProjection ) {
AudioPlaybackCaptureConfiguration config =
new AudioPlaybackCaptureConfiguration.Builder(mediaProjection)
.addMatchingUsage(AudioAttributes.USAGE_MEDIA)
.build();
AudioFormat audioFormat = new AudioFormat.Builder()
.setEncoding(RECORDER_AUDIO_ENCODING)
.setSampleRate(RECORDER_SAMPLERATE)
.setChannelMask(RECORDER_CHANNELS)
.build();
_recorder = new AudioRecord.Builder()
// .setAudioSource(MediaRecorder.AudioSource.MIC)
.setAudioFormat(audioFormat)
.setBufferSizeInBytes(BufferElements2Rec * BytesPerElement)
.setAudioPlaybackCaptureConfig(config)
.build();
_recorder.startRecording();
writeAudioDataToFile();
}
private byte[] short2byte(short[] sData) {
int shortArrsize = sData.length;
byte[] bytes = new byte[shortArrsize * 2];
for (int i = 0; i < shortArrsize; i++) {
bytes[i * 2] = (byte) (sData[i] & 0x00FF);
bytes[(i * 2) + 1] = (byte) (sData[i] >> 8);
sData[i] = 0;
}
return bytes;
}
private void writeAudioDataToFile() {
// Write the output audio in byte
Log.i(MainActivity.LOG_PREFIX, "Recording started. Computing output file name");
File sampleDir = new File(getExternalFilesDir(null), "/TestRecordingDasa1");
if (!sampleDir.exists()) {
sampleDir.mkdirs();
}
String fileName = "Record-" + new SimpleDateFormat("dd-MM-yyyy-hh-mm-ss").format(new Date()) + ".pcm";
String filePath = sampleDir.getAbsolutePath() + "/" + fileName;
//String filePath = "/sdcard/voice8K16bitmono.pcm";
short sData[] = new short[BufferElements2Rec];
FileOutputStream os = null;
try {
os = new FileOutputStream(filePath);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
while (isRecording) {
// gets the voice output from microphone to byte format
_recorder.read(sData, 0, BufferElements2Rec);
System.out.println("Short wirting to file" + sData.toString());
try {
// // writes the data to file from buffer
// // stores the voice buffer
byte bData[] = short2byte(sData);
os.write(bData, 0, BufferElements2Rec * BytesPerElement);
} catch (IOException e) {
e.printStackTrace();
}
}
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
Log.i(MainActivity.LOG_PREFIX, String.format("Recording finished. File saved to '%s'", filePath));
}
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void stopRecording() {
// stops the recording activity
if (null != _recorder) {
isRecording = false;
_recorder.stop();
_recorder.release();
_recorder = null;
}
_mediaProjection.stop();
stopSelf();
}
#Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(_actionReceiver);
}
BroadcastReceiver _actionReceiver = new BroadcastReceiver() {
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equalsIgnoreCase(ACTION_ALL)) {
String actionName = intent.getStringExtra(EXTRA_ACTION_NAME);
if (actionName != null && !actionName.isEmpty()) {
if (actionName.equalsIgnoreCase(ACTION_START)) {
startRecording(_callingIntent);
} else if (actionName.equalsIgnoreCase(ACTION_STOP)){
stopRecording();
}
}
}
}
};
And here is an extract from the main activity where the service and start / stop actions are started.
public class MainActivity extends AppCompatActivity {
public static final String LOG_PREFIX = "CALL_FUNCTION_TEST";
private static final int ALL_PERMISSIONS_PERMISSION_CODE = 1000;
private static final int CREATE_SCREEN_CAPTURE = 1001;
Button _btnInitCapture;
Button _btnStartCapture;
Button _btnStopCapture;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
_btnGetOkPermissions = findViewById(R.id.btnGetOkPermissions);
_btnGetOkPermissions.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
checkOkPermissions();
}
});
_btnInitCapture = findViewById(R.id.btnInitCapture);
_btnInitCapture.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
initAudioCapture();
}
});
_btnStartCapture = findViewById(R.id.btnStartCapture);
_btnStartCapture.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startRecording();
}
});
_btnStopCapture = findViewById(R.id.btnStopAudioCapture);
_btnStopCapture.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
stopRecording();
}
});
}
...
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void initAudioCapture() {
_manager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);
Intent intent = _manager.createScreenCaptureIntent();
startActivityForResult(intent, CREATE_SCREEN_CAPTURE);
}
private void stopRecording() {
Intent broadCastIntent = new Intent();
broadCastIntent.setAction(MediaCaptureService.ACTION_ALL);
broadCastIntent.putExtra(MediaCaptureService.EXTRA_ACTION_NAME, MediaCaptureService.ACTION_STOP);
this.sendBroadcast(broadCastIntent);
}
private void startRecording() {
Intent broadCastIntent = new Intent();
broadCastIntent.setAction(MediaCaptureService.ACTION_ALL);
broadCastIntent.putExtra(MediaCaptureService.EXTRA_ACTION_NAME, MediaCaptureService.ACTION_START);
this.sendBroadcast(broadCastIntent);
}
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
if (CREATE_SCREEN_CAPTURE == requestCode) {
if (resultCode == RESULT_OK) {
Intent i = new Intent(this, MediaCaptureService.class);
i.setAction(MediaCaptureService.ACTION_START);
i.putExtra(MediaCaptureService.EXTRA_RESULT_CODE, resultCode);
i.putExtras(intent);
this.startService(i);
} else {
// user did not grant permissions
}
}
}
}
Well, nothing sets isRecording true. Also, you're doing your recording in a blocking method, but you're on the UI thread, which ought to cause your interface to freeze as soon as you start recording.

CountDownTimer Service crashing when it is opened

I am trying to make a countdown timer screen that will keep counting down if I back out of the app or change screens or something. For some reason it keeps crashing saying that timeLeft is null. I can't figure out why it would be because I know the time variable in my Countdown class is there. Thanks for any help!
Countdown Activity
public class Countdown extends Activity {
public static String time;
public static String address;
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_countdown);
Intent confIntent = getIntent();
time = confIntent.getStringExtra("time");
address = confIntent.getStringExtra("address");
LocalBroadcastManager.getInstance(this).registerReceiver(
new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
TextView textView= findViewById(R.id.t1);
String timeLeftString = intent.getStringExtra("timeSent");
int timeLeft = Integer.parseInt(timeLeftString);
if(timeLeft>0) {
textView.setText("You have " + timeLeft + " minutes left");
}
else{
textView.setText("Y'all outta time, see ya again soon!");
killIt();
}
}
}, new IntentFilter(CountdownService.ACTION_LOCATION_BROADCAST)
);
Intent toService = new Intent(this, CountdownService.class);
startService(toService);
}
#Override
protected void onResume() {
super.onResume();
TextView textView= findViewById(R.id.t1);
textView.setText("You have " + CountdownService.toSend + " minutes left");
}
#Override
protected void onPause() {
super.onPause();
}
public void killIt(){
stopService(new Intent(this, CountdownService.class));
}
}
Countdown Service
public class CountdownService extends Service{
public static int toSend=0;
public int time;
public static final String
ACTION_LOCATION_BROADCAST = CountdownService.class.getName() +
"LocationBroadcast";
public final String timeFromCD = Countdown.time;
public final String address = Countdown.address;
#Override
public void onCreate() {
super.onCreate();
time = Integer.parseInt(timeFromCD);
time = time*60000;
new CountDownTimer(time, 5000) {
public void onTick(long millisUntilFinished) {
int timeLeftInt = (int) Math.ceil((double) millisUntilFinished / 60000); //Whole number of minutes left, ceiling
sendBroadcastMessage(timeLeftInt);
toSend = timeLeftInt;
if(timeLeftInt == 5){
Notify("Not Done");
}
}
public void onFinish() {
sendBroadcastMessage(0);
Notify("done");
Response.Listener<String> response = new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
//creating a jsonResponse that will receive the php json
JSONObject jsonResponse = new JSONObject(response);
boolean success = jsonResponse.getBoolean("success");
if (success) {
} else {
AlertDialog.Builder builder = new AlertDialog.Builder(CountdownService.this);
builder.setMessage("Login Failed")
.setNegativeButton("Retry", null)
.create()
.show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
};
SpotAmountRequest spotAmountRequest = new SpotAmountRequest(address, "0", response);
RequestQueue queue = Volley.newRequestQueue(CountdownService.this);
queue.add(spotAmountRequest);
}
}.start();
}
private void sendBroadcastMessage(int timeSent) {
Intent intent = new Intent(ACTION_LOCATION_BROADCAST);
intent.putExtra("timeSent", timeSent);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
private void Notify(String doneness){
NotificationManager notificationManager = (NotificationManager)
getSystemService(NOTIFICATION_SERVICE);
Intent intent = new Intent(this, Map.class);
PendingIntent pIntent = PendingIntent.getActivity(this, (int) System.currentTimeMillis(), intent, 0);
if(doneness.equals("done")) {
Notification n = new Notification.Builder(this)
.setContentTitle("Time to leave!")
.setContentText("Your PrePark spot has expired, time to go home!")
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(pIntent)
.setAutoCancel(true)
.build();
notificationManager.notify(0, n);
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
// Vibrate for 500 milliseconds
v.vibrate(1000);
}
else{
Notification n = new Notification.Builder(this)
.setContentTitle("Ya got 5 minutes left in your PrePark spot!")
.setContentText("Better get going soon here")
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(pIntent)
.setAutoCancel(true)
.build();
notificationManager.notify(0, n);
}
}
}
You're storing an int value in the intent that you're broadcasting from the service, but you're then trying to get it out as a String where you receive the broadcast. Either change the receiver to use getIntExtra instead of getStringExtra, or convert the int to a String in the service before storing it in the intent.

how to save or prevent my background service from the force stop or clear task from user

Hello friends i am creating one android app App lock application in which user can lock the application for that i am using one background service which run in background always. My service is run fine in all device but in some new device like OPPO,Redme Mi and Lenovo Mobile there is one advace feature like user can clean all the running task from the cleaner and because of this advance features when user clean all the task my service also stop and app lock will not work so user need to go in application and manual start the service is there any solution to protect my service from this.
one of app lock have this kind of solution
https://play.google.com/store/apps/details?id=com.domobile.applock
This app service is start after the clean task i also want to do same for my application i tried many solution but not getting any result i my service code is as below
public class MyAppLockService extends Service {
public static int BuildV = 0;
public static final int NOTIFICATION_ID = 11259186;
private static boolean flag;
public static boolean isLauncher;
public static boolean isRunning;
public static ArrayList<String> locked_list;
public static String pack;
public static Thread th;
String currentHomePackage;
private boolean isRefreshedList;
boolean mAllowDestroy;
BroadcastReceiver mReciever;
private boolean mShowNotification;
UsageStatsManager mUsageStatsManager;
ActivityManager manager;
PowerManager pmanager;
SharedPreferences prefs;
public boolean run;
Timer f6t;
TimerTask tt;
class C02221 extends BroadcastReceiver {
C02221() {
}
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Utils.ACTION_UPDATE)) {
MyAppLockService.this.refreshList();
} else if (intent.getAction().equals(Utils.ACTION_STOP_SELF)) {
MyAppLockService.this.doStopSelf();
} else if (intent.getAction().equals(Utils.ACTION_REMOVE_APP)) {
MyAppLockService.this.removeAppFromLockedList(intent
.getStringExtra("packName"));
}
}
}
#SuppressLint("NewApi")
class C02232 extends TimerTask {
C02232() {
}
#SuppressLint("NewApi")
public void run() {
if (Utils.isScreenOn(MyAppLockService.this.pmanager)) {
MyAppLockService.this.isRefreshedList = false;
String current = "";
try {
current = Utils.getProcess(
MyAppLockService.this.mUsageStatsManager,
MyAppLockService.this.getApplicationContext());
} catch (Exception e) {
current = "";
}
if (current != null) {
if (MyAppLockService.flag
&& current
.equals(MyAppLockService.this.currentHomePackage)) {
if (MyAppLockService.this.prefs.getBoolean(
"immediately", true)) {
MyAppLockService.locked_list = new DBHelper(
MyAppLockService.this
.getApplicationContext())
.getApsHasStateTrue();
}
MyAppLockService.flag = false;
}
if (!current
.equals(MyAppLockService.this.currentHomePackage)
&& MyAppLockService.locked_list.contains(current)) {
Intent it;
if (MyAppLockService.BuildV >= 23) {
long endTime = System.currentTimeMillis();
UsageEvents usageEvents = MyAppLockService.this.mUsageStatsManager
.queryEvents(endTime - 10000, endTime);
Event event = new Event();
while (usageEvents.hasNextEvent()) {
usageEvents.getNextEvent(event);
}
if (current.equals(event.getPackageName())
&& event.getEventType() == 1) {
MyAppLockService.pack = current;
if (MyAppLockService.this.prefs.getBoolean(
"isPattern", false)) {
MyAppLockService.this
.confirmPattern(current);
} else {
it = new Intent(
MyAppLockService.this
.getApplicationContext(),
AppLockActivity.class);
it.setFlags(DriveFile.MODE_READ_ONLY);
MyAppLockService.this
.getApplicationContext()
.startActivity(it);
}
MyAppLockService.flag = true;
return;
}
return;
}
MyAppLockService.pack = current;
if (MyAppLockService.this.prefs.getBoolean("isPattern",
false)) {
MyAppLockService.this.confirmPattern(current);
} else {
it = new Intent(
MyAppLockService.this
.getApplicationContext(),
AppLockActivity.class);
it.setFlags(DriveFile.MODE_READ_ONLY);
MyAppLockService.this.getApplicationContext()
.startActivity(it);
}
MyAppLockService.flag = true;
}
}
} else if (!MyAppLockService.this.isRefreshedList) {
MyAppLockService.this.refreshList();
}
}
}
public MyAppLockService() {
this.run = true;
}
static {
BuildV = VERSION.SDK_INT;
}
public IBinder onBind(Intent intent) {
return null;
}
public void onCreate() {
this.prefs = PreferenceManager
.getDefaultSharedPreferences(getApplicationContext());
this.manager = (ActivityManager) getApplicationContext()
.getSystemService("activity");
this.pmanager = (PowerManager) getApplicationContext()
.getSystemService("power");
if (BuildV >= 21) {
this.mUsageStatsManager = (UsageStatsManager) getApplicationContext()
.getSystemService("usagestats");
}
startNotification();
Intent intent = new Intent("android.intent.action.MAIN");
intent.addCategory("android.intent.category.HOME");
this.currentHomePackage = getPackageManager().resolveActivity(intent,
Cast.MAX_MESSAGE_LENGTH).activityInfo.packageName;
this.mReciever = new C02221();
IntentFilter filter = new IntentFilter(Utils.ACTION_UPDATE);
filter.addAction(Utils.ACTION_STOP_SELF);
filter.addAction(Utils.ACTION_REMOVE_APP);
registerReceiver(this.mReciever, filter);
refreshList();
this.tt = new C02232();
this.f6t = new Timer();
this.f6t.schedule(this.tt, 500, 500);
super.onCreate();
Calendar cal = Calendar.getInstance();
Intent intent12 = new Intent(getBaseContext(),MyAppLockService.class);
PendingIntent pintent = PendingIntent.getService(getBaseContext(), 0, intent12, 0);
AlarmManager alarm = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),5, pintent);
}
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, START_STICKY_COMPATIBILITY, startId);
}
public void onDestroy() {
try {
this.f6t.cancel();
this.tt.cancel();
} catch (Exception e) {
e.printStackTrace();
}
Intent intent1 = new Intent("com.android.techtrainner");
intent1.putExtra("yourvalue", "torestore");
sendBroadcast(intent1);
}
public void refreshList() {
locked_list = new DBHelper(getApplicationContext())
.getApsHasStateTrue();
if (locked_list.size() == 0) {
doStopSelf();
}
this.isRefreshedList = true;
}
#SuppressLint({ "InlinedApi" })
private void startForegroundWithNotification() {
PendingIntent pi = PendingIntent.getActivity(this, 0, new Intent(this,
Calculator_Activity.class), 0);
String title = getString(R.string.app_name);
String content = getString(R.string.app_name);
Builder nb = new Builder(this);
nb.setSmallIcon(R.drawable.ic_transparent);
nb.setContentTitle(title);
nb.setContentText(content);
nb.setWhen(System.currentTimeMillis());
nb.setContentIntent(pi);
nb.setOngoing(true);
nb.setPriority(0);
startForeground(NOTIFICATION_ID, nb.build());
}
private void startNotification() {
startForegroundWithNotification();
if (!this.mShowNotification) {
HelperService.removeNotification(this);
}
}
private void doStopSelf() {
this.mAllowDestroy = true;
unregisterReceiver(this.mReciever);
stopForeground(true);
stopSelf();
}
private void confirmPattern(String st) {
Intent pIntent = new Intent(getApplicationContext(),
ResetActivity.class);
pIntent.putExtra("isFromReset", true);
PendingIntent pi = PendingIntent.getActivity(getApplicationContext(),
12345, pIntent, DriveFile.MODE_READ_ONLY);
Intent intent = new Intent(LockPatternActivity.ACTION_COMPARE_PATTERN, null,
getApplicationContext(), LockPatternActivity.class);
intent.putExtra("packName", st);
intent.putExtra("isStealthMode", this.prefs.getBoolean(
AlpSettings.Display.METADATA_STEALTH_MODE, false));
intent.putExtra("isFromLock", true);
intent.setFlags(DriveFile.MODE_READ_ONLY);
intent.addFlags(Cast.MAX_MESSAGE_LENGTH);
intent.putExtra(LockPatternActivity.EXTRA_PENDING_INTENT_FORGOT_PATTERN, pi);
startActivity(intent);
}
private void removeAppFromLockedList(String packName) {
locked_list.remove(packName);
}
if there is any solution for it then please help me out thanks in advance
Restart the service when it's stopped i.e. System will call onDestroy() on service which is stopped.
set a variable in service class to check service is running or not.
let boolRuningService is a variable
Intent intent = new Intent(DashboardScreen.this, ServiceClass.class);
PendingIntent pintent = PendingIntent.getService(DashboardScreen.this, 0, intent, 0);
if(!ServiceClass.boolRuningService){
AlarmManager alarm = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 30*1000, pintent);
}

Categories

Resources