Android, Phát hiện khi các ứng dụng khác được khởi chạy


92

Tôi đang cố gắng phát triển một ứng dụng ngăn người dùng truy cập vào một ứng dụng cụ thể mà không có mật khẩu. Kịch bản là ...

  1. người dùng nhấp vào ứng dụng "Email" (ví dụ)
  2. ứng dụng của tôi phát hiện khởi chạy một ứng dụng
  3. ứng dụng của tôi xác nhận đó là ứng dụng "Email"
  4. ứng dụng của tôi mở ra một chế độ xem ở trên cùng, yêu cầu mật khẩu
  5. người dùng nhập mật khẩu, nếu đúng, ứng dụng của tôi sẽ biến mất, để lại ứng dụng "Email" ở trên cùng

Tôi không sao làm nốt phần còn lại, chỉ là phần 2 khiến tôi khó hiểu, và sau nhiều ngày đọc trên Broadcast Intents, v.v. và cố gắng nghe "android.intent.action.MAIN" v.v. trong các dự án thử nghiệm của mình, tôi không thể dường như phát hiện khi một ứng dụng không phải của tôi được khởi động.

Có ai giúp được không? Tôi có đang đi đúng cách không, khi tìm kiếm các ứng dụng mới đang phát đi ý định bắt đầu, hay tôi nên đọc nhật ký hệ thống để biết ý định mới hoặc làm điều gì đó trong mã gốc?

Mọi gợi ý sẽ hữu ích, ngay cả khi bạn không thể trả lời đầy đủ, tôi sẽ có thể thực hiện thêm một số nghiên cứu. Cảm ơn rất nhiều. Ian


Tôi không chắc họ đã làm điều đó như thế nào, nhưng các ứng dụng như App Protector thực hiện chính xác những gì bạn đang yêu cầu, vì vậy về mặt kỹ thuật thì điều đó thực sự có thể xảy ra.
hanspeide vào

@lan bạn đã giải quyết vấn đề của mình như thế nào, bạn có thể vui lòng chia sẻ kiến ​​thức của bạn không
nida

chào bạn đã có giải pháp?
ask4solutions

Câu trả lời:


34

Tôi nghĩ chúng ta có thể sử dụng logcat và phân tích đầu ra của nó.

Trong tất cả các chương trình tương tự, tôi đã tìm thấy quyền này:

android.permission.READ_LOGS

Có nghĩa là tất cả chúng đều sử dụng nó nhưng có vẻ như chương trình bắt đầu và sau đó chương trình của chúng tôi (trình bảo vệ ứng dụng) sẽ bắt đầu và hoạt động.

Sử dụng mã dưới đây:

try
    {
        Process mLogcatProc = null;
        BufferedReader reader = null;
        mLogcatProc = Runtime.getRuntime().exec(new String[]{"logcat", "-d"});

        reader = new BufferedReader(new InputStreamReader(mLogcatProc.getInputStream()));

        String line;
        final StringBuilder log = new StringBuilder();
        String separator = System.getProperty("line.separator"); 

        while ((line = reader.readLine()) != null)
        {
            log.append(line);
            log.append(separator);
        }
        String w = log.toString();
        Toast.makeText(getApplicationContext(),w, Toast.LENGTH_LONG).show();
    }
    catch (Exception e) 
    {
        Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
    }

Và đừng quên thêm quyền đó vào tệp Manifest.


làm ơn, chúng tôi phải đặt mã này ở đâu? trong một dịch vụ? trong onStartCommand ()?
haythem souissi

56
sẽ không hoạt động từ JellyBean trở lên. Quyền READ_LOGS hiện chỉ dành cho các ứng dụng hệ thống.
Ran

5
Bạn có hoàn toàn chắc chắn về điều này? Vì Smart AppLock dường như có thể thực hiện điều này ngay cả trên các thiết bị JB. Có phải vì ứng dụng tự nâng cấp lên trạng thái Quản trị viên thiết bị không? play.google.com/store/apps/…
Karthik Balakrishnan

1
@Torcellite, ứng dụng đó có quyền "Nhận các tác vụ đang chạy", vì vậy nó có thể đang sử dụng kỹ thuật đó thay thế.
Sam

1
@Ran vậy phải làm gì để sử dụng nó bây giờ ... hiện có giải pháp nào để giải quyết vấn đề được nêu trong câu hỏi vì tôi cần phải ở trên đậu thạch ... vui lòng phản hồi của bạn
càng sớm càng tốt

19

Một cách phô trương để làm điều đó là có một dịch vụ với vòng lặp định thời để kiểm tra

ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> runningAppProcessInfo = am.getRunningAppProcesses();

