Why does android device administration not work properly - android

I am setting two buttons on the screen. Whenever I press the first button it will disable the camera. ( as an admin )
I have set manifest ;
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.firstapplication.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- This is where we register our receiver -->
<receiver
android:name=".DemoDeviceAdminReceiver"
android:permission="android.permission.BIND_DEVICE_ADMIN" >
<intent-filter>
<!-- This action is required -->
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
</intent-filter>
<!-- This is required this receiver to become device admin component. -->
<meta-data
android:name="android.app.device_admin"
android:resource="#xml/device_admin_sample" />
</receiver>
</application>
I have wrote code as ;
public class MainActivity extends Activity {
static final int ACTIVATION_REQUEST = 47; // identifies our request id
DevicePolicyManager devicePolicyManager;
ComponentName demoDeviceAdmin;
#Override
protected void onCreate(Bundle savedInstanceState) {
// ...
// Initialize Device Policy Manager service and our receiver class
devicePolicyManager = (DevicePolicyManager)getSystemService(Context.DEVICE_POLICY_SERVICE);
demoDeviceAdmin = new ComponentName(this, DemoDeviceAdminReceiver.class);
}
/* begin, camera management block */
static boolean click = false ;
private OnClickListener setCamera = new OnClickListener() {
public void onClick(View v) {
if ( click == false ) {
startCamera();
click = true ;
}
else {
stopCamera();
click = false ;
}
activate () ; // activate device policy manager
}
};
private void startCamera(){
if(getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
camera.unlock();
} else {
;
}
}
#SuppressLint("NewApi") private void stopCamera(){
devicePolicyManager. setCameraDisabled(demoDeviceAdmin, true);
}
/* end, camera management block */
private OnClickListener closeApplication = new OnClickListener() {
public void onClick(View v) {
finish ();
}
};
void initializeDPM ( ) {
if (!devicePolicyManager.isAdminActive(demoDeviceAdmin)) {
Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
demoDeviceAdmin);
intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,
"Additional text explaining why this needs to be added.");
startActivityForResult(intent, ACTIVATION_REQUEST);
} else {
devicePolicyManager.lockNow();
}
}
public void activate ( ) {
// Activate device administration
Intent intent = new Intent(
DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
demoDeviceAdmin);
intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,
"told me to do this");
startActivityForResult(intent, ACTIVATION_REQUEST);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case ACTIVATION_REQUEST:
if (resultCode == Activity.RESULT_OK) {
// Has become the device administrator.
} else {
//Canceled or failed.
}
return;
}
super.onActivityResult(requestCode, resultCode, data);
}
}
My admin class
public class DemoDeviceAdminReceiver extends DeviceAdminReceiver{
#Override
public void onEnabled(Context context, Intent intent) {
super.onEnabled(context, intent);
}
#Override
public void onDisabled(Context context, Intent intent) {
super.onDisabled(context, intent);
}
}
my device_admin_sample is;
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<device-admin xmlns:android="http://schemas.android.com/apk/res/android">
<uses-policies>
<limit-password />
<watch-login />
<reset-password />
<force-lock />
<wipe-data />
<expire-password />
<encrypted-storage />
<disable-camera />
</uses-policies>
</device-admin>
</LinearLayout>
Why I could not close the camera as an admin ?

Related

Android Phone Call UI - Change

