how to unlock phone from service [duplicate] - java

I am doing an application which Locks the screen on shake. Now it is locking and from there it going to a broadcast receiver from there if the screen is off its entering into a service which has to turn the screen on.
Below is the broadcast receiver:
public class ScreenReceiver extends BroadcastReceiver {
public static boolean wasScreenOn = true;
#Override
public void onReceive(Context context, Intent intent) {
System.out.println("Entered Broadcaste Reciever");
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
// DO WHATEVER YOU NEED TO DO HERE
System.out.println("SCREEN_OFF"+wasScreenOn);
wasScreenOn = false;
Intent i = new Intent(context, UpdateService.class);
i.putExtra("screen_state", wasScreenOn);
context.startService(i);
System.out.println("jrkejhr keh");
}
else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
// AND DO WHATEVER YOU NEED TO DO HERE
wasScreenOn = true;
System.out.println("SCREEN_ON"+wasScreenOn);
}
}
And its entering to a service where i had written the intent action to go home is...
ShakeListener mShaker;
int amountOfTime = 0;
Context context1;
#Override
public void onCreate() {
super.onCreate();
// REGISTER RECEIVER THAT HANDLES SCREEN ON AND SCREEN OFF LOGIC
System.out.println("Enterd Service");
final Vibrator vibe = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
mShaker = new ShakeListener(this);
mShaker.setOnShakeListener(new ShakeListener.OnShakeListener () {
public void onShake() {
vibe.vibrate(100);
Intent goHome = new Intent();
goHome.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
goHome.setAction("android.intent.action.MAIN");
goHome.addCategory("android.intent.category.HOME");
startActivity(goHome);
}
});
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
It is entering into the service. But home screen is not displaying. When the service is invoked the the screen is locked.

Edit:
As some folks needs help in Unlocking device after locking programmatically,
I came through post Android screen lock/ unlock programatically, please have look, may help you.
Original Answer was:
You need to get Admin permission and you can lock phone screen
please check below simple tutorial to achive this one
Lock Phone Screen Programmtically
also here is the code example..
LockScreenActivity.java
public class LockScreenActivity extends Activity implements OnClickListener {
private Button lock;
private Button disable;
private Button enable;
static final int RESULT_ENABLE = 1;
DevicePolicyManager deviceManger;
ActivityManager activityManager;
ComponentName compName;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
deviceManger = (DevicePolicyManager)getSystemService(
Context.DEVICE_POLICY_SERVICE);
activityManager = (ActivityManager)getSystemService(
Context.ACTIVITY_SERVICE);
compName = new ComponentName(this, MyAdmin.class);
setContentView(R.layout.main);
lock =(Button)findViewById(R.id.lock);
lock.setOnClickListener(this);
disable = (Button)findViewById(R.id.btnDisable);
enable =(Button)findViewById(R.id.btnEnable);
disable.setOnClickListener(this);
enable.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if(v == lock){
boolean active = deviceManger.isAdminActive(compName);
if (active) {
deviceManger.lockNow();
}
}
if(v == enable){
Intent intent = new Intent(DevicePolicyManager
.ACTION_ADD_DEVICE_ADMIN);
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
compName);
intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,
"Additional text explaining why this needs to be added.");
startActivityForResult(intent, RESULT_ENABLE);
}
if(v == disable){
deviceManger.removeActiveAdmin(compName);
updateButtonStates();
}
}
private void updateButtonStates() {
boolean active = deviceManger.isAdminActive(compName);
if (active) {
enable.setEnabled(false);
disable.setEnabled(true);
} else {
enable.setEnabled(true);
disable.setEnabled(false);
}
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case RESULT_ENABLE:
if (resultCode == Activity.RESULT_OK) {
Log.i("DeviceAdminSample", "Admin enabled!");
} else {
Log.i("DeviceAdminSample", "Admin enable FAILED!");
}
return;
}
super.onActivityResult(requestCode, resultCode, data);
}
}
MyAdmin.java
public class MyAdmin extends DeviceAdminReceiver{
static SharedPreferences getSamplePreferences(Context context) {
return context.getSharedPreferences(
DeviceAdminReceiver.class.getName(), 0);
}
static String PREF_PASSWORD_QUALITY = "password_quality";
static String PREF_PASSWORD_LENGTH = "password_length";
static String PREF_MAX_FAILED_PW = "max_failed_pw";
void showToast(Context context, CharSequence msg) {
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
}
#Override
public void onEnabled(Context context, Intent intent) {
showToast(context, "Sample Device Admin: enabled");
}
#Override
public CharSequence onDisableRequested(Context context, Intent intent) {
return "This is an optional message to warn the user about disabling.";
}
#Override
public void onDisabled(Context context, Intent intent) {
showToast(context, "Sample Device Admin: disabled");
}
#Override
public void onPasswordChanged(Context context, Intent intent) {
showToast(context, "Sample Device Admin: pw changed");
}
#Override
public void onPasswordFailed(Context context, Intent intent) {
showToast(context, "Sample Device Admin: pw failed");
}
#Override
public void onPasswordSucceeded(Context context, Intent intent) {
showToast(context, "Sample Device Admin: pw succeeded");
}
}

