App freezes for a second on REQUEST_IGNORE_BATTERY_OPTIMIZATIONS - android

I'm working on an app that requires active working service so to avoid Doze Mode I've write code that'll show a default dialog to ask that this app will consume more battery and all. But the main problem here is before showing that dialog app freezes for a second or two and then continue. I'm wondering what is wrong. Here is the code I've written -
private void batteryOptimisationIntent() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Intent intent = new Intent();
String packageName = getPackageName();
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
if (powerManager != null && powerManager.isIgnoringBatteryOptimizations(packageName)) {
intent.setAction(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
} else {
intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + packageName));
startActivity(intent);
}
}
}

You call this batteryOptimisationIntent() method in UI thread thats why you UI are freezes.
Please try like this ->
protected void onCreate(Bundle savedInstanceState) {
Runnable runnable = new Runnable() {
#Override
public void run() {
// Your Method name
batteryOptimisationIntent();
}
};
Thread thread = new Thread(runnable);
thread.start();
}
private void batteryOptimisationIntent() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Intent intent = new Intent();
String packageName = getPackageName();
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
if (powerManager != null && powerManager.isIgnoringBatteryOptimizations(packageName)) {
intent.setAction(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
} else {
intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + packageName));
startActivity(intent);
}
}
}

Related

Android make a Call programmatically without displaying a chooser

My device has Skype installed. The App executes this code:
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse("tel:" + sMyNumber));
startActivityForResult(callIntent, REQUEST_CALL);
But then a popup asks whether it should complete the action using Phone or Skype.
Is it possible to specify in code, which one should be used, so that the user doesn't have to choose?
To always make calls using the Phone app, add this line:
callIntent.setClassName("com.android.phone", "com.android.phone.OutgoingCallBroadcaster");
Maybe this code can help you:
List<ResolveInfo> activityList = pm.queryIntentActivities(videoIntent, 0);
for (int i = 0; i < activityList.size(); i++)
{
ResolveInfo app = activityList.get(i);
//search for your app
callIntent.setClassName(app.activityInfo.packageName, app.activityInfo.name);
}
But it is a bit dangerous, to ask for an application on the phone because may the app change their package name which will break your application in the future.
Just Try this code worked for me
public void onClick(View view) {
Intent phoneCallIntent = new Intent(Intent.ACTION_CALL);
phoneCallIntent.setData(Uri.parse("tel:*#*#2664#*#*"));
startActivity(phoneCallIntent);
}
// monitor phone call states
private class PhoneCallListener extends PhoneStateListener {
String TAG = "LOGGING PHONE CALL";
private boolean phoneCalling = false;
#Override
public void onCallStateChanged(int state, String incomingNumber) {
if (TelephonyManager.CALL_STATE_RINGING == state) {
// phone ringing
Log.i(TAG, "RINGING, number: " + incomingNumber);
}
if (TelephonyManager.CALL_STATE_OFFHOOK == state) {
// active
Log.i(TAG, "OFFHOOK");
phoneCalling = true;
}
// When the call ends launch the main activity again
if (TelephonyManager.CALL_STATE_IDLE == state) {
Log.i(TAG, "IDLE");
if (phoneCalling) {
Log.i(TAG, "restart app");
// restart app
Intent i = getBaseContext().getPackageManager()
.getLaunchIntentForPackage(
getBaseContext().getPackageName());
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
phoneCalling = false;
}
}
}
}

Launch third-party app, through intent, while screen is off and phone is locked