How do I change the phone call user interface? Like I have my own dialer layout and contacts layout but how do I change the calling UI. So, when the call is going on, can I remove the speaker button for example?
Here is my dialer scene that I have created: Dialer Picture
But I don't know how to edit this screen: Calling Picture
EDIT: I have already built the UI, I just can not get it to show during call!
Here is the code for as a simpler version:
public class MainActivity extends Activity {
private Button callBtn;
private Button dialBtn;
private EditText number;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
number = (EditText) findViewById(R.id.phoneNumber);
callBtn = (Button) findViewById(R.id.call);
dialBtn = (Button) findViewById(R.id.dial);
// add PhoneStateListener for monitoring
MyPhoneListener phoneListener = new MyPhoneListener();
TelephonyManager telephonyManager =
(TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
// receive notifications of telephony state changes
telephonyManager.listen(phoneListener,PhoneStateListener.LISTEN_CALL_STATE);
callBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
try {
// set the data
String uri = "tel:"+number.getText().toString();
Intent callIntent = new Intent(Intent.ACTION_CALL, Uri.parse(uri));
startActivity(callIntent);
}catch(Exception e) {
Toast.makeText(getApplicationContext(),"Your call has failed...",
Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
});
dialBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
try {
String uri = "tel:"+number.getText().toString();
Intent dialIntent = new Intent(Intent.ACTION_DIAL, Uri.parse(uri));
startActivity(dialIntent);
}catch(Exception e) {
Toast.makeText(getApplicationContext(),"Your call has failed...",
Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
});
}
private class MyPhoneListener extends PhoneStateListener {
private boolean onCall = false;
#Override
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
// phone ringing...
Toast.makeText(MainActivity.this, incomingNumber + " calls you",
Toast.LENGTH_LONG).show();
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
// one call exists that is dialing, active, or on hold
Toast.makeText(MainActivity.this, "on call...",
Toast.LENGTH_LONG).show();
//because user answers the incoming call
onCall = true;
break;
case TelephonyManager.CALL_STATE_IDLE:
// in initialization of the class and at the end of phone call
// detect flag from CALL_STATE_OFFHOOK
if (onCall == true) {
Toast.makeText(MainActivity.this, "restart app after call",
Toast.LENGTH_LONG).show();
// restart our application
Intent restart = getBaseContext().getPackageManager().
getLaunchIntentForPackage(getBaseContext().getPackageName());
restart.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(restart);
onCall = false;
}
break;
default:
break;
}
}
}
}
Thanks!
Add calling permission in manifest
<uses-permission android:name="android.permission.CALL_PHONE" />
Then need to check if call button pressed. for that use below intent filter
<intent-filter>
<action android:name="android.intent.action.CALL_BUTTON" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
and when firing the UI
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.DIAL" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="tel" />
</intent-filter>
that means your calling activity in manifest will be something like this
<activity
android:name="com.example.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<!-- open activity when establishing a call -->
<intent-filter>
<action android:name="android.intent.action.CALL_PRIVILEGED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="tel" />
</intent-filter>
</activity>
since API 23 it is possible, see Replacing default Phone app on Android 6 and 7 with InCallService arekolek.
Kotlin version: Simple Phone
Java version: Simple Phone Dialer
EDIT
As recommended, Below is the simplest java version.
Below is shown the Manifest with the intent-filter needed.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.aliton.customphonecall">
<uses-permission android:name="android.permission.CALL_PHONE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".DialerActivity" >
<intent-filter>
<!-- Handle links from other applications -->
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.DIAL" />
<!-- Populate the system chooser -->
<category android:name="android.intent.category.DEFAULT" />
<!-- Handle links in browsers -->
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="tel" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.DIAL" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<service
android:name=".CallService"
android:permission="android.permission.BIND_INCALL_SERVICE">
<meta-data
android:name="android.telecom.IN_CALL_SERVICE_UI"
android:value="true" />
<intent-filter>
<action android:name="android.telecom.InCallService" />
</intent-filter>
</service>
<activity android:name=".CallActivity"></activity>
</application>
</manifest>
The MainActivity just have a Button with an Intent redirecting to the DialerActivity.
Below is the DialerActivity. In this Activity, you will set your app as default in order to make call with your UI.
public class DialerActivity extends AppCompatActivity {
private static final int REQUEST_CALL_PHONE = 10;
EditText phoneNumber;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dialer);
phoneNumber = (EditText) findViewById(R.id.etNumber);
Button bCall = (Button) findViewById(R.id.btnCall);
offerReplacingDefaultDialer();
bCall.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
makeCall();
}
});
}
private void makeCall() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) == PackageManager.PERMISSION_GRANTED) {
Uri uri = Uri.parse("tel:"+phoneNumber.getText().toString().trim());
Intent Call = new Intent(Intent.ACTION_CALL, uri);
//Toast.makeText(this, "Entered makeCall()", Toast.LENGTH_SHORT).show();
Log.i("debinf Dialer", "Entered makeCall()");
startActivity(Call);
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CALL_PHONE}, REQUEST_CALL_PHONE);
}
}
private void offerReplacingDefaultDialer() {
if (getSystemService(TelecomManager.class).getDefaultDialerPackage() != getPackageName()) {
Intent ChangeDialer = new Intent(TelecomManager.ACTION_CHANGE_DEFAULT_DIALER);
ChangeDialer.putExtra(TelecomManager.EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME, getPackageName());
startActivity(ChangeDialer);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CALL_PHONE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
makeCall();
} else {
Toast.makeText(this, "calling permission denied", Toast.LENGTH_LONG).show();
}
//return;
}
}
}
Here is how InCallService is implemented to manage the calls.
public class CallService extends InCallService {
OngoingCallObject ongoingCallObject;
#Override
public void onCallAdded(Call call) {
super.onCallAdded(call);
new OngoingCallObject().setCall(call);
//Intent CallAct = new Intent(this, CallActivity.class);
//startActivity(CallAct);
CallActivity.start(this, call);
}
#Override
public void onCallRemoved(Call call) {
super.onCallRemoved(call);
new OngoingCallObject().setCall(null);
}
}
Here is how the Object is implemented.
public class OngoingCallObject {
private static Call call;
private Object callback = new Callback() {
#Override
public void onStateChanged(Call call, int state) {
super.onStateChanged(call, state);
Log.i("debinf OngoingObj", "state is "+state);
}
};
public void setCall(Call call) {
if (this.call != null) {
this.call.unregisterCallback((Call.Callback)callback);
}
if (call != null) {
call.registerCallback((Call.Callback)callback);
Log.i("debinf OngoingObj", "call.getState() is "+call.getState());
}
this.call = call;
}
public void answer() {
//assert this.call != null;
if (this.call != null) {
this.call.answer(VideoProfile.STATE_AUDIO_ONLY);
}
}
public void hangup() {
//assert this.call != null;
if (this.call != null) {
this.call.disconnect();
}
}
}
And finally, the CallActivity where you launch your UI.
public class CallActivity extends AppCompatActivity {
TextView callInfo;
Button answer, hangup;
private String number;
private OngoingCallObject ongoingCall;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_call);
ongoingCall = new OngoingCallObject();
answer = (Button) findViewById(R.id.answer);
hangup = (Button) findViewById(R.id.hangup);
callInfo = (TextView) findViewById(R.id.callInfo);
number = Objects.requireNonNull(getIntent().getData().getSchemeSpecificPart());
callInfo.setText("Calling number : "+number);
answer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Toast.makeText(CallActivity.this, "Answer button", Toast.LENGTH_SHORT).show();
ongoingCall.answer();
}
});
hangup.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ongoingCall.hangup();
}
});
}
public static void start(Context context, Call call) {
Intent intent = new Intent(context, CallActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setData(call.getDetails().getHandle());
context.startActivity(intent);
}
}
Here is the xml for DialerActivity: activity_dialer.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".DialerActivity">
<EditText
android:id="#+id/etNumber"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Tel number"/>
<Button
android:id="#+id/btnCall"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="CallActivity"
android:layout_below="#+id/etNumber" />
</RelativeLayout>
Here is the xml for CallActivity: activity_call.xml
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".CallActivity">
<TextView
android:id="#+id/callInfo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.3"
tools:text="Hello World!" />
<Button
android:id="#+id/answer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Answer"
app:layout_constraintBaseline_toBaselineOf="#+id/hangup"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/hangup" />
<Button
android:id="#+id/hangup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hang up"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/answer"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/callInfo" />
</android.support.constraint.ConstraintLayout>
I hope it helps!
EDIT:
Actually the api 23 was release, check this answer. Keep in mind that some devices may not support this functionality.
PREVIEW:
The actual calling view (what you see during calls) CAN`T be changed.
To be more specific, some parts of android CAN NOT be overridden,
android has his core and as developers we have limited access to this
core. In your case you can override dialer but you can`t
override actual phone call view.
You can't do anything about this, until android team decided to share
this core feature with us (developers).
Build your own Dialer UI. Check this out.
You will need an Activity to handle the intent and then displaying a custom UI is your business.

