Có thể khởi động lại Ứng dụng Android sau khi gọi ActivityManager.clearApplicationUserData ()


8

Ứng dụng Android hiện tại của tôi cần gọi

 ActivityManager.clearApplicationUserData()

để mô phỏng việc xóa người dùng Lưu trữ ứng dụng

Mà hoạt động tốt.

Một tác dụng phụ của việc gọi điện clearApplicationUserData()là Ứng dụng bị đóng (có thể hiểu được).

Cung cấp trải nghiệm người dùng kém.

Tôi gặp khó khăn trong việc khởi động lại Ứng dụng của mình sau khi tôi đã gọi clearApplicationUserData().

Tôi đã thử sử dụng startActivity, Alarm Managervới Pending Intent, Foreground/ Backgrounddịch vụ.

Không có gì hoạt động.

Có thể khởi động lại ứng dụng Android đã gọi clearApplicationUserData()không?


1
Tôi đoán là ứng dụng của bạn sẽ chuyển sang trạng thái dừng, như thể người dùng đã nhấp vào "Buộc dừng". Tất cả các báo động xuất sắc, công việc, vv sẽ bị hủy bỏ. "Có thể khởi động lại ứng dụng Android đã gọi clearApplicationUserData()không?" - Tôi nghi ngờ điều đó là có thể từ trong ứng dụng của riêng bạn. Hiển thị thông báo cho người dùng giải thích rằng điều này sẽ xảy ra trước khi gọi phương thức đó và người dùng có thể khởi động lại ứng dụng từ trình khởi chạy.
CommonsWare

1
Tôi nghĩ đây là bản dựng của nó dành cho .. Trình quản lý báo thức với Ý định đang chờ xử lý, Tiền cảnh / Nền sẽ rõ ràng hơn .. Nếu bạn sẽ sử dụng clearApplicationUserDatathì đây sẽ là luồng mong muốn .. Bạn có thể kiểm tra mã nguồn cho nó ..
ADM

@CommonsWare dù sao tôi cũng có thể kích hoạt ghi nhật ký chi tiết (hoặc tương tự) để xem điều gì thực sự xảy ra khi gọi phương thức này?
Hector

1
Tôi không biết ý của bạn là "những gì thực sự xảy ra", nhưng bạn có thể xem Logcat để xem những gì đang được đăng nhập. Nếu bạn đang xem nó từ trong Android Studio, hãy chuyển bộ lọc mức độ nghiêm trọng thành "verbose" và đảm bảo thả xuống cuối được đặt thành "Không có bộ lọc", để xem tất cả các tin nhắn.
CommonsWare

2
Tôi đã từng đi xuống một con đường tương tự trong quá khứ. Cuối cùng, dễ dàng hơn để xóa thủ công cơ sở dữ liệu và chia sẻ tùy chọn và khởi chạy lại MainActivity. Nếu điều này là có thể, nó được khuyến khích mạnh mẽ! Nếu không, có lẽ một cái gì đó như lên lịch một tác vụ với WorkManager(không phải (?) Bị ảnh hưởng bởi dữ liệu ứng dụng rõ ràng) để khởi chạy hoạt động của bạn?
JakeSteam

Câu trả lời:


4

( Câu trả lời thứ 1 : câu trả lời này chỉ hoạt động trong tình huống hạn chế. Đây không phải là câu trả lời hoàn chỉnh)

công khai boolean ClearApplicationUserData ()

Sự miêu tả

Trả về : truenếu ứng dụng yêu cầu xóa dữ liệu của ứng dụng thành công; falsenếu không thì.

Như trang web tham khảo đã nêu, chúng tôi có người trở về trước khi đóng ứng dụng. Vì vậy, chúng tôi sẽ sử dụng người trở về này để khởi động lại ứng dụng.

if(ActivityManager.clearApplicationUserData)
{
     doRestart = true;
}

khi Activity onDestroy()onStop()được gọi là ứng dụng khởi động lại.

   @Override
   protected void onDestroy() {
       super.onDestroy();
       if(doRestart){
           Intent intent = new Intent(this, Activity.class);
           this.startActivity(intent);
       }
   }

    @Override
    protected void onStop() {
        super.onStop();
        if(doRestart){
            Intent intent = new Intent(this, Activity.class);
            this.startActivity(intent);
        }
    }

Chúng tôi đặt hành động khởi động lại ở cả hai onDestroy()onStop()để đảm bảo ứng dụng sẽ được khởi động lại.

Và tôi cũng nghĩ rằng nên dừng hoạt động trước khi HĐH dừng hoạt động.

if(ActivityManager.clearApplicationUserData)
{
     doRestart = true;
     finish(); <= i mean this 
}

bởi vì, nó chắc chắn rằng onDestroy()onStop()sẽ được gọi.


Sau khi gọi ActivityManager.clearApplicationUserData()quá trình ứng dụng bị giết chết. Không có dòng mã nào khác được thực thi.
Onik

