Make calls from custom outgoing screen - android

I want to replace the outgoing screen and make call through that custom screen. I succeed to bring custom screen but I could not make calls. If I use ACTION.CALL then it call the Default outgoing screen.
public class OutgoingCallBroadcastReciver extends BroadcastReceiver {
Context c;
public OutgoingCallBroadcastReciver() {
}
#Override
public void onReceive(final Context context, final Intent intent) {
final String number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
c=context;
setResultData(null);
setResultData(number);
callActionHandler.postDelayed(runRingingActivity, 1000);
}
Handler callActionHandler = new Handler();
Runnable runRingingActivity = new Runnable(){
#Override
public void run()
{
Intent intentPhoneCall = new Intent(c, OutgoingScreen.class);
intentPhoneCall.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intentPhoneCall.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
c.startActivity(intentPhoneCall);
}
};
}

For outgoing calls I make custom work around and created custom permission of outgoing reciever in manifest.
I had called the activity after a delay using handler.
Hope i will work for you.
Please check the below code.
#Override
public void onReceive(Context context, Intent intent)
{
mcontext = context;
setResultData(null);
dialphonenumber = getResultData();
if dialphonenumber == null)
{
dialphonenumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
}
setResultData(dialphonenumber);
callActionHandler.postDelayed(runRingingActivity, 1000);
}
Handler callActionHandler = new Handler();
Runnable runRingingActivity = new Runnable()
{
#Override
public void run()
{
Intent intentPhoneCall = new Intent(mcontext, OutgoingCallActivity.class);
intentPhoneCall.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intentPhoneCall.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mcontext.startActivity(intentPhoneCall);
}
};
Hope it will work for you.
Let me know if you have any issue.

Related

Custom Context for sticky broadcasts with Robolectric

I would like to test my BroadcastReceiver, which depends on sticky broadcasts, with Robolectric. By default Robolectric does not support sticky broadcasts so I created my custom Context to get sticky broadcasts working like this:
public class MyContext extends MockContext {
public MyContext() {
super();
}
#Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
if(receiver == null) { // A sticky broadcast was requested
Intent request = new Intent();
String action = filter.getAction(0);
if(Intent.ACTION_BATTERY_CHANGED.equals(action)) {
request.putExtra(BatteryManager.EXTRA_PLUGGED, 1);
} else if(Intent.ACTION_HEADSET_PLUG.equals(action)) {
request.putExtra("state", 1);
}
return request;
}
return super.registerReceiver(receiver, filter);
}
}
My problem is that I have to use RuntimeEnvironment.application.getApplicationContext to get a valid Context object (I tried to simply call the constructor of my custom Context but that does not work). So how can I get a valid instance of my custom Context or isn't that possible with robolectric?
EDIT: Here is the code from my test and my BroadcastReceiver:
#Before
public void setup() {
context = RuntimeEnvironment.application.getApplicationContext();
receiver = new MyBroadcastReceiver(); // Create Receiver
}
#After
public void finish() {
context.unregisterReceiver(receiver);
}
#Test
public void validateUsbChargingChange() {
IntentFilter filter = new IntentFilter("android.intent.action.ACTION_POWER_CONNECTED");
context.registerReceiver(receiver, filter);
// Simmulate SocketCharging by sending the corresponding Intent
Intent chargingChange = new Intent("android.intent.action.ACTION_POWER_CONNECTED");
RuntimeEnvironment.application.sendBroadcast(chargingChange);
validatePreferences();
}
BroadcastReceiver:
#Override
public void onReceive(Context context, Intent intent) {
IntentFilter iFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent chargingIntent = appContext.registerReceiver(null, iFilter); // sticky
int pluggedState = chargingIntent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
boolean usbCharge = (pluggedState == BatteryManager.BATTERY_PLUGGED_USB);
if(usbCharge) { /* Write values to preferences */ }
}
you can explicitly sendStickBroadcast in you test class constructor, just like below
#RunWith(RobolectricTestRunner.class)
public class BatterySettingActivityTest {
{
ApplicationProvider.getApplicationContext().sendStickyBroadcast(new Intent(Intent.ACTION_BATTERY_CHANGED).putExtra(BatteryManager.EXTRA_LEVEL, 75).putExtra(BatteryManager.EXTRA_PLUGGED, 0));
}
#Rule
public ActivityScenarioRule<BatterySettingActivity> activityScenarioRule = new ActivityScenarioRule<>(BatterySettingActivity.class);
#Test
public void testStickBroadcast() {
activityScenarioRule.getScenario().onActivity(activity -> {
System.out.println("intentForStickyBroadcast=" + activity.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)));
});
}
}