start VPNService from inside android widget

I'm starting a VPNService in my activity and I want to start some thread after the service is started. this is how I start the service:
Intent intent = VpnService.prepare(getActivity());
if (intent != null) {
startActivityForResult(intent, 123);
else {
onActivityResult(123, Activity.RESULT_OK, null);
}
And in onActivityResult I start my thread
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 123) {
// Start some thread
}
}
Now I want to be able to do all this from my app's widget. It seems I can only use startActivity from inside a widget, and this is the right way to use VPNService. is there any way I can achieve this from my widget? some callback from startActivity perhaps?
Don't have too much experience with widgets, but would suggest to go that way:
Create dummy activity only for that startActivityForResult() call (please note that I'm using specific theme for that activity #android:style/Theme.NoDisplay);
Start that dummy activity from the widget;
Store result in activity using SharedPreferences and send broadcast for widget;
Below is example project:
AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.alexstarc.testapp"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="19"
android:targetSdkVersion="19"/>
<application
android:label="#string/app_name"
android:icon="#drawable/ic_launcher"
android:allowBackup="true">
<activity
android:name=".MyActivity"
android:label="#string/app_name"
android:theme="#android:style/Theme.NoDisplay">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<receiver android:name="TestWidgetProvider"
android:exported="false">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<!-- Custom actions -->
<action android:name="com.alexstarc.testapp.ACTION_BTN" />
<action android:name="com.alexstarc.testapp.ACTION_VPN_RESULT" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="#xml/appwidget_info" />
</receiver>
</application>
</manifest>
appwidget_info.xml:
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="180dp"
android:minHeight="40dp"
android:updatePeriodMillis="0"
android:initialLayout="#layout/appwidget"
android:resizeMode="horizontal|vertical"
android:widgetCategory="home_screen"
android:previewImage="#drawable/widget_preview"/>
appwidget.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="4dp"
android:background="#drawable/appwidget_bg">
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/launchVPN"
android:src="#android:drawable/ic_media_play"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/resultText"
style="#android:style/TextAppearance.DeviceDefault.Medium.Inverse"
android:layout_toRightOf="#id/launchVPN"
android:text="#string/test_text"
android:gravity="bottom"/>
</RelativeLayout>
MyActivity.java:
public class MyActivity extends Activity {
private static final int VPN_LAUNCH_CODE = 123;
public static String SHARED_PREFS_NAME = "shared_prefs";
public static String RESULT_VPN = "vpn_launch_result";
public static String ACTION_VPN_RESULT = "com.alexstarc.testapp.ACTION_VPN_RESULT";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = VpnService.prepare(MyActivity.this);
if (intent != null) {
startActivityForResult(intent, VPN_LAUNCH_CODE);
} else {
onActivityResult(VPN_LAUNCH_CODE, Activity.RESULT_OK, null);
}
}
#Override
protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 123) {
getSharedPreferences(SHARED_PREFS_NAME, MODE_MULTI_PROCESS).edit().putString(RESULT_VPN, "VPN Result is " + resultCode).commit();
final Intent resultIntent = new Intent(ACTION_VPN_RESULT);
sendBroadcast(resultIntent);
finish();
}
}
}
TestWidgetProvider.java:
public final class TestWidgetProvider extends AppWidgetProvider {
private static final String ACTION_START_BTN = "com.alexstarc.testapp.ACTION_BTN";
// TODO: Use Shared Prefs for this
private static int sWidgetId = 0;
private static boolean sVPNDone = false;
#Override
public void onUpdate(final Context context, final AppWidgetManager appWidgetManager, final int[] appWidgetIds) {
for (int widgetId : appWidgetIds) {
updateWidget(context, appWidgetManager, widgetId);
}
sWidgetId = appWidgetIds[0];
}
/**
* Updates single App Widget
*
* #param context {#link android.content.Context}
* #param appWidgetManager {#link android.appwidget.AppWidgetManager}
* #param widgetId of current widget
*/
private static void updateWidget(final Context context, final AppWidgetManager appWidgetManager, final int widgetId) {
final ArrayList<Integer> widgets = new ArrayList<Integer>();
final Intent btnClickIntent = new Intent(context, TestWidgetProvider.class);
btnClickIntent.setAction(ACTION_START_BTN);
final PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, btnClickIntent, 0);
// Get the layout for the App Widget and attach an on-click listener
// to the button
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget);
views.setOnClickPendingIntent(R.id.launchVPN, pendingIntent);
// Update from shared preferences after activity was launched
if (sVPNDone) {
views.setTextViewText(R.id.resultText,
context.getSharedPreferences(MyActivity.SHARED_PREFS_NAME, Context.MODE_PRIVATE).getString(MyActivity.RESULT_VPN, "No result"));
}
appWidgetManager.updateAppWidget(widgetId, views);
}
#Override
public void onReceive(final Context context, final Intent intent) {
final String action = intent.getAction();
if (ACTION_START_BTN.equals(action)) {
// Start listening service
final Intent vpnActivityIntent = new Intent(context, MyActivity.class);
vpnActivityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(vpnActivityIntent);
} else if (MyActivity.ACTION_VPN_RESULT.equals(action)) {
sVPNDone = true;
updateWidget(context, AppWidgetManager.getInstance(context), sWidgetId);
} else {
super.onReceive(context, intent);
}
}
}
You want to use implicit intents for this kind of thing. You may even package the widget in another application than the service using this scheme if you only make sure to sign the packages with the same key.
AndroidManifest.xml:
<!-- Specify a new kind of permission based on your signature -->
<permission
android:name="com.example.VPN"
android:protectionLevel="signature" />
<!-- This application uses this new permission -->
<uses-permission android:name="com.example.VPN" />
<!-- Let the VPN service use the permission and listen for an implicit intent -->
<service
android:name="com.example.VpnService"
android:exported="true"
android:permission="com.example.VPN" >
<intent-filter>
<action android:name="com.example.intent.action.START_VPN" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>
VpnService:
public static final String ACTION_START_VPN = "com.example.intent.action.START_VPN";
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
if (null != intent && ACTION_START_VPN.equals(intent.getAction()) {
// Do your stuff here
}
}
In your widget:
Intent intent = new Intent(VpnService.ACTION_START_VPN);
context.startService(intent);