@Onik bạn đã thử chưa? khi Activity bị đóng, luôn luôn gọi onDestroy () và nguồn chính thức cũng nói rằng nó trả về boolean nếu không nó sẽ trả về void.
Mr.AF

1
Tất nhiên tôi đã thử, tại sao tôi lại viết bình luận với thông tin chi tiết như vậy? Nếu bạn có một hành vi gọi phương thức khác, tôi đoán có sự khác biệt trong việc triển khai API, điều này làm cho phiên bản HĐH giải pháp của bạn trở nên cụ thể.
Onik

@ Mr.AF cảm ơn vì đã dành thời gian trả lời. Tôi sẽ thử giải pháp của bạn chắc chắn
Hector

@Onik xem câu trả lời tiếp theo của tôi :)
Mr.AF

3

Đề nghị của tôi nghe có vẻ tầm thường nhưng, bạn đã cân nhắc việc không gọi ActivityManager.clearApplicationUserData()chưa?

Dưới đây là những gì các tài liệu nói về phương pháp này:

Cho phép một ứng dụng xóa dữ liệu của chính nó khỏi đĩa. Điều này tương đương với việc người dùng chọn xóa dữ liệu của ứng dụng trong giao diện người dùng cài đặt thiết bị. Nó xóa tất cả dữ liệu động được liên kết với ứng dụng - dữ liệu riêng tư và dữ liệu trong vùng riêng tư của nó trên bộ nhớ ngoài - nhưng không xóa chính ứng dụng đã cài đặt, cũng như bất kỳ tệp OBB nào.

Vì vậy, để bắt chước hành vi này, bạn chỉ cần xóa các thư mục lưu trữ nội bộ và bên ngoài. Không có quyền là cần thiết để truy cập bất kỳ trong số đó.


2

( Câu trả lời thứ 2 : tôi cần đóng góp nhiều hơn cho nó)

Sau 8 giờ nghiên cứu trong Hệ điều hành Android và Trang web dành cho nhà phát triển Android để tìm giải pháp khởi động lại hoạt động khi clearApplicationUserDatađược gọi. Cuối cùng, tôi sẽ có thể tìm thấy một giải pháp tốt đẹp / hack .

Giải pháp này trông giống như rê bóng zidane :)

Hãy giới thiệu giải pháp. lúc đầu, clearApplicationUserDataxóa tất cả các manh mối của ứng dụng khi được gọi như các tác vụ, thông báo, báo thức , v.v. do đó, việc gọi Hoạt động rõ ràng là không thể .

cách ngầm là cách duy nhất có thể của hoạt động gọi.

Sau một vài thử nghiệm tôi thấy rằng ứng dụng manifestđã đăng ký intent-filters sẽ không bị xóa và họ có thể nghe các chương trình phát sóng hệ thống đến .

Khoảng 98% các chương trình phát sóng hệ thống sẽ không được nhận bởi ứng dụng đã bị xóa2% còn lại có thể không được phát sóng sớm.

vậy lam gi ? hmmm Thôi nào anh bạn phải tìm một giải pháp ...

bingo, tôi phải kích hoạt một cái gì đó để hệ thống phát nó <= trông hack :)

vì vậy tôi quyết định chọn WIFI_STATE_CHANGED

  • Quyền truy cập dễ dàng
  • Hệ thống phát sóng chậm trễ <= điều này đảm bảo ứng dụng được đóng trước khi phát

tệp kê khai

<receiver
   android:name=".PackageDataClearedReceiver"
   android:enabled="true"
   android:exported="true">
     <intent-filter android:priority="100">
       <action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
       <action android:name="android.net.wifi.STATE_CHANGE" />
     </intent-filter>
 </receiver>

MainActivity.java

public class MainActivity extends AppCompatActivity {
    ActivityManager am;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        AppCompatButton btn = findViewById(R.id.btn);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        am = (ActivityManager) getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
                        if (am != null) {
                            ExecutorService pool = Executors.newFixedThreadPool(2);
                            final Collection<Future> futures = new HashSet<Future>();
                            futures.add(pool.submit(new Runnable() {
                                @Override
                                public void run() {
                                    WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
                                    wifiManager.setWifiEnabled(true);
                                    wifiManager.setWifiEnabled(false);
                                    am.clearApplicationUserData();
                                }
                            }));
                            for (Future future : futures) {
                                future.isDone();
                            }
                        }

                    }
                }).start();
            }
        });
    }
}

bản giới thiệu

nhập mô tả hình ảnh ở đây

Hãy nhớ rằng, nó chỉ là một sản phẩm khả thi tối thiểu cần được phát triển nhiều hơn để làm cho nó hoạt động hoàn hảo.


Cách tiếp cận này sẽ không hiệu quả với ứng dụng của tôi vì tôi đã phát hiện các thay đổi về trạng thái WIFI để hiển thị thông báo cho người dùng của mình, Nếu tôi tiếp cận giải pháp thứ 2 mỗi khi thay đổi trạng thái WIFI, tôi sẽ bắt đầu hoạt động chính của mình
Hector

