(續3)Device Administration 裝置管理
Source URL
https://developer.android.com/guide/topics/admin/device-admin.html
前一篇文章在此
https://javahand.blogspot.tw/2017/12/device-administration_4.html
在繼續之前,先來看 iOS 對 MDM 的支援。在 Google 中用關鍵字 "iOS MDM" 搜尋,第一個結果即為 Apple 官方的 商務支援。後來隨便逛,又找到 Mobile Device Management (MDM) Protocol。只能待我了解 Android 後,再來研究了。
----------------------------------------------------- 正文開始 ----------------------------------------------------
昨天的邏輯大約是
如果未設置管理項目
則顯示設定畫面 showSetupProfile()
如果設定完成
如果受管理的 App 已安裝 或 該 App 為隱藏
則顯示其狀態 showStatusProfile()
否則顯示主要內容 showMainFragment()
先來看 showStatusProfile()
------------------------------------------- showStatusProfile() -----------------------------------------
private void showStatusProfile()
{
getSupportFragmentManager().beginTransaction().replace(
R.id.container, new StatusFragment()).commit();
-------------------- StatusFragment.java ----------------------
public class StatusFragment
extends Fragment
implements View.OnClickListener
{
...
public View onCreateView( LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState )
{
return inflater.inflate(
R.layout.fragment_status, container, false );
---------------- fragment_status.xml ------------------
<LinearLayout>
<TextView
text="@string/status_not_installed"
------------------ strings.xml ---------------------
<string name="status_not_installed">
AppRestrictionsSchema is not installed.</string>
----------------------------------------------------
/>
<Button />
-------------------------------------------------------
} // end Method onCreateView( LayoutInflater, ... )
public void onResume()
{
super.onResume();
updateUi( getActivity());
----------------------------
因空間不足,移至下方程式碼區塊 A ---------------------------- } // end Method onResume()
} // end Class StatusFragment ---------------------------------------------------------------
} // end Method showStatusProfile()
--------------------------------------------------------------------
---------------------------- 程式碼區塊 A ---------------------------
private void updateUi( Activity activity ){
PackageManager packageManager = activity.getPackageManager();
try
{
int packageFlags;
if ( Build.VERSION.SDK_INT < 24 )
{ //noinspection deprecation
packageFlags = PackageManager.GET_UNINSTALLED_PACKAGES;
}
else
{
packageFlags = PackageManager.MATCH_UNINSTALLED_PACKAGES;
} // end If-Else
ApplicationInfo info = packageManager.getApplicationInfo(
Constants.PACKAGE_NAME_APP_RESTRICTION_SCHEMA,
packageFlags );
DevicePolicyManager devicePolicyManager = (DevicePolicyManager)
activity.getSystemService( Activity.DEVICE_POLICY_SERVICE );
if (( info.flags & ApplicationInfo.FLAG_INSTALLED ) != 0 )
{
if ( !devicePolicyManager.isApplicationHidden(
EnforcerDeviceAdminReceiver.getComponentName( activity ),
Constants.PACKAGE_NAME_APP_RESTRICTION_SCHEMA ))
{ // App 已準備好執行限制
// 因 unhideApp() 會處理,所以應該不會執行到此
mListener.onStatusUpdated();
}
else
{ // 已安裝 App 但為隱藏
mTextStatus.setText( R.string.status_not_activated );
------------------------ strings.xml -----------------------
<string name="status_not_activated">AppRestrictionsSchema is
installed, but not activated in this profile.</string>
------------------------------------------------------------
mButtonUnhide.setVisibility( View.VISIBLE );
} // end If-Else
}
else
{ // 必須重新安裝範例程式
mTextStatus.setText( R.string.status_need_reinstall );
------------------------ strings.xml -----------------------
<string name="status_need_reinstall">AppRestrictionSchema
needs reinstalling.</string>
------------------------------------------------------------
mButtonUnhide.setVisibility( View.GONE );
} // end If-Else
}
catch ( PackageManager.NameNotFoundException e )
{ // 必須重新安裝範例程式
mTextStatus.setText( R.string.status_need_reinstall );
mButtonUnhide.setVisibility( View.GONE );
} // end Try-Catch
} // end Method updateUi( Activity )
以上就是 showStatusProfile() 相關程式碼。
再來看的是 showMainFragment()。
------------------------- showMainFragment() ------------------------
private void showMainFragment()
{
getSupportFragmentManager().beginTransaction().replace(
R.id.container, new AppRestrictionEnforcerFragment()).commit();
} // end Method showMainFragment()
--------------------------------------------------------------------
---------------- AppRestrictionEnforcerFragment.java ----------------
public class AppRestrictionEnforcerFragment
extends Fragment
implements CompoundButton.OnCheckedChangeListener,
AdapterView.OnItemSelectedListener,
View.OnClickListener,
ItemAddFragment.OnItemAddedListener
{
...
public View onCreateView( LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState )
{
return inflater.inflate( R.layout
.fragment_app_restriction_enforcer, container, false );
} // end Method onCreateView( LayoutInflater, ViewGroup, Bundle )
public void onResume()
{
super.onResume();
loadRestrictions( getActivity());
} // end onResume()
private void loadRestrictions( Activity activity )
{
RestrictionsManager manager = (RestrictionsManager)
activity.getSystemService( Context.RESTRICTIONS_SERVICE );
List<RestrictionEntry> restrictions
= manager.getManifestRestrictions(
Constants.PACKAGE_NAME_APP_RESTRICTION_SCHEMA );
SharedPreferences prefs = activity
.getSharedPreferences( PREFS_KEY, Context.MODE_PRIVATE );
for ( RestrictionEntry restriction : restrictions )
{
String key = restriction.getKey();
if ( RESTRICTION_KEY_SAY_HELLO.equals( key ))
{
updateCanSayHello(
prefs.getBoolean( RESTRICTION_KEY_SAY_HELLO,
restriction.getSelectedState()));
}
else if ( RESTRICTION_KEY_MESSAGE.equals( key ))
{
updateMessage( prefs.getString( RESTRICTION_KEY_MESSAGE,
restriction.getSelectedString()));
}
else if ( RESTRICTION_KEY_NUMBER.equals( key ))
{
updateNumber( prefs.getInt( RESTRICTION_KEY_NUMBER,
restriction.getIntValue()));
}
else if ( RESTRICTION_KEY_RANK.equals( key ))
{
updateRank( activity, restriction.getChoiceValues(),
prefs.getString(RESTRICTION_KEY_RANK,
restriction.getSelectedString()));
}
else if ( RESTRICTION_KEY_APPROVALS.equals( key ))
{
updateApprovals( activity, restriction.getChoiceValues(),
TextUtils.split(prefs.getString(RESTRICTION_KEY_APPROVALS,
TextUtils.join(DELIMETER,
restriction.getAllSelectedStrings())),
DELIMETER));
} else if (BUNDLE_SUPPORTED && RESTRICTION_KEY_ITEMS.equals(key)) {
String itemsString = prefs.getString(RESTRICTION_KEY_ITEMS, "");
HashMap<String, String> items = new HashMap<>();
for (String itemString : TextUtils.split(itemsString, DELIMETER)) {
String[] strings = itemString.split(SEPARATOR, 2);
items.put(strings[0], strings[1]);
}
updateItems(activity, items);
}
}
}
} // end Class AppRestrictionEnforcerFragment
--------------------------------------------------------------------
--------------- fragment_app_restriction_enforcer.xml ---------------
<ScrollView>
<LinearLayout>
<Switch
text="@string/allow_saying_hello"
------------------------ strings.xml -------------------------- <string name="allow_saying_hello">Allow AppRestrictionSchema to
say hello: </string>
---------------------------------------------------------------
/>
<LinearLayout>
<TextView
text="@string/message"
----------------------- strings.xml -------------------------
<string name="message">Message: </string>
-------------------------------------------------------------
/>
<EditText>
<LinearLayout>
<TextView
text="@string/number"
----------------------- strings.xml -------------------------
<string name="number">Number: </string>
-------------------------------------------------------------
/>
<EditText>
<LinearLayout>
<TextView
text="@string/rank"
----------------------- strings.xml -------------------------
<string name="rank">Rank: </string>
-------------------------------------------------------------
/>
<Spinner
id="rank"
/>
...
--------------------------------------------------------------------
https://developer.android.com/guide/topics/admin/device-admin.html
前一篇文章在此
https://javahand.blogspot.tw/2017/12/device-administration_4.html
在繼續之前,先來看 iOS 對 MDM 的支援。在 Google 中用關鍵字 "iOS MDM" 搜尋,第一個結果即為 Apple 官方的 商務支援。後來隨便逛,又找到 Mobile Device Management (MDM) Protocol。只能待我了解 Android 後,再來研究了。
----------------------------------------------------- 正文開始 ----------------------------------------------------
昨天的邏輯大約是
如果未設置管理項目
則顯示設定畫面 showSetupProfile()
如果設定完成
如果受管理的 App 已安裝 或 該 App 為隱藏
則顯示其狀態 showStatusProfile()
否則顯示主要內容 showMainFragment()
先來看 showStatusProfile()
------------------------------------------- showStatusProfile() -----------------------------------------
private void showStatusProfile()
{
getSupportFragmentManager().beginTransaction().replace(
R.id.container, new StatusFragment()).commit();
-------------------- StatusFragment.java ----------------------
public class StatusFragment
extends Fragment
implements View.OnClickListener
{
...
public View onCreateView( LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState )
{
return inflater.inflate(
R.layout.fragment_status, container, false );
---------------- fragment_status.xml ------------------
<LinearLayout>
<TextView
text="@string/status_not_installed"
------------------ strings.xml ---------------------
<string name="status_not_installed">
AppRestrictionsSchema is not installed.</string>
----------------------------------------------------
/>
<Button />
-------------------------------------------------------
} // end Method onCreateView( LayoutInflater, ... )
public void onResume()
{
super.onResume();
updateUi( getActivity());
----------------------------
因空間不足,移至下方程式碼區塊 A ---------------------------- } // end Method onResume()
} // end Class StatusFragment ---------------------------------------------------------------
} // end Method showStatusProfile()
--------------------------------------------------------------------
---------------------------- 程式碼區塊 A ---------------------------
private void updateUi( Activity activity ){
PackageManager packageManager = activity.getPackageManager();
try
{
int packageFlags;
if ( Build.VERSION.SDK_INT < 24 )
{ //noinspection deprecation
packageFlags = PackageManager.GET_UNINSTALLED_PACKAGES;
}
else
{
packageFlags = PackageManager.MATCH_UNINSTALLED_PACKAGES;
} // end If-Else
ApplicationInfo info = packageManager.getApplicationInfo(
Constants.PACKAGE_NAME_APP_RESTRICTION_SCHEMA,
packageFlags );
DevicePolicyManager devicePolicyManager = (DevicePolicyManager)
activity.getSystemService( Activity.DEVICE_POLICY_SERVICE );
if (( info.flags & ApplicationInfo.FLAG_INSTALLED ) != 0 )
{
if ( !devicePolicyManager.isApplicationHidden(
EnforcerDeviceAdminReceiver.getComponentName( activity ),
Constants.PACKAGE_NAME_APP_RESTRICTION_SCHEMA ))
{ // App 已準備好執行限制
// 因 unhideApp() 會處理,所以應該不會執行到此
mListener.onStatusUpdated();
}
else
{ // 已安裝 App 但為隱藏
mTextStatus.setText( R.string.status_not_activated );
------------------------ strings.xml -----------------------
<string name="status_not_activated">AppRestrictionsSchema is
installed, but not activated in this profile.</string>
------------------------------------------------------------
mButtonUnhide.setVisibility( View.VISIBLE );
} // end If-Else
}
else
{ // 必須重新安裝範例程式
mTextStatus.setText( R.string.status_need_reinstall );
------------------------ strings.xml -----------------------
<string name="status_need_reinstall">AppRestrictionSchema
needs reinstalling.</string>
------------------------------------------------------------
mButtonUnhide.setVisibility( View.GONE );
} // end If-Else
}
catch ( PackageManager.NameNotFoundException e )
{ // 必須重新安裝範例程式
mTextStatus.setText( R.string.status_need_reinstall );
mButtonUnhide.setVisibility( View.GONE );
} // end Try-Catch
} // end Method updateUi( Activity )
以上就是 showStatusProfile() 相關程式碼。
再來看的是 showMainFragment()。
------------------------- showMainFragment() ------------------------
private void showMainFragment()
{
getSupportFragmentManager().beginTransaction().replace(
R.id.container, new AppRestrictionEnforcerFragment()).commit();
} // end Method showMainFragment()
--------------------------------------------------------------------
---------------- AppRestrictionEnforcerFragment.java ----------------
public class AppRestrictionEnforcerFragment
extends Fragment
implements CompoundButton.OnCheckedChangeListener,
AdapterView.OnItemSelectedListener,
View.OnClickListener,
ItemAddFragment.OnItemAddedListener
{
...
public View onCreateView( LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState )
{
return inflater.inflate( R.layout
.fragment_app_restriction_enforcer, container, false );
} // end Method onCreateView( LayoutInflater, ViewGroup, Bundle )
public void onResume()
{
super.onResume();
loadRestrictions( getActivity());
} // end onResume()
private void loadRestrictions( Activity activity )
{
RestrictionsManager manager = (RestrictionsManager)
activity.getSystemService( Context.RESTRICTIONS_SERVICE );
List<RestrictionEntry> restrictions
= manager.getManifestRestrictions(
Constants.PACKAGE_NAME_APP_RESTRICTION_SCHEMA );
SharedPreferences prefs = activity
.getSharedPreferences( PREFS_KEY, Context.MODE_PRIVATE );
for ( RestrictionEntry restriction : restrictions )
{
String key = restriction.getKey();
if ( RESTRICTION_KEY_SAY_HELLO.equals( key ))
{
updateCanSayHello(
prefs.getBoolean( RESTRICTION_KEY_SAY_HELLO,
restriction.getSelectedState()));
}
else if ( RESTRICTION_KEY_MESSAGE.equals( key ))
{
updateMessage( prefs.getString( RESTRICTION_KEY_MESSAGE,
restriction.getSelectedString()));
}
else if ( RESTRICTION_KEY_NUMBER.equals( key ))
{
updateNumber( prefs.getInt( RESTRICTION_KEY_NUMBER,
restriction.getIntValue()));
}
else if ( RESTRICTION_KEY_RANK.equals( key ))
{
updateRank( activity, restriction.getChoiceValues(),
prefs.getString(RESTRICTION_KEY_RANK,
restriction.getSelectedString()));
}
else if ( RESTRICTION_KEY_APPROVALS.equals( key ))
{
updateApprovals( activity, restriction.getChoiceValues(),
TextUtils.split(prefs.getString(RESTRICTION_KEY_APPROVALS,
TextUtils.join(DELIMETER,
restriction.getAllSelectedStrings())),
DELIMETER));
} else if (BUNDLE_SUPPORTED && RESTRICTION_KEY_ITEMS.equals(key)) {
String itemsString = prefs.getString(RESTRICTION_KEY_ITEMS, "");
HashMap<String, String> items = new HashMap<>();
for (String itemString : TextUtils.split(itemsString, DELIMETER)) {
String[] strings = itemString.split(SEPARATOR, 2);
items.put(strings[0], strings[1]);
}
updateItems(activity, items);
}
}
}
} // end Class AppRestrictionEnforcerFragment
--------------------------------------------------------------------
--------------- fragment_app_restriction_enforcer.xml ---------------
<ScrollView>
<LinearLayout>
<Switch
text="@string/allow_saying_hello"
------------------------ strings.xml -------------------------- <string name="allow_saying_hello">Allow AppRestrictionSchema to
say hello: </string>
---------------------------------------------------------------
/>
<LinearLayout>
<TextView
text="@string/message"
----------------------- strings.xml -------------------------
<string name="message">Message: </string>
-------------------------------------------------------------
/>
<EditText>
<LinearLayout>
<TextView
text="@string/number"
----------------------- strings.xml -------------------------
<string name="number">Number: </string>
-------------------------------------------------------------
/>
<EditText>
<LinearLayout>
<TextView
text="@string/rank"
----------------------- strings.xml -------------------------
<string name="rank">Rank: </string>
-------------------------------------------------------------
/>
<Spinner
id="rank"
/>
...
--------------------------------------------------------------------
留言
張貼留言