How to Lock/Unlock screen programmatically?

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

How to remotely invoke a device admin policy?

What I want to do, have a [BroadcastReceiver] that listens to any incoming SMS, that when the incoming SMS has a certain keyword, it will pass over to device admin and invoke the required policy.
I have created a BroadcastReceiver that listen to SMS and pop a toast, and it works fine. Then I created a device admin app following this guide: http://marakana.com/s/post/1291/android_device_policy_administration_tutorial, and its working as it should. But when I include that SMS receiver together with device admin, it crashes whenever an sms comes in. Also, I'm unable to pass the string that I want to use from the SMS receiver to my device admin app in order to invoke the required policy.
This is my device admin
public class AppPolicyActivity extends Activity implements OnCheckedChangeListener {
static final int ACTIVATION_REQUEST = 47;
DevicePolicyManager mDPM;
ComponentName appPolicy;
ToggleButton toggleBtn;
#Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity_layout);
toggleBtn = (ToggleButton) findViewById(R.id.toggleBtn);
toggleBtn.setOnCheckedChangeListener(this);
mDPM = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
appPolicy = new ComponentName(this, AppPolicyReceiver.class);
// The commented code below made my app crash during installation
/* Intent intent;
try {
if (getIntent() != null) {
intent = getIntent();
String keyword = intent.getStringExtra("keyword");
if (keyword.equals("LOCK")) {
receivedSMS(keyword);
} else if (keyword.equals("WIPE")) {
receivedSMS(keyword);
}
keyword = "";
intent = null;
finish();
}
} catch (Exception e) {} */
}
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// TODO Auto-generated method stub
if (isChecked) {
Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, appPolicy);
intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "Activate the application to use its features");
startActivityForResult(intent, ACTIVATION_REQUEST);
} else {
mDPM.removeActiveAdmin(appPolicy);
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
switch (requestCode) {
case ACTIVATION_REQUEST:
if (resultCode == Activity.RESULT_OK) {
toggleBtn.setChecked(true);
} else {
toggleBtn.setChecked(false);
}
return;
}
super.onActivityResult(requestCode, resultCode, data);
}
public void receivedSMS(String keyword) {
// Lock
if (keyword.equals("LOCK")) {
mDPM.lockNow();
}
// Wipe/delete
else if (keyword.equals("WIPE")) {
mDPM.wipeData(ACTIVATION_REQUEST);
}
}
}
This is the device admin receiver class
public class AppPolicyReceiver extends DeviceAdminReceiver {
#Override
public void onDisabled(Context context, Intent intent) {
// TODO Auto-generated method stub
Toast.makeText(context, R.string.disabletext, Toast.LENGTH_SHORT).show();
super.onDisabled(context, intent);
}
#Override
public void onEnabled(Context context, Intent intent) {
// TODO Auto-generated method stub
Toast.makeText(context, R.string.enabletext, Toast.LENGTH_SHORT).show();
super.onEnabled(context, intent);
}
}
this is my manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.fyp.mobilesecurity"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="15" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<uses-permission android:name="android.permission.SEND_SMS"/>
<application android:label="#string/app_name"
android:icon="#drawable/ic_launcher"
android:theme="#style/AppTheme">
<activity android:name="AppPolicyActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- appPolicyReceiver -->
<receiver android:permission="android.permission.BIND_DEVICE_ADMIN" android:name="AppPolicyReceiver">
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED"/>
<action android:name="android.app.action.DEVICE_ADMIN_DISABLED"/>
</intent-filter>
<meta-data android:resource="#xml/app_admin"
android:name="android.app.device_admin"/>
</receiver>
<!-- SMSReceiver -->
<receiver android:enabled="true" android:name="SMSReceiver" android:exported="true">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
</application>
</manifest>
and this is from log, as you can see my receiver is not even started.
11-17 21:06:52.300: E/AndroidRuntime(375): java.lang.RuntimeException: Unable to start receiver com.fyp.mobilesecurity.SMSReceiver: java.lang.NullPointerException
I just realize that its returning an exception, so I enclosed my receiver in try/catch block, and now its working fine.
You'll need to see what's causing the NullPointerException in SMSReceiver. The stacktrace will have the line number.