@ Hector yup, nó cần phát triển hơn nữa và tùy chỉnh theo nhu cầu của bạn như tôi đã nói đó là sản phẩm khả thi tối thiểu. Bạn cần tùy chỉnh nó
Mr.AF

@Hector bạn cần đặt điều kiện trong Bộ thu để khởi động lại hoạt động khi cần
Mr.AF

0

Hy vọng rằng điều này vẫn sẽ phục vụ như là sự giúp đỡ

Câu hỏi: Có thể khởi động lại Ứng dụng Android có tên là ClearApplicationUserData () không? Trả lời: Không

Khi bạn gọi clearApplicationUserData (), sau đó gọi phương thức bên dưới.

private void triggerRebirth(Context context) {
     PackageManager packageManager = context.getPackageManager();
     Intent intent = packageManager.getLaunchIntentForPackage(context.getPackageName());
     ComponentName componentName = intent.getComponent();

     Intent mainIntent = Intent.makeRestartActivityTask(componentName);
     context.startActivity(mainIntent);
     Runtime.getRuntime().exit(0);
}

Chúc mừng mã hóa.


-1

Xóa dữ liệu ứng dụng trên thiết bị thông qua API clearApplicationUserData() đặt lại ứng dụng như thể nó vừa được cài đặt. Như bạn đã tìm thấy, mọi báo động và phát sóng được đăng ký với ứng dụng của bạn cũng sẽ bị xóa. Cách hiệu quả nhất để giữ ứng dụng của bạn ở phía trước sẽ là tự xóa dữ liệu, như những người khác đã chỉ ra, thay vì sử dụng API. Dưới đây là một ví dụ: https://stackoverflow.com/a/9073473/949224


Tuy nhiên , nếu bạn quyết tâm sử dụng API (đảm bảo tất cả dữ liệu sẽ bị xóa) và ứng dụng bị dừng lại, tôi có một đề xuất:

Tạo một ứng dụng đồng hành nhỏ có thể được khởi chạy ngay trước khi bạn xóa dữ liệu ứng dụng của mình. Ứng dụng đồng hành chỉ cần khởi chạy lại ứng dụng của bạn, có thể sau một thời gian ngắn.

    Intent launchIntent = getPackageManager().getLaunchIntentForPackage("example.com.testrelaunchapp");
    if (launchIntent != null) {
        startActivity(launchIntent);//null pointer check in case package name was not found
    } else {
        Log.w( TAG, "Unable to resolve launch activity of relauncher companion app");
    }

    ((ActivityManager)getSystemService(Context.ACTIVITY_SERVICE))
                    .clearApplicationUserData();   

Bản thân ứng dụng đồng hành cần phải đóng sau đó và lý tưởng nhất là phải được ẩn khỏi Stack hoạt động, v.v.

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    final Intent launchIntent = getPackageManager().getLaunchIntentForPackage("example.com.yourmainapp");
    if (launchIntent != null) {
        Handler handler = new Handler(getMainLooper());
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                Log.i( TAG, "About to act on launchIntent");
                launchIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                launchIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
                startActivity(launchIntent);
                finish();
                System.exit(0);
            }
        }, 1000);
    }    
 }     

Tôi đã thấy điều này hoạt động với Android 6.0, nhưng không có gì đảm bảo nó sẽ linh hoạt và hoạt động trên bảng. Sẽ còn nhiều việc phải làm để làm cho ứng dụng UI đồng hành trở nên ít hơn nếu muốn và được ẩn khỏi trình khởi chạy điện thoại. Bạn cũng có thể muốn gói APK dưới dạng tệp trong ứng dụng của riêng mình và cài đặt nó ngay lần chạy đầu tiên, điều này sẽ cần người dùng kích hoạt cài đặt từ "Nguồn không xác định" (cửa hàng không chơi). Nó có thể được thực hiện thông qua các ý định cho các cài đặt hệ thống phù hợp, nếu cần, nhưng người dùng sẽ cần một lời giải thích tốt tại sao điều này lại cần thiết.

Vì vậy, như tôi đã nói, cách tiếp cận đơn giản hơn là tự xóa dữ liệu và quyền ứng dụng.


Tôi nghĩ rằng đó không phải là giải pháp khả thi. bởi vì giải pháp của bạn cần các gói cài đặt thêm khiến nó không thể. và nếu chúng tôi có thể có thêm các gói hoặc ứng dụng đồng hành thì sẽ có rất nhiều cách để bắt đầu hoạt động.
Mr.AF

Chắc chắn có thể nhắc người dùng cài đặt ứng dụng khác từ chính bạn. Câu hỏi là liệu bạn có muốn hành vi này là một phần trong cách bạn vận hành. Như tôi đã đề cập, tôi sẽ không đề xuất nó, nhưng nó vẫn xứng đáng để đề cập đến ý tưởng trên nguyên tắc trong trường hợp nó hữu ích cho người khác.
dr_g
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.