Bạn chạy qua danh sách đó để xem những gì đang chạy trên điện thoại. Giờ đây, bạn có thể xác định chúng bằng id và processName, vì vậy, đối với hoạt động tiêu chuẩn, điều này rất dễ dàng đối với các tùy chỉnh trừ khi bạn dừng chúng lại, rất khó để phân biệt ...

Lưu ý: đây không phải là danh sách những gì đang thực sự xuất hiện trên màn hình, chỉ là danh sách những gì đang chạy ... đại loại là có thể vô hiệu hóa mục tiêu của bạn nhưng ít nhất bạn sẽ biết khi nào có thứ gì đó bắt đầu chạy ... nó sẽ tiếp tục ở trong đó danh sách ngay cả khi ở chế độ nền.

Đối với mật khẩu, bạn chỉ có thể bắt đầu hoạt động của mình khi bạn tìm thấy một ứng dụng được bảo vệ hoặc bất cứ thứ gì.


Có thể lấy được thời gian khi ứng dụng được khởi chạy / tiếp tục lại không?
0LLiena

4
Trong Android L sử dụng android.app.usagegói thay thế. developer.android.com/reference/android/app/usage/…
Plo_Koon

12

Tôi nghĩ và hy vọng điều này là không thể. Hãy xem xét chức năng như vậy có thể bị lạm dụng bởi phần mềm độc hại dễ dàng như thế nào. Bạn có thể lắng nghe ý định hướng đến bạn và những ý định được truyền phát, nhưng khởi chạy ứng dụng không nên là một sự kiện phát sóng.

Những gì bạn có thể làm là thay thế trình khởi chạy . Nếu người dùng đồng ý với nó.


1
Tại sao nó không thể được? Đó là thiết bị của tôi và tôi quyết định sẽ chạy gì trên nó. Làm thế nào đây là một vấn đề nhiều hơn các quyền khác mà chúng tôi cấp thường xuyên? Trình khởi chạy thay thế sẽ không bắt đầu khởi chạy tất cả các ứng dụng chỉ những ứng dụng do nó khởi chạy trực tiếp. Có nhiều bình luận về vấn đề này và các chủ đề tương tự trên SO tuyên bố rằng việc có thể đơn giản nhìn thấy ý định sẽ là một vấn đề lớn nhưng không ai giải thích vấn đề là gì và tại sao nó lại bị coi là khó chịu đến mức hệ thống đặc quyền hiện có không thể được sử dụng để làm cho người dùng hiểu rõ điều gì đang xảy ra.
Kevin Whitefoot

Khi các quyền tiềm năng đi, đây là một sự ngu ngốc. Điểm của việc có một mô hình bảo mật là cho phép hầu hết các trường hợp sử dụng hợp pháp, đồng thời ngăn chặn hầu hết (lý tưởng là tất cả) việc khai thác. Không chỉ bạn (có lẽ là một người dùng hiểu biết) cần được bảo vệ mà còn cả những người dùng ngây thơ cài đặt ứng dụng và người viết ứng dụng không cần phải xem xét thêm một phương tiện tấn công khác. Tất cả bảo mật là sự cân bằng: trong trường hợp này, giữa tiện ích và sức mạnh so với khả năng khai thác lớn. Bạn có thể tự do sao chép ngăn xếp Android và viết mã hệ thống của riêng mình nếu bạn thực sự muốn mức độ tự do đó cho chính mình.
Pontus Gpris

12
class CheckRunningActivity extends Thread{
    ActivityManager am = null;
    Context context = null;

    public CheckRunningActivity(Context con){
        context = con;
        am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    }

    public void run(){
        Looper.prepare();

        while(true){
            // Return a list of the tasks that are currently running,
            // with the most recent being first and older ones after in order.
            // Taken 1 inside getRunningTasks method means want to take only
            // top activity from stack and forgot the olders.
            List< ActivityManager.RunningTaskInfo > taskInfo = am.getRunningTasks(1);

            String currentRunningActivityName = taskInfo.get(0).topActivity.getClassName();

            if (currentRunningActivityName.equals("PACKAGE_NAME.ACTIVITY_NAME")) {
                // show your activity here on top of PACKAGE_NAME.ACTIVITY_NAME
            }
        }
        Looper.loop();
    }
}

Bạn có thể xem hiện tại đang chạy Activityvà kiểm tra xem điều này có Activitytương ứng với Email ứng dụng hay không.

Chạy CheckRunningActivity Threadtrên Applicationđầu (hoặc khi khởi động thiết bị).

new CheckRunningActivity().start();

Cập nhật: Lớp này cần android.permission.GET_TASKSquyền, vì vậy hãy thêm dòng tiếp theo vào Tệp kê khai:

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