Android Device Admin not working

I am new in android and i would like to lock the phone. So I Read through Device Admin documentation. and have my code looking like this. But it doesnt seem to notice it on my manifest suggests if i have it defined in it which i do
my manifest.xml
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".MainLauncher"android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".Controller"android:label="#string/app_name">
</activity>
<activity android:name=".DeviceAdminSample$Controller"android:label="#string/activity_sample_device_admin">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.SAMPLE_CODE" />
</intent-filter>
</activity>
<receiver android:name=".DeviceAdminSample"android:label="#string/sample_device_admin"android:description="#string/sample_device_admin_description"android:permission="android.permission.BIND_DEVICE_ADMIN">
<meta-data android:name="android.app.device_admin"android:resource="#xml/device_admin_sample" />
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
</intent-filter>
</receiver>
</application>
<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
<uses-permission android:name="android.permission.WAKE_LOCK" />
</manifest>
My Code
public class DeviceAdminSample extends DeviceAdminReceiver {
public static class Controller extends Activity {
static final int RESULT_ENABLE = 1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mDPM = (DevicePolicyManager)getSystemService(Context.DEVICE_POLICY_SERVICE);
mAM = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
mDeviceAdminSample = new ComponentName(Controller.this, DeviceAdminSample.class);
mEnableButton = (Button)this.findViewById(R.id.button1);
mEnableButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
mDeviceAdminSample);
intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,
"Additional text explaining why this needs to be added.");
startActivityForResult(intent, RESULT_ENABLE);
}
});
mDisableButton = (Button)this.findViewById(R.id.button2);
mDisableButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
mDPM.removeActiveAdmin(mDeviceAdminSample);
updateButtonStates();
}
});
mForceLockButton = (Button)this.findViewById(R.id.button3);
mForceLockButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Log.i(" In","In the forc lock button");
if (mAM.isUserAMonkey()) {
AlertDialog.Builder builder = new AlertDialog.Builder(Controller.this);
builder.setMessage("You can't lock my screen because you are a monkey!");
builder.setPositiveButton("I admit defeat", null);
builder.show();
return;
}
boolean active = mDPM.isAdminActive(mDeviceAdminSample);
if (active) {
v mDPM.lockNow();
}
}
});
}
void updateButtonStates() {
boolean active = mDPM.isAdminActive(mDeviceAdminSample);
if (active) {
mForceLockButton.setEnabled(true);
} else {
mForceLockButton.setEnabled(false);
}
}
}
}
My Other Activity
package com.examples;
public class MainLauncher extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mainlauncher);
Button btnLock = (Button)this.findViewById(R.id.button22);
btnLock.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
KeyguardManager keyguardManager = (KeyguardManager)getSystemService(Activity.KEYGUARD_SERVICE);
KeyguardLock lock = keyguardManager.newKeyguardLock(KEYGUARD_SERVICE);
lock.reenableKeyguard();
}
});
Button btnDevice = (Button)this.findViewById(R.id.button11);
btnDevice.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
try{
Intent openScreen = new Intent();
openScreen.setClass(MainLauncher.this, DeviceAdminSample.class);
startActivity(openScreen);
}
catch(Exception e)
{Log.i("DeviceAdmin button",String.valueOf(e));}
}
});
}
}
Have you added a resource under "xml" folder called "device_admin_sample.xml"? It will have permission required for doing a "force lock" for Device administrator to work.

Categories

Resources