The androidmanifest.xml and policies.xml files on the sample page are invisible in my browser due to it trying to format the XML files as HTML. I'm only posting this for reference for the convenience of others, this is sourced from the sample page.
Thanks all for this helpful question!
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.kns"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="8" />
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".LockScreenActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".MyAdmin"
android:permission="android.permission.BIND_DEVICE_ADMIN">
<meta-data android:name="android.app.device_admin"
android:resource="#xml/policies" />
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
</intent-filter>
</receiver>
</application>
</manifest>
policies.xml
<?xml version="1.0" encoding="utf-8"?>
<device-admin xmlns:android="http://schemas.android.com/apk/res/android">
<uses-policies>
<limit-password />
<watch-login />
<reset-password />
<force-lock />
<wipe-data />
</uses-policies>
</device-admin>

Use Activity.getWindow() to get the window of your activity; use Window.addFlags() to add whichever of the following flags in WindowManager.LayoutParams that you desire:
FLAG_DISMISS_KEYGUARD
FLAG_SHOW_WHEN_LOCKED
FLAG_TURN_SCREEN_ON

Related

Android NFC Reader in MVP - onNewIntent not firing

I have a working NFC reader/writer code. Using the same code, I added the reader function in another app which is following MVP architecture.
The activity is named NFCReaderActivity. A separate NFC class is created (NFCReader), which implements Sensor interface.
The app is supposed to work both in the foreground and launch showing the NFC tag info. The launch part is working fine and app launches and reads the tag and shows its content.
However, in the foreground, on scanning, it does nothing. I only hear the scan beep but no onNewIntent is firing.
Below are the log entries captured for foreground and launch actions. There is a difference in the class names:
When not launching
I/ActivityManager: START u0 {act=android.nfc.action.NDEF_DISCOVERED typ=application/com.abc.vi flg=0x14008000 cmp=com.abc.vi/.ui.reader.NFCReader (has extras)} from uid 10038 on display 0
When launching
I/ActivityManager: START u0 {act=android.nfc.action.NDEF_DISCOVERED typ=application/com.abc.vi cmp=com.abc.vi/.ui.reader.NFCReaderActivity (has extras)} from uid 1027 on display 0
Activity
onCreate
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(TAG, "__onCreate__ " );
setContentView(R.layout.activity_nfc_reader);
VI.setNFCReaderActivityContext(this); //VI is the Application class
ButterKnife.bind(this);
presenter = new ReaderPresenter(this);
}
onNewIntent
#Override
public void onNewIntent(Intent intent) {
Log.i(TAG, "__onNewIntent__ " );
// onResume gets called after this to handle the intent
// setIntent(intent);
presenter.onNewIntent(intent);
}
onResume, onPause
#Override
protected void onResume() {
super.onResume();
Log.i(TAG, "__onResume__ " );
presenter.onResume();
}
#Override
protected void onPause() {
super.onPause();
Log.i(TAG, "__onPause__ " );
presenter.onPause();
}
Presenter
ReaderPresenter(ReaderContract.View view) {
this.view = view;
initSensor();
}
#Override
public void initSensor() {
nfcReader = new NFCReader(VI.getNFCReaderActivityContext(), this); //VI is the Application class
}
#Override
public void onNewIntent(Intent intent) {
nfcReader.resolveIntent(intent);
}
#Override
public void onResume() {
nfcReader.onResume();
}
#Override
public void onPause() {
nfcReader.onPause();
}
#Override
public void onDestroy() {
speech.onDestroy();
}
NFCReader
public class NFCReader implements Sensors {
private static final String TAG = NFCReader.class.getSimpleName();
private NfcAdapter nfcAdapter;
private PendingIntent nfcPendingIntent;
private NFCReaderActivity activity;
private ReaderPresenter presenter;
NFCReader(NFCReaderActivity nfcReaderActivity, ReaderPresenter readerPresenter) {
this.activity = nfcReaderActivity;
this.presenter = readerPresenter;
init();
}
#Override
public void init() {
//Initialize NFC adapter
nfcAdapter = NfcAdapter.getDefaultAdapter(activity);
nfcPendingIntent = PendingIntent.getActivity(activity, 0, new Intent(activity,
getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP), 0);
}
public void onResume() {
if (nfcAdapter != null) {
nfcAdapter.enableForegroundDispatch(activity, nfcPendingIntent, null, null);
// if NFC not enabled
if (!nfcAdapter.isEnabled()) {
new AlertDialog.Builder(activity)
.setPositiveButton(activity.getString(R.string.update_setting_btn),
(dialog, which) -> {
Intent setNfc = new Intent(Settings.ACTION_WIRELESS_SETTINGS);
activity.startActivity(setNfc);
})
.setOnCancelListener(
dialog -> activity.finish()
)
.create().show();
}
resolveIntent(activity.getIntent());
} else {
Toast.makeText(VI.getAppContext(),
activity.getString(R.string.error_no_nfc_found), Toast.LENGTH_LONG).show();
}
}
public void onPause() {
if (nfcAdapter != null) {
nfcAdapter.disableForegroundDispatch(activity);
}
}
public void resolveIntent(Intent intent){
Log.i(TAG, "__resolveIntent__");
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) {
NdefMessage[] messages = null;
Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
if (rawMsgs != null) {
messages = new NdefMessage[rawMsgs.length];
for (int i = 0; i < rawMsgs.length; i++) {
messages[i] = (NdefMessage) rawMsgs[i];
}
}
if ((messages != null ? messages[0] : null) != null) {
StringBuilder result = new StringBuilder();
byte[] payload = messages[0].getRecords()[0].getPayload();
for (byte aPayload : payload) {
result.append((char) aPayload);
}
Log.i(TAG,"Decoded --> "+result.toString());
presenter.getData(result.toString());
}
}
}
}
Manifest
<activity android:name=".ui.reader.NFCReaderActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="#string/mime_type" />
</intent-filter>
</activity>
UPDATE
I moved all the code from NFCReader class to NFCReaderActivity and both foreground and launch modes are working. The issue is with MVP architecture. How to convert it back to MVP?
You seem to register the pending intent for the wrong (actually an invalid) component (not your activity class). The reason is that when you create the PendingIntent that you assign to nfcPendingIntent, you use getClass() to obtain the class of the NFCReader instance. Instead you would need to use activity.getClass() to obtain the class of your activity component.