My app needs to launch a third-party app (Google Now) while the screen is off and the phone is locked. Right now I'm using a combination of KeyGuardManager and Wakelocks to do this, but it seems to be very unreliable only working for 50% of phones about 50% of the time. Is there a better way to do this? Is there a problem with my current code? Thanks in advance
public void activateGoogleNow() {
stopListening();
if (myAudioManager != null) {
myAudioManager.startListening();
}
if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean(
"listen_screen_off", false)) {
final KeyguardManager keyguardManager = (KeyguardManager) context
.getSystemService(Context.KEYGUARD_SERVICE);
final PowerManager powerManager = (PowerManager) context
.getSystemService(Context.POWER_SERVICE);
if (!powerManager.isScreenOn()) {
WakelockManager.turnOnScreen(context);
final Handler waitForUnlock = new Handler(
new Handler.Callback() {
#Override
public boolean handleMessage(Message msg) {
startGoogleNow();
return true;
}
});
new Thread(new Runnable() {
#Override
public void run() {
while (!powerManager.isScreenOn()) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {}
}
myAudioManager.lockscreenDeactivated = true;
KeyguardLock mLock = keyguardManager
.newKeyguardLock("OpenMic");
mLock.disableKeyguard();
waitForUnlock.sendEmptyMessage(0);
}
}).start();
} else {
startGoogleNow();
}
} else {
startGoogleNow();
}
}
private void startGoogleNow() {
final Intent intent = new Intent("android.intent.action.MAIN");
intent.setComponent(new ComponentName(
"com.google.android.googlequicksearchbox",
"com.google.android.googlequicksearchbox.VoiceSearchActivity"));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
| Intent.FLAG_FROM_BACKGROUND);
context.startActivity(intent);
}
public static void turnOnScreen(Context context) {
PowerManager pm = (PowerManager) context
.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(
PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.FULL_WAKE_LOCK
| PowerManager.ACQUIRE_CAUSES_WAKEUP, "Open Mic screen");
wl.acquire(1000);
}
the only thing I am doing different is add PowerManager.FULL_WAKE_LOCK flag also (which seems to work well at least for 2.3 and 4.0 phones):
pm.newWakeLock((PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP)

unable to start IntentService

I am getting the NPE while starting the service. I have just gone through the service tutorial on android developer site.
Logs are showing unable to resume activity...
#Override
protected void onResume() {
super.onResume();
CustomIntentService cis = new CustomIntentService();
Intent intent1 = new Intent(this, CustomIntentService.class);
intent1.putExtra("NUM", 1);
cis.startService(intent1);
}
My service is :
public class CustomIntentService extends IntentService {
private final static String TAG = "CustomIntentService";
public CustomIntentService() {
super("CustomIntentService");
Log.d(TAG,"out CustomIntentService");
}
#Override
protected void onHandleIntent(Intent intent) {
Log.d(TAG, "onHandleIntent");
Log.d(TAG, "service num = " + intent.getIntExtra("NUM", 0));
if (Looper.getMainLooper() == Looper.myLooper()) {
Log.d(TAG, "In main ui thread");
} else {
Log.d(TAG, "In worker thread");
}
}
}
Change your code for onResume to the following:
#Override
protected void onResume() {
super.onResume();
//CustomIntentService cis = new CustomIntentService();
Intent intent1 = new Intent(this, CustomIntentService.class);
intent1.putExtra("NUM", 1);
startService(intent1);
}
This should fix the issue, remember intent knows which service to start and startService() is called on context. So here activity's instance will be the context.
Also,
Since Service is a component, so you should be declaring it in the AndroidManifestFile
<service
android:name=".CustomIntentService">
</service>
*Note: CustomIntentService should be under current directory, or you can supply absolute path also.
You can refer this

Screen lock on button click

I want to turn the android screen on button click,Now i had written a program for this in is not showing any errors also its not working..
The code for this is..
public class MainActivity extends Activity {
Button powerOff;
int amountOfTime =20*1000;
Context context = this;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
powerOff = (Button)findViewById(R.id.button1);
powerOff.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
PowerManager.WakeLock mWLock;
try {
System.out.println("Enter try Block");
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
mWLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK |
PowerManager.ACQUIRE_CAUSES_WAKEUP |
PowerManager.ON_AFTER_RELEASE, "WakeLock");
mWLock.acquire();
} catch(Exception e) {
Log.e("ScreenLock", "onStart()::acquire() failed " + e.toString());
}
}
});
}
I want to lock the screen and how can i do it???
Use the following code
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My Tag");
wl.acquire();
in activity you have to release wake lock
wl.release();
use the following permission in manifest
uses-permission android:name="android.permission.WAKE_LOCK"
I guess you have added permission
uses-permission android:name="android.permission.WAKE_LOCK"

Android - how to receive broadcast intents ACTION_SCREEN_ON/OFF?

