We have an application installed on a rooted device as a system application. The latter doesn't have the android.permission.MANAGE_USB and we want to add it to a newer version so that the permission is given to the user automatically. I have followed the post:
bypass android usb host permission confirmation dialog
More specifically, the answer marked as correct from the user d_d_t.
Why doesn't it work? I mean, I have taken this newer version, directly installed it as our original system application and it works perfectly! But when I update the existing version with no usb permission with the newer version it just doesn't work. The new one is just an update. Same certificate and all.
I'm at a loss. Any thoughts?
Our code below:
AndroidManifest.xml.
<uses-permission
android:name="android.permission.MANAGE_USB"
android:protectionLevel="signature" />
Java class.
try {
PackageManager pm = getApplicationContext().getPackageManager();
ApplicationInfo ai = pm.getApplicationInfo(getApplicationContext().getPackageName(), 0);
if (ai != null) {
UsbManager manager = (UsbManager) getApplicationContext().getSystemService(Context.USB_SERVICE);
IBinder b = ServiceManager.getService(Context.USB_SERVICE);
IUsbManager service = IUsbManager.Stub.asInterface(b);
HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
while (deviceIterator.hasNext()) {
UsbDevice device = deviceIterator.next();
if (device.getVendorId() == 0x0403) {
service.grantDevicePermission(device, ai.uid);
service.setDevicePackage(device,getApplicationContext().getPackageName(), 0);
}
}
}
} catch (Exception e) {
Log.e("UsbReceiver", "exception " + e);
e.printStackTrace();
}
Related
I am trying to build a parental control app. So now i want to disable or lock app (like Whatsapp, Facebook, etc). I have tried using PackageManager.setComponentEnabledSetting(). But it is throwing java.lang.SercurityException.
So how can I make a parental control app such that I can disable any app I want without root.
my code is
pm.setComponentEnabledSetting(new ComponentName(temp.activityInfo.packageName,
temp.activityInfo.name+".class"),
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
my error was this
java.lang.SecurityException: Permission Denial: attempt to change component state from pid=11537, uid=10067, package uid=10029
You must add below permissions to manifest.
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"/>
but , these permissions are for System apps and you can not use. :(
You can not write a app to lock or close another app.this is a policy in Google.
for lock a app you must check running apps repeatedly, if specific app is open,then show a activity over that.
while(!Thread.currentThread().isInterrupted())
{
String topActivity = getFrontApp();
if(topActivity.isEmpty())
{
threadSleep(500);
continue;
}
if(topActivity.equals("lockApp"))
{
showLockActivity();
}
threadSleep(500);
}
// for Api21+ need permission
public static String getFrontApp()
{
if (Build.VERSION.SDK_INT >= 21)
{
UsageStatsManager usageManager = SystemMaster.getUsageStatsManager();
long now = System.currentTimeMillis();
List<UsageStats> localList = usageManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, now - 900_000L, now);
String str = "";
if (localList != null)
{
SortedMap<Long,UsageStats> mySortedMap = new TreeMap<>();
for(UsageStats usageStats : localList)
mySortedMap.put(usageStats.getLastTimeUsed(), usageStats);
if(!mySortedMap.isEmpty())
str = mySortedMap.get(mySortedMap.lastKey()).getPackageName();
}
return str;
}
else
{
ActivityManager am = (ActivityManager) getApplication().getSystemService(Context.ACTIVITY_SERVICE);
return am.getRunningTasks(1).get(0).topActivity.getPackageName();
}
above code is very simple , for real app must write more.
I have an android VPN app running on OpenVPN core, so I want to check if a specific app is installed, on connecting the app, it will stop and request for such app to be uninstalled before it works.
I have seen such on an app using JSON for all the app id blacklisted and I really don't know to go about it on my own app.
here is the JSON image file:
Blacklist.json
thank you.
You need to figure out what is the right package name of any installed application on your device.
Getting Package Info:
private boolean isPackageInstalled(String packageName, PackageManager packageManager) {
try {
packageManager.getPackageInfo(packageName, 0);
return true;
} catch (PackageManager.NameNotFoundException e) {
return false;
}
}
Then you can check in here like,
PackageManager pm = context.getPackageManager();
boolean isInstalled = isPackageInstalled("com.somepackage.name", pm);
if(isInstalled) {
// NO VPN
}
else {
// start your service
}
After reading a lot of answers at SO and the android docs, it seems to be impossible to restart a device without root permission.
The app doesn't even ask me if I'd like to grand the permission.
// 1. Use permission in Manifest
<uses-permission android:name="android.permission.REBOOT" />
// 2. Request permission in MainActivity
if (ContextCompat.checkSelfPermission(this, Manifest.permission.REBOOT) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.REBOOT}, 1);
}
// 3. Restart on button click
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
pm.reboot(null);
Error:
java.lang.SecurityException: Neither user 10201 nor current process has android.permission.REBOOT.
Is there any workaround that I missed?
Thank you very much!
B.
No, you can't do this from your Android application without root permissions but you can do this from the terminal by using the command: "adb reboot". But if you can root your device then you can use the following code to reboot:
try {
Process process = Runtime.getRuntime().exec("adb reboot");
} catch (IOException e) {
e.printStackTrace();
}
And if this too get failed on a rooted device then you can try with this by asking for root permission(tried on android kitkat 4.4),
try{
List<String> envList = new ArrayList<String>();
Map<String, String> envMap = System.getenv();
for (String envName : envMap.keySet()) {
envList.add(envName + "=" + envMap.get(envName));
}
final String[] environment = (String[]) envList.toArray(new String[0]);
String command= "reboot";
Runtime.getRuntime().exec(
new String[]{"su", "-c", command},
environment).waitFor();
}catch(IOException e){
//catch exception
}
I'm having an issue with retrieving the MAC address of the device programatically, before anyone mentions anything about other posts I have read them already such as:
How to find MAC address of an Android device programmatically
however I tried using the code with my own application and tested it with a simple log.d, only to find that it is returning nothing. The message of "seeing if this works shows" but nothing else. So i am presuming the mac address is null.
Log.d("seeing if this works", macAddress2);
The code of what I have done is shown here:
//Set onclick listener for the Get Mac Address button
getMac.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
WifiInfo wInfo = wifiManager.getConnectionInfo();
String macAddress2 = wInfo.getMacAddress();
macAddress.setText(macAddress2);
}
});
Which Android version are you testing on? The latest(10/2015) Android M preview has blocked the app from getting the hardware identifiers for Wifi and Bluetooth.
To provide users with greater data protection, starting in this release, Android removes programmatic access to the device’s local hardware identifier for apps using the Wi-Fi and Bluetooth APIs. The WifiInfo.getMacAddress() and the BluetoothAdapter.getAddress() methods now return a constant value of 02:00:00:00:00:00.
There is a workaround by reading the Wifi MAC from /sys/class/net/wlan0/address, which however will also be blocked in the Android N as claimed by Google.
Try this:
public static String getMacAddr() {
try {
List<NetworkInterface> all = Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface nif : all) {
if (!nif.getName().equalsIgnoreCase("wlan0")) continue;
byte[] macBytes = nif.getHardwareAddress();
if (macBytes == null) {
return "";
}
StringBuilder res1 = new StringBuilder();
for (byte b : macBytes) {
res1.append(Integer.toHexString(b & 0xFF) + ":");
}
if (res1.length() > 0) {
res1.deleteCharAt(res1.length() - 1);
}
return res1.toString();
}
} catch (Exception ex) {
}
return "02:00:00:00:00:00";
}
From here:
http://robinhenniges.com/en/android6-get-mac-address-programmatically
Works for me.
Do you have this in the manifest?
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
I downloaded apk file from url(my server) and save it in sdcard. If user install it from sdcard, I want to know, whether is any notification that app is installed successfully or is app istalled in device. Is there any callback on installed app
try this code :
protected boolean isAppInstalled(String packageName) {
Intent mIntent = getPackageManager().getLaunchIntentForPackage(packageName);
if (mIntent != null) {
return true;
}
else {
return false;
}
}
to get the package name of the app easily : just search your app in the google play website , and then you will take the id parameter ( it is the package name of the app) . Example :
you will search on Youtube app on google play , and you will find it in this url :
https://play.google.com/store/apps/details?id=com.google.android.youtube&feature=search_result#?t=W251bGwsMSwxLDEsImNvbS5nb29nbGUuYW5kcm9pZC55b3V0dWJlIl0.
the package name is the id param, so it is : com.google.android.youtube
And then when you want to test , you will just have :
String packageName = "com.google.android.youtube";
boolean isYoutubeInstalled = isAppInstalled(packageName);
PLUS : if you want to get the list of all installed apps in you device , you can find your answer in this tutorial
final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
final List pkgAppsList = context.getPackageManager().queryIntentActivities( mainIntent, 0);
You'll get the list of all installed applications on Android.
Use this to check if an application is installed
PackageManager pm = context.getPackageManager();
List<ApplicationInfo> list = pm.getInstalledApplications(0);
for (int i = 0; i < list.size(); i++) {
if(list.get(i).packageName.equals("com.my package")){
//do what you want
}
}
In Youtube Player API, you can access YoutubeIntents class and use isYoutubeInstalled to verify if device has the Android app or not.