I am trying to set the lock task packages but IsAdminActive is returning false.
To set the device owner and active admin I used the command dpm set-device-owner PinningTest.PinningTest/.AdminReceiverTest from the adb shell. This completed successfully.
My MainActivity:
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
DevicePolicyManager devicePolicyManager = (DevicePolicyManager)GetSystemService(Context.DevicePolicyService);
ComponentName testDeviceAdmin = new ComponentName(this, Java.Lang.Class.FromType(typeof(AdminReceiverTest)).Name);
if (devicePolicyManager.IsAdminActive(testDeviceAdmin))
{
devicePolicyManager.SetLockTaskPackages(testDeviceAdmin, new string[] { PackageName });
}
}
My AndroidManifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="PinningTest.PinningTest"
android:versionCode="1" android:versionName="1.0"
android:installLocation="auto">
<uses-sdk android:minSdkVersion="21" />
<uses-permission android:name="android.permission.BIND_DEVICE_ADMIN" />
<application android:label="PinningTest">
<receiver android:name=".AdminReceiverTest"
android:label="#string/ApplicationName"
android:description="#string/ApplicationName"
android:permission="android.permission.BIND_DEVICE_ADMIN">
<meta-data android:name="android.app.device_admin" android:resource="#xml/device_admin" />
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
</intent-filter>
</receiver>
</application>
</manifest>
AdminReceiverTest.cs:
namespace PinningTest
{
class AdminReceiverTest : DeviceAdminReceiver
{
}
}
I was following the tutorial here and have also looked at various others but I haven't been able to find a complete Xamarin example.
Any help is appreciated.
Many thanks.
I originally had the same issue, but I've just got this working by using the following
[BroadcastReceiver(Name = "com.sceneskope.survey.DeviceAdminReceiver", Enabled = true, Exported = true, Permission = "android.permission.BIND_DEVICE_ADMIN")]
[MetaData("android.app.device_admin", Resource = "#xml/device_admin_receiver")]
[IntentFilter(new[] { "android.app.action.DEVICE_ADMIN_ENABLED" })]
public class DeviceAdminReceiver : Android.App.Admin.DeviceAdminReceiver
{
}
And setting the device owner using
.\adb.exe shell dpm set-device-owner com.afwsamples.testdpc/.DeviceAdminReceiver
That appears to solve my problems, so I guess this was down to issues with the names when putting in the manifest manually.
It looks like your manual manifest entries are not taking into account the auto-generated class names (Md5-based) that Xamarin.Android generates to avoid namespace collisions.
Since DeviceAdminReceiver is a subclass of BroadcastReceiver, use the [BroadcastReceiver] class attribute to override the auto-generated class names in your manifest:
[BroadcastReceiver(Name = "com.sushihangover.deviceownerapp.adminreceiver", Enabled = true, Exported = true)]
[IntentFilter(new[] { "android.app.action.DEVICE_ADMIN_ENABLED" })]
public class AdminReceiverTest : DeviceAdminReceiver
{
public override void OnReceive(Context context, Intent intent)
{
base.OnReceive(context, intent);
}
}
Thus in your manifest, the following is auto-generated:
<receiver android:enabled="true" android:exported="true" android:name="com.sushihangover.deviceownerapp.adminreceiver">
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
</intent-filter>
</receiver>
Related
I am currently trying to add deep linking support (via Intents) to an Android application written using .NET MAUI.
I have added an activity XML element under the application element in my AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application android:allowBackup="true" android:icon="#mipmap/appicon" android:roundIcon="#mipmap/appicon_round" android:supportsRtl="true">
<activity android:name="TestApp.MainActivity" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https"
android:host="test"
android:pathPrefix="/group" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
I have also added an IntentFilter to the MainActivity.cs under Platforms\Android (see below):
[IntentFilter(new[] { Intent.ActionView },
Categories = new[]
{
Intent.ActionView,
Intent.CategoryDefault,
Intent.CategoryBrowsable
},
DataScheme = "https", DataHost = "test", DataPathPrefix = "/group"
)
]
public class MainActivity : MauiAppCompatActivity
Just not sure what to do at this point to react (where to put event handler, etc.) to the intent.
If anyone has any suggestions, it would be greatly appreciated.
You can handle the intent by overriding OnNewIntent method .
Fetch the information from intent.DataString and do what you want.
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
//test
OnNewIntent(Intent);
}
protected override void OnNewIntent(Intent intent)
{
base.OnNewIntent(intent);
var data = intent.DataString;
if (intent.Action != Intent.ActionView) return;
if (string.IsNullOrWhiteSpace(data)) return;
if (data.Contains("/group"))
{
//do what you want
}
}
Hello there i have been trying to create a broadcast receiver but i am unable to call it i.e start it from application startup here is my code please tell me that whether something is missing or not here is the things i tried until now
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.testing.broacast" android:versionCode="1" android:versionName="1.0" android:installLocation="auto">
<uses-sdk android:minSdkVersion="16" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application android:label="App4"></application>
<receiver android:name=".Broadcast">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</manifest>
here is my broadcast reciever
[BroadcastReceiver]
[IntentFilter(new[] { Intent.ActionBootCompleted })]
public class Broadcast : BroadcastReceiver
{
public override void OnReceive(Context context,Intent intent)
{
Toast.MakeText(context, "Hello", ToastLength.Long).Show();
// Create your application here}
}
}
This is how it works on my device
[BroadcastReceiver(Enabled = true)]
[IntentFilter(new[] { Intent.ActionBootCompleted })]
public class Broadcast : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
Toast.MakeText(context, "Hello", ToastLength.Long).Show();
}
}
The difference is [BroadcastReceiver(Enabled = true)]
Also I did not need to put the receiver tag in my AndroidManifest.xml.
I have an application A that has to bind to a service that is in another package. I have put a custom intent filter in order to make it work. Sadly the application wont bind. The log says that it can't find the service.
Application A is in the package "com.example.app_a"
The service is in another package "com.example.app_talker_service"
So I just can't refer to the service with the xxx.class solution, so my guess was to use an intent filter in the manifest file of the service's package.
Application A, on the other hand, will need to do a bind to the service to make it start (if it hasn't already started) and that later it will communicate with it though the use of broadcast receivers. I did some experimentation and I noticed that the broadcasts work fine, but what is wrond is that for some reason, the application A can't seem to find my service during the binding....
Here is the code for application A which binds in onStart():
#Override
protected void onStart()
{
// TODO Auto-generated method stub
super.onStart();
//Bind to service
getApplicationContext().bindService(new Intent("com.example.talker_service.SERVICE"), mConnection,Context.BIND_AUTO_CREATE);
}
private boolean mIsBound = false;
private ServiceConnection mConnection = new ServiceConnection()
{
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
mIsBound = true;
Toast.makeText(getApplicationContext(), "CONNECTED TO SERVICE!", Toast.LENGTH_SHORT).show();
Intent intent = new Intent();
intent.setAction("com.example.talker_service.SERVICE");
intent.putExtra("REQUEST", "REGISTER APP");
intent.putExtra("FILTER", "com.example.app_a");
intent.putExtra("NAME", "Applicazione A");
String[] components = {"NUMBER_SENT","CHANGE_TEXT_COLOR","CHANGE_TEXTVIEW_SIZE"};
intent.putExtra("COMPONENTS", components);
MainActivityA.this.sendBroadcast(intent);
}
#Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
mIsBound = false;
}
};
Here instead is the cmanifest for the service which I called Talker_service:
en<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.app_talker_service"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="19" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<service
android:name=".Talker_Service"
android:enabled="true"
android:exported="true"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" >
<intent-filter >
<action android:name="com.example.talker_service.SERVICE"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="text/plain" />
</intent-filter>
</service>
<activity
android:name=".ConnectionManagerActivity"
android:label="#string/title_activity_connection_manager" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
I don't undertsand why it doesn't bind.. I put the intent filter, am I missing something? Ah, and the logs says this:
12-03 22:45:13.786: W/ContextImpl(26076): Implicit intents with startService are
not safe: Intent {
act=com.example.talker_service.SERVICE }
android.content.ContextWrapper.bindService:517
com.example.app_a.MainActivityA.onStart:81
android.app.Instrumentation.callActivityOnStart:1171
12-03 22:45:13.786: W/ActivityManager(764): Unable to start service Intent { >act=com.example.talker_service.SERVICE } U=0: not
found
This instead is the manifest file for application A
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.app_a"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE" ></uses-permission>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivityA"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
I don't know why using intent filters is not working (it says that it can't find it) but by using the following code I was able to make my application connect to the remote service:
Intent i = new Intent();
i.setClassName("com.example.app_talker_service", "com.example.app_talker_service.Talker_Service");
bindService(i, conn, Context.BIND_AUTO_CREATE);
so using the seClassName method and providing the name of the pacake and that full path of the service, I was able to make it work. I am not sure if this falls in the realm of "best practice" for this type of problem, but for my it worked. Any solution is better than no solution. I found this solution thants to this link:
Remote Service Tutorial
I want to start my application when phone startup
I just follow tutorial from here but it doesn't work in my device. Please see my method:
package net.londatiga.android;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class MyBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent startServiceIntent = new Intent(context, ExampleActivity.class);
context.startService(startServiceIntent);
}
}
And this is my manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.londatiga.android"
android:versionCode="2" android:versionName="1.01">
<uses-sdk android:minSdkVersion="7"
android:targetSdkVersion="15"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application android:icon="#drawable/icon" android:label="#string/app_name">
<receiver android:name="net.londatiga.android.MyBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter android:priority="1000">
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<activity android:name=".ExampleActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Where is my mistake please?
Instead of:
context.startService(startServiceIntent);
Use:
context.startActivity(startServiceIntent);
You don't have any Service, You need to open activity.
Intent startServiceIntent = new Intent(context, ExampleActivity.class);
context.startActivity(startServiceIntent);
Create a class name it as AfterBootActivity:
public class AfterBootActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}}
Now, Create a new class named as Autostart.java which extends a BroadcastReceiver:
public class Autostart extends BroadcastReceiver {
public void onReceive(Context context, Intent arg1) {
Intent intent = new Intent(context, StarterService.class);
context.startService(intent);
}}
In the Manifest file add this class as a receiver. This class will listen to the Broadcast call the Android OS sends after the boot sequence has finished i.e. after the phone started up.
Now Create a class named as StarterService.java which will extend Service:
public class StarterService extends Service {
private static final String TAG = "MyService";
public IBinder onBind(Intent intent) {
return null;
}
public void onDestroy() {
Toast.makeText(this, "Service stopped", Toast.LENGTH_LONG).show();
Log.d(TAG, "onDestroy");
}
/**
* The below started service opens the Activity.
*/
public void onStart(Intent intent, int startid) {
Intent intents = new Intent(getBaseContext(), AfterBootActivity.class);
intents.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intents);
Toast.makeText(this, "Service started", Toast.LENGTH_LONG).show();
Log.d(TAG, "onStart");
}}
When the class Autostart receives the BOOT_COMPLETED Broadcast from Android OS it will start the StarterService which then starts the Android Activity “AfterBootActivity” i.e our main class. We can play any audio/video or anything in it.
Change your Manifest.xml as below:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="on.boot.completed"
android:installLocation="internalOnly"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="7"
android:targetSdkVersion="18" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name="on.boot.completed.AfterBootActivity"
android:label="#string/app_name"
android:theme="#android:style/Theme.Black.NoTitleBar.Fullscreen" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name="on.boot.completed.Autostart" >
<intent-filter>
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service
android:name="on.boot.completed.StarterService"
android:enabled="true"
android:exported="true" />
</application>
</manifest>
Also Remember to install it in internal memory because if the app installed on the SD Card then autostart will not work! That’s why it’s important that we add in manifest.
android:installLocation="internalOnly"
That’s all run your app.
After it has been started turn off your phone and turn it back on and the app would start automatically after the device has booted up.
I try to get a broadcast receiver working. Should be as simple as possible, I have my manifest like this:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mytest.intentRec" android:versionCode="1"
android:versionName="1.0">
<application android:icon="#drawable/icon" android:label="#string/app_name"
android:debuggable="true">
<activity android:name=".mainAct" 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="com.mytest.intentRec.MyIntentRec"
android:enabled="true" >
</receiver>
</application>
<uses-sdk android:minSdkVersion="7" />
</manifest>
As you can see I have a main activity mainAct, this does nothing but sending the broadcast once started:
public class mainAct extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
this.sendBroadcast(new Intent());
}
}
and I have a class MyIntentRec, which is as simple as it could:
public class MyIntentRec extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.v("IntentRec", "got it");
}
}
What I expect is that when I start my app that a broadcast is sent and being picked up and that a log entry is written. I don't see that log entry and I don't see any error. I'm suspecting to have either an error in the manifest or in sending the broadcast. I just created an empty intent there, does it need to be some intent with certain properties?
Please setClass for your Intent,
EX:
public class mainAct extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent i=new Intent("any string");
i.setClass(this, MyIntentRec.class);
this.sendBroadcast(i);
}
}
That is what it means " The absence of any filters means that it can be invoked only by Intent objects that specify its exact class name."
[Old answer]
You should register what kind of actions you need in the manifest.
Ex:
<receiver android:name="com.mytest.intentRec.MyIntentRec" android:enabled="true" >
<intent-filter>
<action android:name="your.intent" />
</intent-filter>
</receiver>
send it,
this.sendBroadcast(new Intent("your.intent"));
it is insufficient to make just new Intent();. You have to specify it with some action. Also, you have to specify in your manifest the intent filter for this particular action. Please read more here and here.
You didn't define any Intent Filters in the manifest for your BroadcastReceiver. Specify one for a custom Action type. You also have to define this custom Action type in the Intent you brodcast upon startup.
Try specifying what actions your receiver should catch in the manifest. You can do this as such:
<receiver android:name="com.mytest.intentRec.MyIntentRec">
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</receiver>