How to set limit when user enter wrong pattern many time?

Currentlly I am implementing pattern lock application and I want to set limit when user enter wrong pattern many time.Example,If user enter wrong pattern at that time set limit(3 or 4 time limit) and set delay 30 second and after 30 second give permission to enter pattern.
So,If anyone know how i can do this please give idea of that.
Here this my Reciever
public class LockScreenReceiver extends DeviceAdminReceiver {
Context context;
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.i("Action...","..."+action);
//If the screen was just turned on or it just booted up, start your Lock Activity
if(action.equals(Intent.ACTION_SCREEN_OFF) || action.equals(Intent.ACTION_BOOT_COMPLETED))
{
Intent i = new Intent(context, MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
#Override
public void onPasswordFailed(Context ctxt, Intent intent) {
DevicePolicyManager mgr = (DevicePolicyManager) ctxt.getSystemService(Context.DEVICE_POLICY_SERVICE);
int no = mgr.getCurrentFailedPasswordAttempts();
if (no >= 3) {
context.startActivity(new Intent(context,ChangeActivity.class));
}
}
}
Service
public class LockScreenService extends Service {
DeviceAdminReceiver receiver;
#Override
public IBinder onBind(Intent intent) {
return null;
}
// Register for Lockscreen event intents
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
receiver = new LockScreenReceiver();
registerReceiver(receiver, filter);
startForeground();
return START_STICKY;
}
// Run service in foreground so it is less likely to be killed by system
private void startForeground() {
Notification notification = new NotificationCompat.Builder(this)
.setContentTitle(getResources().getString(R.string.app_name))
.setTicker(getResources().getString(R.string.app_name))
.setContentText("Running")
.setContentIntent(null)
.setOngoing(true)
.build();
startForeground(9999,notification);
}
#Override
#SuppressWarnings("deprecation")
public void onCreate() {
KeyguardManager.KeyguardLock key;
KeyguardManager km = (KeyguardManager)getSystemService(KEYGUARD_SERVICE);
//This is deprecated, but it is a simple way to disable the lockscreen in code
key = km.newKeyguardLock("IN");
key.disableKeyguard();
//Start listening for the Screen On, Screen Off, and Boot completed actions
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_BOOT_COMPLETED);
//Set up a receiver to listen for the Intents in this Service
receiver = new LockScreenReceiver();
registerReceiver(receiver, filter);
super.onCreate();
}
#Override
public void onDestroy() {
unregisterReceiver(receiver);
super.onDestroy();
}
}
Activity
public class MainActivity extends ActionBarActivity {
private Lock9View lock9View;
private static String MY_PREFS_NAME = "PatternLock";
private static String PATTERN_KEY;
SharedPreferences prefs;
Button btnChange;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
startService(new Intent(MainActivity.this, LockScreenService.class));
makeFullScreen();
setContentView(R.layout.activity_main);
btnChange = (Button)findViewById(R.id.btnChange);
btnChange.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent in = new Intent(MainActivity.this,ChangeActivity.class);
startActivity(in);
}
});
prefs = getSharedPreferences(MY_PREFS_NAME, MODE_PRIVATE);
lock9View = (Lock9View) findViewById(R.id.lock_9_view);
lock9View.setCallBack(new Lock9View.CallBack() {
#Override
public void onFinish(String password) {
PATTERN_KEY = prefs.getString("Pattern", "invalid");
if (PATTERN_KEY.equals("invalid")) {
Toast.makeText(MainActivity.this, "Options --> Create new Pattern", Toast.LENGTH_LONG).show();
} else {
if (password.equals(PATTERN_KEY)) {
Intent startMain = new Intent(Intent.ACTION_MAIN);
startMain.addCategory(Intent.CATEGORY_HOME);
startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(startMain);
}else{
Context context = getApplicationContext();
// Create layout inflator object to inflate toast.xml file
LayoutInflater inflater = getLayoutInflater();
// Call toast.xml file for toast layout
View toastRoot = inflater.inflate(R.layout.layout_toast3, null);
Toast toast = new Toast(context);
// Set layout to toast
toast.setView(toastRoot);
toast.setGravity(Gravity.HORIZONTAL_GRAVITY_MASK | Gravity.BOTTOM,
0, 0);
toast.setDuration(Toast.LENGTH_LONG);
toast.show();
}
}
}
});
}
private void makeFullScreen() {
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
if(Build.VERSION.SDK_INT < 19) { //View.SYSTEM_UI_FLAG_IMMERSIVE is only on API 19+
this.getWindow().getDecorView()
.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
} else {
this.getWindow().getDecorView()
.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE);
}
}
#Override
public void onBackPressed() {
return; //Do nothing!
}
public void unlockScreen(View view) {
//Instead of using finish(), this totally destroys the process
android.os.Process.killProcess(android.os.Process.myPid());
}
}
So,How i can achieve this...
Have a int field like failedCounter and increment it each time user inputs invalid patterns check if reached the limit then disable the input interface and have a handler to reset the value after the time delay.
int failedCount = 0;
final static int LIMIT = 5; //set your limit here
private void invalidPattern() {
if (++failedCount == LIMIT) {
//disable the input
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
//reset the failed count
faildCount = 0;
//Enable the input interface here
}
}, 30000); // 30Sec delay
}
}
Use this two methods -
ScheduledThreadPoolExecutor c1;
private void IncorrectCallCounter() {
if (failedCounter>=0)
{
c1.shutdownNow();
LockScreenFor30Second();
}else
{
if (c1!=null)
c1.shutdownNow();
}
c1 = new ScheduledThreadPoolExecutor(1);
c1.schedule(new Runnable() {
#Override
public void run() {
failedCounter=0;
c1.shutdownNow();
}
}, 15, TimeUnit.SECONDS);
}
ScheduledThreadPoolExecutor c2;
private void LockScreenFor30Second() {
//Lock Screen Here
c2 = new ScheduledThreadPoolExecutor(1);
c2.schedule(new Runnable() {
#Override
public void run() {
//Unlock Screen Here
c2.shutdownNow();
}
}, 30, TimeUnit.SECONDS);
}
Declare failedCounter globally
private int failedCounter=0;
And call this method when you detect wrong pattern -
failedCounter=failedCounter+1;
IncorrectCallCounter();
If user enter wrong pattern 4 times in 15 seconds then this will call LockScreenFor30Second method. and inside LockScreenFor30Second add your code.