Tôi đang sử dụng phương pháp này nhưng cách này sẽ mở đi mở lại "// hiển thị hoạt động của bạn ở đây trên PACKAGE_NAME.ACTIVITY_NAME" do vòng lặp. Bất kỳ giải pháp nào cho điều đó?
Anuj Sharma

dừng CheckRunningActivity thread khi bạn nhận được kết quả mong muốn
Veaceslav Gaidarji

Cảm ơn bạn đã trả lời, sau đó làm thế nào / khi chuỗi này được khởi động lại lần nữa? Tôi đang sử dụng Dịch vụ cố định.
Anuj Sharma,

tùy thuộc vào bối cảnh của vấn đề, hãy mô tả chi tiết hơn những gì bạn muốn nhận được.
Veaceslav Gaidarji

2
Trong mã của bạn ở đây, Looper.loop()câu lệnh có vẻ như nó sẽ không bao giờ được thực thi do while(true)vòng lặp không bao giờ kết thúc. Đây có phải là một sai lầm?
Sam

11

Vấn đề chính là bạn đang cố gắng lắng nghe ý định ngầm khi Trình khởi chạy (màn hình chính) thường sử dụng ý định rõ ràng.

Ý định ngầm là khi bạn muốn nói "Ai đó phát video này" và Android chọn một ứng dụng có thể xử lý ý định đó.

Ý định rõ ràng là những gì sẽ xảy ra khi bạn nhấp vào biểu tượng "Email" trên màn hình chính. Nó đặc biệt yêu cầu Android mở ứng dụng cụ thể đó bằng tên đủ điều kiện (tức là com.android.mail hoặc một cái gì đó).

Không có cách nào AFAIK để chặn những ý định rõ ràng như vậy. Đó là một biện pháp bảo mật được tích hợp trong Android mà không có hai Hoạt động nào có thể có cùng tên gói đủ điều kiện. Điều này ngăn bên thứ ba sao chép ứng dụng và giả mạo là ứng dụng đó. Nếu điều bạn muốn làm là có thể, về mặt lý thuyết, bạn có thể cài đặt một ứng dụng có thể chặn tất cả các ứng dụng của đối thủ cạnh tranh hoạt động.

Những gì bạn đang cố gắng làm đi ngược lại với mô hình bảo mật của Android.

Một điều bạn có thể làm là hợp tác với các nhà phát triển ứng dụng cụ thể để chuyển tiếp ý định đến hệ thống bảo mật của bạn, nhưng đó có thể không phải là điều bạn muốn giải quyết.


7

getRunningTasks() không được dùng nữa trong Android L.

Để có được thống kê sử dụng ứng dụng, bạn có thể sử dụng lớp UsageStats từ gói android.app.usage .

API thống kê sử dụng ứng dụng mới cho phép nhà phát triển ứng dụng thu thập số liệu thống kê liên quan đến việc sử dụng ứng dụng. API này cung cấp thông tin sử dụng chi tiết hơn so với phương thức getRecentTasks () không dùng nữa.

Để sử dụng API này, trước tiên bạn phải khai báo android.permission.PACKAGE_USAGE_STATSquyền trong tệp kê khai của mình. Người dùng cũng phải kích hoạt quyền truy cập cho ứng dụng này thông qua Settings > Security > Apps with usage access.

Dưới đây là ví dụ ứng dụng cơ bản cho thấy cách sử dụng API thống kê sử dụng ứng dụng để cho phép người dùng thu thập số liệu thống kê liên quan đến việc sử dụng ứng dụng.


thống kê sử dụng có thể giúp ích như thế nào trong việc biết rằng ứng dụng nào đang ở nền tảng?
Ajay

3

Có lẽ bạn cần một dịch vụ, một thứ gì đó sẽ chạy trong nền liên tục. Hơn để dịch vụ của bạn làm những gì bạn đã nói. Nghe cho android.intent.action.MAIN cũng với danh mục android.intent.category.LAUNCHER. Sau đó, yêu cầu bộ thu phát sóng đó ghi đè phương thức onReceive và kiểm tra xem tên của ứng dụng, v.v.


2
Điều này nghe có vẻ giống như phương pháp tôi đã nghĩ đến, nhưng tôi đang đấu tranh để nhận chương trình phát CHÍNH (mèo. LAUNCHER) với một BroadcastReceiver cơ bản. Có ai quản lý để làm điều này trước đây? Ở giai đoạn này, tôi chỉ muốn phát hiện một ứng dụng đã được khởi chạy hoặc tiếp tục lại. Sau đó, tôi có thể so sánh tên gói với một chuỗi chứa (các) tên mà tôi đang tìm kiếm.
Ian
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.