"signInSilently(): failure" when trying to sign in to GooglePlay Game Services with LibGDX

I have been trying to add Google Game Services to my LibGDX project for the past 3 days now at first I tried the LibGDX tutorials but all of them seem to be outdated. Then I was advised to use the Google Game Services official code
LibGDX: How to Implement Google Play Game Services?
I imported the sample project TypeANumber and tried to add the code to my project but when I try to sign in I'm getting the "signInSilently(): failure" error and it crashes when I try to open the leaderboards and achievements on both the debug and signed APKS.
Here is my code:
AndroidLauncher:
private void signInSilently() {
Log.d(TAG, "signInSilently()");
mGoogleSignInClient.silentSignIn().addOnCompleteListener(this,
new OnCompleteListener<GoogleSignInAccount>() {
#Override
public void onComplete(#NonNull Task<GoogleSignInAccount> task) {
if (task.isSuccessful()) {
Log.d(TAG, "signInSilently(): success");
onConnected(task.getResult());
} else {
Log.d(TAG, "signInSilently(): failure", task.getException());
onDisconnected();
}
}
});
}
#Override
public void showLeaderboards(){
runOnUiThread(new Runnable() {
public void run() {
onShowLeaderboardsRequested();
}
});
}
#Override
public void showAchievements(){
runOnUiThread(new Runnable() {
public void run() {
onShowAchievementsRequested();
}
});
}
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.harrybanda.blaster" >
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="27" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<meta-data android:name="com.google.android.gms.games.APP_ID"
android:value="#string/app_id" />
<meta-data android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version"/>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/GdxTheme" >
<activity
android:name="com.google.android.gms.ads.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
android:theme="#android:style/Theme.Translucent" />
<activity
android:name="com.harrybanda.blaster.AndroidLauncher"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
In my build.gradle i added:
compile "com.google.android.gms:play-services-games:11.8.0"
compile "com.google.android.gms:play-services-auth:11.8.0"
Logcat:
01-07 09:56:30.011 618-618/? D/Blaster: onResume()
01-07 09:56:30.011 618-618/? D/Blaster: signInSilently()
01-07 09:56:30.512 618-618/? D/Blaster: signInSilently(): failure
com.google.android.gms.common.api.b: 4:
at com.google.android.gms.common.internal.y.a(Unknown Source)
at com.google.android.gms.common.internal.ae.a(Unknown Source)
at com.google.android.gms.common.internal.af.a(Unknown Source)
at com.google.android.gms.common.api.internal.BasePendingResult.c(Unknown Source)
at com.google.android.gms.common.api.internal.BasePendingResult.a(Unknown Source)
at com.google.android.gms.auth.api.signin.internal.g.a(Unknown Source)
at com.google.android.gms.auth.api.signin.internal.r.onTransact(Unknown Source)
at android.os.Binder.execTransact(Binder.java:451)
01-07 09:56:30.512 618-618/? D/Blaster: onDisconnected()
From 1st look of your question, It seems that you're keeping meta data outside the application tag but should be inside application tag in AndroidManifest.xml file
Like this :
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/GdxTheme" >
<activity
android:name="com.google.android.gms.ads.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
android:theme="#android:style/Theme.Translucent" />
<activity
android:name="com.harrybanda.blaster.AndroidLauncher"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
<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.games.APP_ID"
android:value="#string/app_id" />
<meta-data android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version"/>
</application>
StatusCode 4 (SIGN_IN_REQUIRED) error means client attempted to
connect to the service but the user is not signed in.
Here is my AndroidLauncher class
public class AndroidLauncher extends AndroidApplication implements MyServices {
private GoogleSignInClient mGoogleSignInClient;
private LeaderboardsClient mLeaderboardsClient;
private PlayersClient mPlayersClient;
private static final String TAG=AndroidLauncher.class.getSimpleName();
private static final int RC_SIGN_IN = 9001;
private static final int RC_UNUSED = 5001;
private static final int RC_LEADERBOARD_UI = 9004;
private String greetingMsg="Welcome, ";
private boolean greetingDisplayed;
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
greetingDisplayed=false;
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
initialize(new GdxGame(this), config);
mGoogleSignInClient = GoogleSignIn.getClient(this,
new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN).build());
}
#Override
public boolean isSignedIn() {
return GoogleSignIn.getLastSignedInAccount(this) != null;
}
private void signInSilently() {
mGoogleSignInClient.silentSignIn().addOnCompleteListener(this,
new OnCompleteListener<GoogleSignInAccount>() {
#Override
public void onComplete(#NonNull Task<GoogleSignInAccount> task) {
if (task.isSuccessful()) {
greetingMsg="Welcome back, ";
onConnected(task.getResult());
} else {
onDisconnected();
}
}
});
}
private void onConnected(GoogleSignInAccount googleSignInAccount) {
mLeaderboardsClient = Games.getLeaderboardsClient(this, googleSignInAccount);
mPlayersClient = Games.getPlayersClient(this, googleSignInAccount);
mPlayersClient.getCurrentPlayer()
.addOnCompleteListener(new OnCompleteListener<Player>() {
#Override
public void onComplete(#NonNull Task<Player> task) {
String displayName;
if (task.isSuccessful()) {
displayName = task.getResult().getDisplayName();
} else {
Exception e = task.getException();
handleException(e, getString(R.string.players_exception));
displayName = "???";
}
if(!greetingDisplayed)
welcomeMessage(displayName);
}
});
}
private void welcomeMessage(String name){
Toast toast = Toast.makeText(this, greetingMsg + name, Toast.LENGTH_LONG);
toast.setGravity(Gravity.TOP, 0, 0);
View view = toast.getView();
TextView text = (TextView) view.findViewById(android.R.id.message);
toast.show();
greetingDisplayed=true;
}
#Override
public void startSignInIntent() {
startActivityForResult(mGoogleSignInClient.getSignInIntent(), RC_SIGN_IN);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
if (requestCode == RC_SIGN_IN) {
Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(intent);
try {
GoogleSignInAccount account = task.getResult(ApiException.class);
greetingMsg="Welcome, ";
onConnected(account);
} catch (ApiException apiException) {
String message = apiException.getMessage();
if (message == null || message.isEmpty()) {
message = getString(R.string.signin_other_error);
}
onDisconnected();
}
}
}
#Override
protected void onResume() {
super.onResume();
signInSilently();
}
private void signOut() {
if (!isSignedIn()) {
Log.w(TAG, "signOut() called, but was not signed in!");
return;
}
mGoogleSignInClient.signOut().addOnCompleteListener(this,
new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
boolean successful = task.isSuccessful();
Log.d(TAG, "signOut(): " + (successful ? "success" : "failed"));
onDisconnected();
}
});
}
private void onDisconnected() {
mLeaderboardsClient = null;
mPlayersClient = null;
}
#Override
public void submitScore(int score){
if(isSignedIn())
mLeaderboardsClient.submitScore(getString(R.string.leaderboard_id), score);
}
#Override
public void showLeaderBoard() {
if(isSignedIn())
mLeaderboardsClient.getLeaderboardIntent(getString(R.string.leaderboard_id))
.addOnSuccessListener(new OnSuccessListener<Intent>() {
#Override
public void onSuccess(Intent intent) {
startActivityForResult(intent, RC_LEADERBOARD_UI);
}
});
}
private void handleException(Exception e, String details) {
int status = 0;
if (e instanceof ApiException) {
ApiException apiException = (ApiException) e;
status = apiException.getStatusCode();
}
String message = getString(R.string.status_exception_error, details, status, e);
new AlertDialog.Builder(this)
.setMessage(message)
.setNeutralButton(android.R.string.ok, null)
.show();
}
}
And MyServices interface
interface MyServices{
void startSignInIntent();
boolean isSignedIn();
void showLeaderBoard();
void submitScore(int score);
}
First time I call startSignInIntent() of interface by myself after user install app.
I think I got it.
This is from Google Play Games Services official docs:
You can call silentSignIn() to retrieve the currently signed-in
player’s account, and try to sign players in without displaying a user
interface if they have successfully signed in to your app on a
different device.
...
If the silent sign-in attempt fails, you can optionally send the sign-in intent to display a sign-in user interface, as described in Performing interactive sign-in.
...
If the silent sign-in attempt fails, you can call getException() to obtain an ApiException with the detailed status code. A status code of CommonStatusCodes.SIGN_IN_REQUIRED indicates that the player needs to take explicit action to sign-in. In this case, your app should launch an interactive sign-in flow as described in the next section.
And as #Aryan noted, you get CommonStatusCodes.SIGN_IN_REQUIRED, which means that a user is not signed in. It's intentional in this case, that silentSignIn() is not successful. It will only be successful, if a user is already signed in on any device.