android, how to pop a dialog from some non ui module

How to open a dialog when from some non ui module when there might be different activity in display?
Let's say there could be multiple activities stacked, Activity_A, Activity_B, Activity_C. The common service module may running on non ui thread and running into case need to popup a dialog.
It could be done by passing the handler from all active activities to the module and post message to let the activity to pop dialog.
But that need some management in terms of passing the handler and determine who is on top of the view.
Is there a better way?
You can show dailog from non-ui thread using BroadcastReceiver
Understand Flow:
public class Sample extends Activity {
BroadcastReceiver updateUIReciver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
updateUIReciver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//UI update here
ShowFailedDailog(null, getString(R.string.mms_sending_service_failed_txt));
}
};
IntentFilter filter = new IntentFilter();
filter.addAction("update.from.nonui");
registerReceiver(updateUIReciver, filter);
}
void ShowFailedDailog(String title, String message) {
final Dialog dialog = new Dialog(context);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.import_backup_popup);
TextView Save = (TextView) dialog.findViewById(R.id.tOk);
Save.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dialog.dismiss();
}
});
TextView cancel = (TextView) dialog.findViewById(R.id.tCancel);
cancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dialog.dismiss();
}
});
dialog.show();
}
}
NON UI:
public class NonUiSerive extends Service {
Context context;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null) {
// ..... your tasks
if (SomeFlagUpdateTrue) {
Intent local = new Intent();
local.setAction("mms.seding.failed");
context.sendBroadcast(local);
}
}
this.stopSelf();
return 0;
}
}
Similarly register receiver all your three class it will update in every activity not restricted to one.
After try out I think the simplest is to use application context to open a activity for dialog. This way it would not care who's the current activity on top.
Intent dialogIntent = new Intent(applicationCotext, DialogActivity.class);
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
applicationCotext.startActivity(dialogIntent);

How to refresh a ListView from a BroadcastReceiver?

