2010-10-01 40 views
23

đối với một số yêu cầu cụ thể Tôi đang yêu cầu thay đổi Android Mặc định Trang chủ ứng dụng với ứng dụng Home tùy chỉnh của tôi (một thiết lập bên trong ứng dụng của tôi mà sẽ chuyển đổi chủ mặc định = ứng dụng của tôi hoặc nhà trước)Android: thay đổi mặc định Home Application

Tôi không muốn người dùng di chuyển các cài đặt Android rất phức tạp.

Bất kỳ một thể giúp tôi ra như nơi đăng ký launcher.apk cho mặc định ứng dụng nhà hoặc làm thế nào để thay đổi điều đó

Điều duy nhất tôi có thể tìm thấy được rằng câu hỏi cũ: How to change default Android's Desktop application?

nhưng không có câu trả lời ở tất cả.

Tôi đã thấy HomeSwitcher trong Market thực hiện thủ thuật, nhưng không có câu trả lời cho nhà phát triển chắc chắn có thể bận.

EDIT

Tôi thấy điều này trên web http://www.mail-archive.com/[email protected]/msg74167.html

Nhưng tôi có cùng một vấn đề:

đây là mã của tôi:

private void makePreferred() { 
      PackageManager pm = getPackageManager(); 
      IntentFilter f = new IntentFilter("android.intent.action.MAIN"); 
      f.addCategory("android.intent.category.HOME"); 
      f.addCategory("android.intent.category.DEFAULT"); 
      ComponentName cn = new ComponentName("com.example.android.home", "com.example.android.home.Home"); 
      pm.addPreferredActivity(f, IntentFilter.MATCH_CATEGORY_EMPTY, null, cn); 

Tôi có tập android.permission.SET_PREFERRED_APPLICATIONS trong bản kê khai . Sau khi thực thi mã ở trên, nhật ký xác nhận mọi thứ có được thêm vào như mong đợi (cùng nhật ký như khi tôi đánh dấu chọn "Đặt làm mặc định" từ danh sách của IntentResolver). Tuy nhiên, khi tôi tiến hành bằng cách nhấn vào nhà, danh sách vẫn xuất hiện và các bản ghi nói:

INFO/PackageManager(52): Result set changed, dropping preferred 
activity for Intent { act=android.intent.action.MAIN cat= 
[android.intent.category.HOME] flg=0x10200000 } type null 

Vì vậy, có vẻ như resolver xóa các mục nhập mặc định. Tôi có đang làm điều gì đó sai, hoặc đây có phải là biện pháp bảo mật không? Ý tưởng đằng sau điều này là gì?

+1

Tôi khá chắc chắn rằng bạn không thể ép buộc người dùng sử dụng ý định của bạn làm mặc định cho bất cứ điều gì - nó nên luôn luôn là sự lựa chọn của họ. Đăng ký nó như là một mục đích Trang chủ nên là đủ cho người dùng để có được một hộp thoại yêu cầu ứng dụng nhà mà họ muốn khởi động. –

+0

Điều này là không thể UNLESS bạn đang làm việc với một xây dựng chính cho một chiếc điện thoại và thậm chí sau đó nó vẫn còn nguy hiểm. Cân nhắc nói cho người yêu cầu của bạn KHÔNG. Bởi vì đây không phải là hành vi mong đợi từ góc độ ứng dụng. – JoxTraex

Trả lời

8

Tôi đã nghiên cứu sâu rộng về điều đó và bắt đầu từ 2.2 không có cách nào để thực hiện điều đó. Cách duy nhất là sử dụng một số hack rằng ứng dụng khóa trẻ mới biết đi nhưng ứng dụng này đặt điện thoại samsung gần đây trong vòng lặp vô hạn, vì vậy nó là một cách tiếp cận nguy hiểm.

nếu bạn nhìn vào mã nguồn Froyo here của lớp PackageManager, bạn sẽ thấy tình trạng nhỏ này trong phương pháp addPreferredActivity:

if (getUidTargetSdkVersionLockedLP(Binder.getCallingUid()) 
        < Build.VERSION_CODES.FROYO) { 
       Slog.w(TAG, "Ignoring addPreferredActivity() from uid" 
         + Binder.getCallingUid()); 
       return; 
      } 

HomeSwitcher không hoạt động đúng trên 2.2 vì nó sử dụng phương pháp và phát triển rất này nhận xét về trang ứng dụng "Froyo (2.2) không được hỗ trợ do sự thay đổi API"

+0

OP không gây khó khăn. Lỗi của anh ta là "thả hoạt động ưa thích ..." được tạo ra tiếp theo trong mã. Tất cả việc kiểm tra đó là ngăn bạn gọi addPreferredActivity từ một ứng dụng không được xây dựng chống lại Froyo. –

7

"Kết quả thiết lập thay đổi" có nghĩa là tập hợp các gói phù hợp với ý định đó đã thay đổi từ tập bạn chỉ định khi bạn c reated mặc định - - do đó, mặc định không còn giá trị. Danh sách các thành phần của bạn (mà bạn hiện đang thiết lập để null) cần phải chứa tất cả các ứng dụng màn hình hiển thị trên thiết bị, không chỉ của bạn.

Đây là mã ví dụ mà tôi đã thử nghiệm (sử dụng vỏ adb bắt đầu http://www.google.co.uk/) và được sử dụng để đặt trình duyệt mặc định.XXX đại diện cho tên khách hàng mà tôi phải bôi đen.

Lưu ý rằng để gọi addPreferredActivity, bạn phải biên soạn dựa trên phiên bản tối thiểu là sdk 8 (2.2) và bạn phải chỉ định quyền SET_PREFERRED_APPLICATIONS. Quyền đó là mức bảo vệ 2, vì vậy bạn cần phải được ký với cùng một chứng chỉ như PackageManager.

IntentFilter filter = new IntentFilter(); 
filter.addAction("android.intent.action.VIEW"); 
filter.addCategory("android.intent.category.DEFAULT"); 
filter.addDataScheme("http"); 
Context context = getApplicationContext(); 
ComponentName component = new ComponentName("com.opera.mini.XXX", "com.opera.mini.XXX.CustomerBrowser"); 
ComponentName[] components = new ComponentName[] {new ComponentName("com.android.browser", "com.android.browser.BrowserActivity"), 
                component}; 
pm.addPreferredActivity(filter, IntentFilter.MATCH_CATEGORY_SCHEME, components, component); 

ETA - nếu bạn đánh dấu phản hồi này, bạn có thể cho tôi biết lý do không. Mã tôi đăng ở trên được kiểm tra và làm việc ...

+6

làm thế nào để ký nó với cùng một giấy chứng nhận? – hoffmanc

+0

Tôi cũng muốn triển khai nó, tôi muốn thay đổi trình khởi chạy mặc định sau lần khởi động đầu tiên. Tôi đã đặt mã cho constructor của PackageManagerService, nhưng nó luôn thất bại. Bạn có thể cho tôi biết Nếu tôi muốn làm điều đó, vị trí nào tôi nên đặt mã? cảm ơn rất nhiều! – alexunder

+0

@hoffmanc bạn sẽ cần các phím nền tảng mà hệ điều hành được xây dựng cùng. Trừ khi bạn đang xây dựng và ký bản ROM của riêng mình, bạn sẽ không có quyền truy cập vào các bản ROM này. – amitav13

0

Mã này hoạt động trên thiết bị ICS của tôi: Tôi sử dụng dịch vụ hợp lý cho một số cuộc gọi, một trong số đó được gọi là SET_PREFERRED_LAUNCHER, gói được đặt mặc định mới gói Launcher (PREFERRED_PACKAGE_KEY) và hoạt động nó (PREFERRED_ACTIVITY_KEY)

Method installPackageMethod = null; 
Method deletePackageMethod = null; 
Method setPreferredActivityMethod = null; 
Method replacePreferredActivityMethod = null; 
Object pm = null; 


    @Override 
public void onCreate() { 
    super.onCreate(); 
     if (pm == null) 
     pm = getPackageManager(); 
    try { 
     if (setPreferredActivityMethod == null) 
      setPreferredActivityMethod = pm.getClass().getMethod(
        "addPreferredActivity", IntentFilter.class, int.class, 
        ComponentName[].class, ComponentName.class); 
    } catch (NoSuchMethodException e) { 
     e.printStackTrace(); 
    } 
} 


private final class ServiceHandler extends Handler { 
    private Context context; 

    public ServiceHandler(Looper looper, Context ctx) { 
     super(looper); 
     context = ctx; 
    } 

    @Override 
    public void handleMessage(Message msg) { 
     Intent intent = (Intent) msg.getData().getParcelable(
       UPDATER_SERVICE_ACTION); 
     int request = intent.getIntExtra(
       REQUEST_KEY, 
       REQUEST_UNKNOWN); 
     Bundle bundle = intent.getExtras(); 

     switch (request) { 
     case INSTALL_APPLICATION: { 
      if (bundle != null) { 
       String appPath = bundle 
         .getString(APP_PATH_KEY); 
       if (appPath != null) { 
        LogUtil.e(TAG, "try to install " + appPath); 

        try { 
         am.installPackage(appPath); 
        } catch (Exception e) { 
         e.printStackTrace(); 
        } 

        LogUtil.e(TAG, "install of " + appPath + " done"); 
       } 
      } 
      break; 
     } 
     case UNISTALL_PACKAGE: { 
      if (bundle != null) { 
       String packagename = bundle 
         .getString(PACKAGE_NAME_KEY); 
       if (packagename != null) { 
        LogUtil.e(TAG, "unistall " + packagename); 

        try { 
         deletePackageMethod 
           .invoke(pm, packagename, null, 0); 
        } catch (Exception e) { 
         e.printStackTrace(); 
        } 
       } 
      } 
      break; 
     } 
     case SET_PREFERRED_LAUNCHER: { 
      if (bundle != null) { 
       String package_name = bundle 
         .getString(PREFERRED_PACKAGE_KEY); 
       if (package_name == null) { 
        LogUtil.e(TAG, 
          "WARNING: setDefaultActivity cannot continue, package is NULL"); 
        return; 
       } 
       String activity_name = bundle 
         .getString(PREFERRED_ACTIVITY_KEY); 
       if (activity_name == null) { 
        LogUtil.e(TAG, 
          "WARNING: setDefaultActivity cannot continue, activity is NULL"); 
        return; 
       } 

       LogUtil.e(TAG, "setDefaultActivity activity=" 
         + activity_name + " package=" + package_name); 

       IntentFilter filter = new IntentFilter(
         "android.intent.action.MAIN"); 
       filter.addCategory("android.intent.category.HOME"); 
       filter.addCategory("android.intent.category.DEFAULT"); 
       ComponentName[] components = new ComponentName[] { 
         new ComponentName("com.android.launcher", 
           "com.android.launcher2.Launcher"), 
         new ComponentName(package_name, activity_name) }; 
       ComponentName activity = new ComponentName(package_name, 
         activity_name); 
       try { 
        setPreferredActivityMethod.invoke(pm, filter, 
          IntentFilter.MATCH_CATEGORY_EMPTY, components, 
          activity); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
     } 

    } 

} 

Hãy nhớ thêm trong file manifest của bạn cho phép này:

<uses-permission android:name="android.permission.SET_PREFERRED_APPLICATIONS"/> 

Cách sử dụng:

public void setPreferredLauncher(String activity_name,String package_name) 
{ 
    Intent intent = new Intent(UPDATER_SERVICE_ACTION); 
    intent.putExtra(REQUEST_KEY, SET_PREFERRED_LAUNCHER); 
    intent.putExtra(PREFERRED_ACTIVITY_KEY, activity_name); 
    intent.putExtra(PREFERRED_PACKAGE_KEY, package_name); 
    context.startService(intent); 
} 

nơi:

public static final String _UPDATER_SERVICE_ACTION = "com.android.updaterservice.ACTION"; 
public static final String REQUEST_KEY = "com.android.updaterservice.REQUEST_KEY"; 
public static final String PACKAGE_NAME_KEY = "com.android.updaterservice.PACKAGE_NAME_KEY"; 
public static final String APP_PATH_KEY = "com.android.updaterservice.APP_PATH_KEY"; 
public static final String PREFERRED_ACTIVITY_KEY = "com.android.updaterservice.PREFERRED_ACTIVITY_KEY"; 
public static final String PREFERRED_PACKAGE_KEY = "com.android.updaterservice.PREFERRED_PACKAGE_KEY"; 
public static final String INSTALL_PACKAGE_RESULT = "com.android.updaterservice.INSTALL_PACKAGE_RESULT"; 
public static final String PACKAGE_NAME = "PACKAGE_NAME"; 
public static final String INSTALL_SUCCEEDED = "INSTALL_SUCCEEDED"; 
public static final int REQUEST_UNKNOWN = -1; 
public static final int INSTALL_APPLICATION = 1; 
public static final int UNISTALL_PACKAGE = 2; 
public static final int SET_PREFERRED_LAUNCHER = 3; 
+1

Lưu ý rằng chỉ các ứng dụng được ký bằng cùng một phím ký như đã ký phần mềm mới có thể giữ quyền 'SET_PREFERRED_APPLICATIONS'. – CommonsWare

+0

Tại am.installPackage() .. là gì? những gì để khai báo? và không sử dụng serviceHandler .. hãy cập nhật nó đúng cách –

0
startActivity(new Intent(Settings.ACTION_HOME_SETTINGS)); 
+0

Thao tác này sẽ chuyển đến cài đặt và cho phép bạn đặt Trình khởi chạy trang chủ theo cách thủ công, nhưng không đặt lại trình khởi chạy mặc định theo chương trình. – saiyancoder

Các vấn đề liên quan