Android service closed even with startForeground()

So I need a service for my app, but I need it to keep running all the time until the user press the end Button in the app. It goes like this : The user press start, my service start (starting a notification btw), then 2-3h or more later the user has to click on the notification which get him back to the app where he can press the "End" button and end the service. I call this a Start-End cycle for simplicity purposes.
My user will use many Start-End cycles a day, but the problem is my notification goes away after some time when the phone his lock.
I've already been able to put the notification and service thanks to Stackoverflow so I hope you have a solution for this too :)!
Here is my main activity :
public class MainActivity extends AppCompatActivity{
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
checkEnabled();
mTimeListenerD.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) { //Button to set the Start time
setDebutTime();
checkEnabled();
new Thread(new Runnable() {
#Override
public void run() {
Intent start=new Intent(MainActivity.this,TimeService.class);
start.putExtra("StopSig",false);
start.putExtra("Temps_travail",mTempsTravail); //Envoi Long
start.putExtra("mSmallest",mSmallest); //Envoi Long
start.putExtra("file_src",src); //Envoi String
start.putExtra("file_dst",dst); //Envoi String
start.putExtra("Debut",sDebut); //Envoi String
start.putExtra("Fin",sFin); //Envoi String
start.putExtra("Name",sName);//Envoi String
start.putExtra("String_travail",sTempsTravail); //Envoi String
start.putExtra("Smallest",sSmallest);//Envoi String*/
startService(start);
}
}).start();
}
});
mTimeListenerF.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) { //Button to set the End Time
setFinTime();
checkEnabled();
new Thread(new Runnable() {
#Override
public void run() {
Intent end = new Intent(MainActivity.this,TimeService.class);
end.putExtra("StopSig",true);
end.putExtra("TimeF",mTimeF);
end.putExtra("Temps_travail",mTempsTravail); //Envoi Long
end.putExtra("mSmallest",mSmallest); //Envoi Long
end.putExtra("file_src",src); //Envoi String
end.putExtra("file_dst",dst); //Envoi String
end.putExtra("Debut",sDebut); //Envoi String
end.putExtra("Fin",sFin); //Envoi String
end.putExtra("Name",sName);//Envoi String
end.putExtra("String_travail",sTempsTravail); //Envoi String
end.putExtra("Smallest",sSmallest);
// startService(end);
stopService(end);
}
}).start();
}
});
mMail.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
sendMail();
}
}); //Send data by mail
Here is the service i use, with the method that show the notification:
public class TimeService extends Service {
#Override
public void onCreate() {
Log.i(TAG, "Service onCreate");
mContext=TimeService.this;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "Service onStartCommand");
Toast.makeText(this,"TimeServiceStarted",Toast.LENGTH_LONG).show();
stopSig=intent.getBooleanExtra("StopSig",false); //Receiving Boolean
setDebutTime();
setNotification();
//Stop service once it finishes its task
//stopSelf();
return Service.START_STICKY;
}
#Override
public IBinder onBind(Intent arg0) {
Log.i(TAG, "Service onBind");
TSTempsTravail=arg0.getLongExtra("Temps_travail",TSTempsTravail); //Receiving Long
TSSmallest=arg0.getLongExtra("mSmallest",TSSmallest);//Receiving Long
sName=arg0.getStringExtra("Name");//Receiving String
sDebut= arg0.getStringExtra("Debut");//Receiving String
sFin= arg0.getStringExtra("Fin");//Receiving String
sTempsTravail= arg0.getStringExtra("String_travail");//Receiving String
sSmallest=arg0.getStringExtra("Smallest");//Receiving String
return null;
}
#Override
public void onDestroy() {
stopSig=true;
setFinTime();
// getName();
getHeureSupp(TimeD,TimeF);
Clock();
writeToFile(sDebut,sFin,sName,sTempsTravail);
try {
copyFile(src,dst);
} catch (IOException e) {
e.printStackTrace();
}
//sendMail();
Log.i(TAG, "Service onDestroy");
//Toast.makeText(this,"Service stopped",Toast.LENGTH_LONG).show();
}
public void setNotification() {
Intent notificationIntent = new Intent(this, MainActivity.class);
/*notificationIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);*/
PendingIntent pendingIntent = PendingIntent.getActivity(this, 15, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Bitmap icon = BitmapFactory.decodeResource(getResources(),
R.drawable.logo);
NotificationCompat.Builder notification = (NotificationCompat.Builder) new NotificationCompat.Builder(this)
.setContentTitle("myTitle")
.setTicker("myTicker")
.setContentText("myText")
.setSmallIcon(R.drawable.logo_small)
.setLargeIcon(Bitmap.createScaledBitmap(icon, 128, 128, false))
.setContentIntent(pendingIntent)
.setOngoing(true);
startForeground(15, notification.build());
}
And finally here is the Manifest if that can be useful in anyway :
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.benjii.myapp">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<application
android:allowBackup="true"
android:icon="#drawable/logo_small"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity"
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=".TimeService"
android:icon="#drawable/logo_small"
android:label="#string/service">
</service>
</application>
</manifest>
Application components (services, activities, etc) always run in main thread, no matter what thread they are started from. Consider starting thread in your Service instead, or use an IntentService.

Simple service won't bind : bindService return false, service connection never triggered

This is my first time using Service in Android and my service won't bind.
The Service code :
package mackosoft.almightymessage;
public final class MainService extends Service {
private final static String TAG = "Main Service";
private final IBinder binder = new MainServiceBinder();
#Override
public final void onCreate() {
super.onCreate();
Log.d(TAG, "Service created");
Toast.makeText(this, "Service created", Toast.LENGTH_SHORT).show();
}
#Override
public final int onStartCommand(final Intent intent, final int flags, final int startId) {
return START_STICKY;
}
#Override
public final void onDestroy() {
super.onDestroy();
Log.d(TAG, "Service created");
Toast.makeText(this, "Service destroyed", Toast.LENGTH_SHORT).show();
}
#Override
public final IBinder onBind(final Intent intent) {
Toast.makeText(this, "Service binded", Toast.LENGTH_SHORT).show();
return this.binder;
}
public final class MainServiceBinder extends Binder {
final MainService getService() {
return MainService.this;
}
}
}
Manifest file :
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="mackosoft.almightymessage" >
<application
android:allowBackup="true"
android:icon="#drawable/ic_logo"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden"
android:icon="#drawable/ic_logo"
android:label="#string/app_name"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".MainService"
android:enabled="true" >
</service>
</Application
</manifest>
And finally the part in MainActivity where I try to bind the service :
public final class MainActivity extends AppCompatActivity {
#Override
protected final void onStart() {
super.onStart();
final Intent intent = new Intent(MainActivity.this, MainService.MainServiceBinder.class);
final boolean status = bindService(intent, this.connection, Context.BIND_AUTO_CREATE);
Log.d(TAG, "Service binded ? " + status);
}
private final ServiceConnection connection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
Log.d(TAG, "Service connected !");
service = ((MainService.MainServiceBinder) iBinder).getService(); // service is a private member of MainActivity
}
#Override
public void onServiceDisconnected(ComponentName componentName) {
Log.d(TAG, "Service disconnected !");
}
};
}
Running the application, Logcat shows :
mackosoft.almightymessage D/MainActivity﹕ Service binded ? false
And Service Connection is NEVER triggered !
I tried multiple solution :
Moving the binding call to a Button.onClick() and using getApplicationContext()
Using directly getApplicationContext()
In the Manifest, changed -> android:name="mackosoft.almightymessage.MainService"
Changed also the Intent-> final Intent intent = new Intent(this, MainService.MainServiceBinder.class);
Also tried to add this.startService(intent) and with this.getApplicationContext()
All of the above fail and no error in the logs !
I have no luck at all.
Test device : Samsung Galaxy Note 3 running Cyanogen Mode 12.1 (Android 5.1)
Android Studio 1.2.1.1 (stable)
Thanks for the help !!
final Intent intent = new Intent(MainActivity.this, MainService.MainServiceBinder.class);
Should be
final Intent intent = new Intent(MainActivity.this, MainService.class);
See the example provided in the docs for further info