If I call notifyDataSetChanged() on the custom adapter associated to my ListView, all the views should refresh themself (getView() will be called).
Now I have a BroadcastReceiver that is listening to an event. When the event fires, the ListView must be refreshed. How can I achieve this?
Thanks!
If you refresh listview from receiver you'll have code like this:
BroadcastReceiver br;
public final static String BROADCAST_ACTION = "BROADCAST_ACTION";
br = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
//code refreshing...
}
};
IntentFilter intFilt = new IntentFilter(BROADCAST_ACTION);
registerReceiver(br, intFilt);
And you call it with code:
Intent intent = new Intent(BROADCAST_ACTION);
sendBroadcast(intent);
If you need the refresh to be another action you just need to add (after action):
Intent intent = new Intent(BROADCAST_ACTION);
sendBroadcast(intent);
As requested, please see the sample code below:
public interface OnDataUpdateListener {
void onDataAvailable(ArrayList<String> newDataList);
}
public class MyTestReceiver extends BroadcastReceiver {
public static final String DATA_LIST = "DATA_LIST";
private OnDataUpdateListener mDataUpdateListener = null;
public MyTestReceiver(OnDataUpdateListener dataUpdateListener) {
mDataUpdateListener = dataUpdateListener;
}
#Override
public void onReceive(Context ctx, Intent intent) {
// assuming data is available in the delivered intent
ArrayList<String> dataList = intent.getSerializableExtra(DATA_LIST);
if (null != mDataUpdateListener) {
mDataUpdateListener.onDataAvailable(dataList);
}
}
}
public class MyActivity extends FragmentActivity implements OnDataUpdateListener {
public static final String ACTION_DATA_UPDATE_READY = "ACTION_DATA_UPDATE_READY";
private MyTestReceiver mTestReceiver = null;
private <SomeAdapterClass> mAdapter = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
// other required initialization
mTestReceiver = new MyTestReceiver(this);
}
#Override
public void onResume() {
super.onResume();
if (null != mTestReceiver) {
registerReceiver(mTestReceiver, new IntentFilter(ACTION_DATA_UPDATE_READY));
}
}
void onDataAvailable(ArrayList<String> newDataList) {
// assuming you want to replace existing data and not willing to append to existing dataset
mAdapter.clear();
mAdapter.addAll(newDataList);
mAdapter.notifyDataSetChanged();
}
}
In the code where your data is updated, fire off a message signalling that data has been changed...
(You will need access to either the Activity or the Application context to do this)
Intent intent = new Intent("ListViewDataUpdated");
LocalBroadcastManager.getInstance(context.sendBroadcast(intent));
Then just catch the catch the message using the following code in your activity, and tell your ListAdapter to update...
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
myListAdapter.notifyDataSetChanged();
}
};
#Override
public void onResume(){
super.onResume();
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver, new IntentFilter("ListViewDataUpdated"));
myListAdapter.notifyDataSetChanged();//in case our data was updated while this activity was paused
}
#Override
protected void onPause() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
super.onPause();
}
Credit: adapted from Vogella
LocalBroadcastManager.getInstance(context.sendBroadcast(intent));
change to
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
I might be wrong but it works for me...

infinitly execution while send broadcast

I want to use
context.sendBroadcast(intent, receiverPermission);
in my application
but I don't know to pass receiverPermission parameter in function and also how to set in manifest file
please any body help me
I want to show you my source code
public class LocationReceiver extends BroadcastReceiver {
public static final String BROADCAST_ACTION = "LOCATION_CHANGE";
#Override
public void onReceive(Context context, Intent intent) {
intent.setAction(BROADCAST_ACTION);
Bundle b = intent.getExtras();
Location loc = (Location)b.get(android.location.LocationManager.KEY_LOCATION_CHANGED);
Logger.debug("Loc:"+loc);
if(loc != null){
doBroadCast(context,intent,loc);
}
}
public void doBroadCast(final Context context,final Intent i1,final Location loc){
Handler h = new Handler();
h.post(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
Logger.debug("LocationReceiver->sendLocation update broadcast");
i1.putExtra("Latitude", loc.getLatitude());
i1.putExtra("Longitude", loc.getLongitude());
context.sendBroadcast(i1,null);
}
});
}
}
and on activity I have write
#Override
protected void onResume() {
registerReceiver(broadcastReceiver, new IntentFilter(LocationReceiver.BROADCAST_ACTION));
}
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
UpdateUI(intent);
}
};
private void UpdateUI(Intent i){
Double Latitude = i.getDoubleExtra("Latitude",0);
Double Longitude = i.getDoubleExtra("Longitude",0);
showMap(Latitude, Longitude);
}
Now my problem is when it sendbroadcast it execute infinitly doBroadcast function(), please help me to come out.
Check after intent.setAction(BROADCAST_ACTION); that the action is really set to BROADCAST_ACTION
Check if you have registered this BroadcastReceiver with the action BROADCAST_ACTION in the <intent-filter> ( if it is, then that s why you have that infinite loop)

Categories

Resources