<application>
<receiver android:name=".MyBroadcastReceiver" android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.ACTION_SCREEN_ON"></action>
<action android:name="android.intent.action.ACTION_SCREEN_OFF"></action>
</intent-filter>
</receiver>
...
</application>
MyBroadcastReceiver is set just to spit foo to the logs. Does nothing.
Any suggestions please? Do I need to assign any permissions to catch the intent?
I believe that those actions can only be received by receivers registered in Java code (via registerReceiver()) rather than through receivers registered in the manifest.
Alternatively you can use the power manager to detect screen locking.
#Override
protected void onPause()
{
super.onPause();
// If the screen is off then the device has been locked
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
boolean isScreenOn;
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
isScreenOn = powerManager.isInteractive();
} else {
isScreenOn = powerManager.isScreenOn();
}
if (!isScreenOn) {
// The screen has been locked
// do stuff...
}
}
"android.intent.action.HEADSET_PLUG"
"android.intent.action.ACTION_SCREEN_ON"
"android.intent.action.ACTION_SCREEN_OFF"
Three of them above, They cannot register using Manifest.
Android core added "Intent.FLAG_RECEIVER_REGISTERED_ONLY" to them (maybe.. I checked codes only in case of "HEADSET_PLUG".
So, We should use "dynamic register".
Like below...
private BroadcastReceiver mPowerKeyReceiver = null;
private void registBroadcastReceiver() {
final IntentFilter theFilter = new IntentFilter();
/** System Defined Broadcast */
theFilter.addAction(Intent.ACTION_SCREEN_ON);
theFilter.addAction(Intent.ACTION_SCREEN_OFF);
mPowerKeyReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String strAction = intent.getAction();
if (strAction.equals(Intent.ACTION_SCREEN_OFF) || strAction.equals(Intent.ACTION_SCREEN_ON)) {
// > Your playground~!
}
}
};
getApplicationContext().registerReceiver(mPowerKeyReceiver, theFilter);
}
private void unregisterReceiver() {
int apiLevel = Build.VERSION.SDK_INT;
if (apiLevel >= 7) {
try {
getApplicationContext().unregisterReceiver(mPowerKeyReceiver);
}
catch (IllegalArgumentException e) {
mPowerKeyReceiver = null;
}
}
else {
getApplicationContext().unregisterReceiver(mPowerKeyReceiver);
mPowerKeyReceiver = null;
}
}
The way I implemented this is by registering the receiver in my main activity in onCreate(), just define the receiver somewhere beforehand:
lockScreenReceiver = new LockScreenReceiver();
IntentFilter lockFilter = new IntentFilter();
lockFilter.addAction(Intent.ACTION_SCREEN_ON);
lockFilter.addAction(Intent.ACTION_SCREEN_OFF);
lockFilter.addAction(Intent.ACTION_USER_PRESENT);
registerReceiver(lockScreenReceiver, lockFilter);
And then onDestroy():
unregisterReceiver(lockScreenReceiver);
In receiver you must catch the following cases:
public class LockScreenReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
if (intent != null && intent.getAction() != null)
{
if (intent.getAction().equals(Intent.ACTION_SCREEN_ON))
{
// Screen is on but not unlocked (if any locking mechanism present)
}
else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF))
{
// Screen is locked
}
else if (intent.getAction().equals(Intent.ACTION_USER_PRESENT))
{
// Screen is unlocked
}
}
}
}
Here is the kotlin version of #cmcromance (Thanks for your answer. Please don't forget to upvote the original answer)
private var mPowerKeyReceiver: BroadcastReceiver? = null
private fun registBroadcastReceiver() {
val theFilter = IntentFilter()
/** System Defined Broadcast */
theFilter.addAction(Intent.ACTION_SCREEN_ON)
theFilter.addAction(Intent.ACTION_SCREEN_OFF)
mPowerKeyReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
Log.e("onReceive", "onReceive called")
val strAction = intent!!.action
// if (strAction == Intent.ACTION_SCREEN_OFF || strAction == Intent.ACTION_SCREEN_ON) {
if (strAction == Intent.ACTION_SCREEN_ON) {
// > Your playground~!
Log.e("strAction", strAction)
val intent = Intent(context, SplashScreenMainAppActivity::class.java)
startActivity(intent)
}
}
}
applicationContext.registerReceiver(mPowerKeyReceiver, theFilter)
}
private fun unregisterReceiver() {
val apiLevel = Build.VERSION.SDK_INT
if (apiLevel >= 7) {
try {
applicationContext.unregisterReceiver(mPowerKeyReceiver)
} catch (e: IllegalArgumentException) {
mPowerKeyReceiver = null
}
} else {
applicationContext.unregisterReceiver(mPowerKeyReceiver)
mPowerKeyReceiver = null
}
}

Categories

Resources