Hang up and decline incoming call by custom activity[buttons] Android

I am just in process by learning Android a bit, and i have stumbled on this problem.
I want to do a "custom incoming call screen". My current Solution is a class(IncomingCallInterceptor) that extends from BroadcastReceiver. In IncomingCallInterceptor class i override the onReceive and starting my activity(MainActivity) with layout when the phone is ringing.
In that activity(MainActivity) i have three buttons:
Accept Call, Hang Up, Decline Call
Those buttons should do what they say, Answer the phone, hang up the phone or decline the call.
I have in someway got the Accept Call to work, but not Hang Up and Decline.
Heres my code below:
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.uppgift.six.one.incoming61.sixone" >
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.CALL_PHONE"/>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<receiver android:name="IncomingCallInterceptor">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE"/>
</intent-filter>
</receiver>
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
</activity>
</application>
</manifest>
IncomingCallInterceptor that extends from BroadcastReceiver:
public class IncomingCallInterceptor extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Context appContext = context.getApplicationContext();
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
String msg = "Phone state changed to " + state;
if (TelephonyManager.EXTRA_STATE_RINGING.equals(state)) {
String incomingNumber = intent.getStringExtra
(TelephonyManager.EXTRA_INCOMING_NUMBER);
msg += ". Incoming number is this " + incomingNumber;
//START MY ACTIVITY!
Intent i = new Intent(appContext, MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
appContext.startActivity(i);
}
Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
}
}
Here is my Activity(The Layout is nothing to post, just now is basically three buttons)
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnAnswer = (Button)findViewById(R.id.btnAnswer);
Button btnDecline= (Button)findViewById(R.id.btnDecline);
Button btnHangUp= (Button)findViewById(R.id.btnHangUp);
btnAnswer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(Intent.ACTION_MEDIA_BUTTON);
i.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP,
KeyEvent.KEYCODE_HEADSETHOOK));
sendOrderedBroadcast(i, null);
}
});
btnDecline.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Decline Call (I need help here)
}
});
btnHangUp.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Hang Up Call (I need help here)
}
});
}
In the MainActivity class it is marked by comments where i need some help.
I have also seen something about a "Telephonyservice interface"(thingy) solution, but i don't understand how that worked when i was testing it.
Reject Call:
try {
TelephonyManager tm = (TelephonyManager)
getSystemService(Context.TELEPHONY_SERVICE);
try {
Class c = Class.forName(tm.getClass().getName());
Method m = c.getDeclaredMethod("getITelephony");
m.setAccessible(true);
Object telephonyService = m.invoke(tm); // Get the internal ITelephony object
c = Class.forName(telephonyService.getClass().getName()); // Get its class
m = c.getDeclaredMethod("endCall"); // Get the "endCall()" method
m.setAccessible(true); // Make it accessible
m.invoke(telephonyService); // invoke endCall()
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
}
}

Categories