Helpex - Trao đổi & giúp đỡ Đăng nhập
41

Vấn đề trong tầm tay : Tôi phải tạo một Servicecái chạy liên tục. Dịch vụ này giám sát 5 ứng dụng, ví dụ như 5 trò chơi android được cài đặt trên điện thoại của bạn. Dịch vụ này cần lấy thông tin về: 1. Trò chơi được mở và chạy bao nhiêu lần? 2. Cho bao nhiêu thời gian mỗi trò chơi đã chạy.

ví dụ: Nói Nếu tôi đã cài đặt dịch vụ này trong ứng dụng của mình. Và tôi đã để nó chạy trong một tháng. Tôi cần thông tin kiểu này trên màn hình của ứng dụng:

Trò chơi Số lần trò chơi được chạy Thời lượng chơi trò chơi

Trò chơi 1 có 20 lần chơi tổng cộng trong 15 giờ

Trò chơi 2 có 16 lần chơi trong tổng cộng 25 giờ

..

..

Trò chơi 5 10 lần được chơi tổng cộng trong 12 giờ

Cách tiếp cận Có thể : Khi một ứng dụng tải, nó sẽ xuất hiện trong bộ nhớ. Lưu ý hệ thống đồng hồ thời gian trong khi ứng dụng khởi động. Và khi ứng dụng kết thúc hoặc được đặt ở chế độ nền, hãy ghi lại thời gian.

Vì vậy, giả sử nếu một ứng dụng được đưa vào bộ nhớ lúc 9:00 tối và thoát ra nền lúc 9:30 tối, tức là thời gian chơi của chúng tôi là 30 phút. Lần tiếp theo ứng dụng được phát, thời lượng sẽ được thêm vào 30 từ lần phát trước đó được lưu trữ trong một số loại biến, v.v. Mỗi khi một ứng dụng được đưa vào bộ nhớ, bộ đếm của nó đang được phát sẽ tăng lên một. Do đó cung cấp cho chúng tôi số lần một ứng dụng được phát.

Mã hóa: Tôi không biết về ServiceAndroid vì tôi chưa bao giờ thực sự làm việc trên chúng. Bất kỳ hướng dẫn nào liên quan đến vấn đề của tôi trong tầm tay sẽ rất hữu ích. Thứ hai, nếu có một cách khác để điều này có thể được thực hiện. Tôi cũng muốn biết điều đó. Tôi thực sự có thể sử dụng một số đoạn mã để bắt đầu dự án này.

41 hữu ích 5 bình luận 37k xem chia sẻ
36

Như bạn đã viết rằng nhiệm vụ là giám sát các ứng dụng của bên thứ 3, không có giải pháp nào khác ngoài việc đọc định kỳ danh sách các quy trình và phát hiện quy trình nền trước . Bạn cần một dịch vụ cho việc này. Rất tiếc, Android không cung cấp các phương tiện như sự kiện phát sóng để thay đổi quy trình nền trước.

Trên thực tế, nhiệm vụ yêu cầu rất nhiều mã, ít nhất là nhiều hơn một câu trả lời thông thường có thể bao gồm. Tôi đang đăng một phần của nó ở đây, nhưng bạn nên giải quyết nhiều sắc thái còn sót lại sau hậu trường, chẳng hạn như đồng bộ hóa và thông tin liên tục giữa các lần khởi chạy. Đây chỉ là một bộ xương.

Đầu tiên, hãy viết mã một đối tượng ứng dụng, đây là một nơi tốt để đăng ký tất cả những thứ liên quan đến phiên bản.

MonitorApp

public class MonitorApp extends Application
{
  // actual store of statistics
  private final ArrayList<HashMap<String,Object>> processList = new ArrayList<HashMap<String,Object>>();

  // fast-access index by package name (used for lookup)
  private ArrayList<String> packages = new ArrayList<String>();

  public ArrayList<HashMap<String,Object>> getProcessList()
  {
    return processList;
  }

  public ArrayList<String> getPackages()
  {
    return packages;
  }

  // TODO: you need to save and load the instance data
  // TODO: you need to address synchronization issues
}

Sau đó, hãy soạn thảo một hoạt động.

MonitorActivity

import static ProcessList.COLUMN_PROCESS_NAME;
import static ProcessList.COLUMN_PROCESS_PROP;
import static ProcessList.COLUMN_PROCESS_COUNT;
import static ProcessList.COLUMN_PROCESS_TIME;

public class MonitorActivity extends Activity implements MonitorService.ServiceCallback
{
  private ArrayList<HashMap<String,Object>> processList;
  private MonitorService backgroundService;
  private MyCustomAdapter adapter = null;
  private ListView listView = null;

  @Override
  public void onCreate(Bundle savedInstanceState)
  {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main); // TODO: provide your layout
    listView = (ListView)findViewById(R.id.id_process_listview);
    createAdapter();

    this.bindService(
      new Intent(this, MonitorService.class),
      serviceConnection,
      Context.BIND_AUTO_CREATE);
  }

  private void createAdapter()
  {
    processList = ((MonitorApp)getApplication()).getProcessList();
    adapter = new MyCustomAdapter(this, processList, R.layout.complex_list_item,
    new String[]
    {
      COLUMN_PROCESS_NAME,
      COLUMN_PROCESS_PROP, // TODO: you may calculate and pre-fill this field
                           // from COLUMN_PROCESS_COUNT and COLUMN_PROCESS_TIME
                           // so eliminating the need to use the custom adapter
    },
    new int[]
    {
      android.R.id.text1,
      android.R.id.text2
    });

    listView.setAdapter(adapter);
  }

  // callback method invoked by the service when foreground process changed
  @Override
  public void sendResults(int resultCode, Bundle b)
  {
    adapter.notifyDataSetChanged();
  }

  private class MyCustomAdapter extends SimpleAdapter
  {
    MyCustomAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to)
    {
      super(context, data, resource, from, to);
    }

    @Override
    public View getView (int position, View convertView, ViewGroup parent)
    {
      View result = super.getView(position, convertView, parent);

      // TODO: customize process statistics display
      int count = (Integer)(processList.get(position).get(COLUMN_PROCESS_COUNT));
      int seconds = (Integer)(processList.get(position).get(COLUMN_PROCESS_TIME));

      return result;
    }
  }

  private ServiceConnection serviceConnection = new ServiceConnection()
  {
    @Override
    public void onServiceConnected(ComponentName className, IBinder service)
    {
      LocalBinder binder = (LocalBinder)service;
      backgroundService = binder.getService();
      backgroundService.setCallback(MonitorActivity.this);
      backgroundService.start();
    }

    @Override
    public void onServiceDisconnected(ComponentName className)
    {
      backgroundService = null;
    }
  };

  @Override
  public void onResume()
  {
    super.onResume();
    if(backgroundService != null)
    {
      backgroundService.setCallback(this);
    }
  }

  @Override
  public void onPause()
  {
    super.onPause();
    if(backgroundService != null)
    {
      backgroundService.setCallback(null);
    }
  }

}

Hoạt động này khởi chạy dịch vụ nhân viên chạy nền, dịch vụ này thực sự giám sát các quy trình. Bạn có thể chuyển đăng ký dịch vụ từ hoạt động vào phiên bản ứng dụng. Bản thân dịch vụ là một cái gì đó như thế này:

MonitorService

public class MonitorService extends Service
{
  private boolean initialized = false;
  private final IBinder mBinder = new LocalBinder();
  private ServiceCallback callback = null;
  private Timer timer = null;
  private final Handler mHandler = new Handler();
  private String foreground = null;
  private ArrayList<HashMap<String,Object>> processList;
  private ArrayList<String> packages;
  private Date split = null;

  public static int SERVICE_PERIOD = 5000; // TODO: customize (this is for scan every 5 seconds)

  private final ProcessList pl = new ProcessList(this)
  {
    @Override
    protected boolean isFilteredByName(String pack)
    {
      // TODO: filter processes by names, return true to skip the process
      // always return false (by default) to monitor all processes
      return false;
    }

  };

  public interface ServiceCallback
  {
    void sendResults(int resultCode, Bundle b);
  }

  public class LocalBinder extends Binder
  {
    MonitorService getService()
    {
      // Return this instance of the service so clients can call public methods
      return MonitorService.this;
    }
  }

  @Override
  public void onCreate()
  {
    super.onCreate();
    initialized = true;
    processList = ((MonitorApp)getApplication()).getProcessList();
    packages = ((MonitorApp)getApplication()).getPackages();
  }

  @Override
  public IBinder onBind(Intent intent)
  {
    if(initialized)
    {
      return mBinder;
    }
    return null;
  }

  public void setCallback(ServiceCallback callback)
  {
    this.callback = callback;
  }

  private boolean addToStatistics(String target)
  {
    boolean changed = false;
    Date now = new Date();
    if(!TextUtils.isEmpty(target))
    {
      if(!target.equals(foreground))
      {
        int i;
        if(foreground != null && split != null)
        {
          // TODO: calculate time difference from current moment
          // to the moment when previous foreground process was activated
          i = packages.indexOf(foreground);
          long delta = (now.getTime() - split.getTime()) / 1000;
          Long time = (Long)processList.get(i).get(COLUMN_PROCESS_TIME);
          if(time != null)
          { 
            // TODO: add the delta to statistics of 'foreground' 
            time += delta;
          }
          else
          {
            time = new Long(delta);
          }
          processList.get(i).put(COLUMN_PROCESS_TIME, time);
        }

        // update count of process activation for new 'target'
        i = packages.indexOf(target);
        Integer count = (Integer)processList.get(i).get(COLUMN_PROCESS_COUNT);
        if(count != null) count++;
        else
        {
          count = new Integer(1);
        }
        processList.get(i).put(COLUMN_PROCESS_COUNT, count);

        foreground = target;
        split = now;
        changed = true;
      }
    }
    return changed; 
  }


  public void start()
  {
    if(timer == null)
    {
      timer = new Timer();
      timer.schedule(new MonitoringTimerTask(), 500, SERVICE_PERIOD);
    }

    // TODO: startForeground(srvcid, createNotification(null));
  }

  public void stop()
  {
    timer.cancel();
    timer.purge();
    timer = null;
  }

  private class MonitoringTimerTask extends TimerTask
  {
    @Override
    public void run()
    {
      fillProcessList();

      ActivityManager activityManager = (ActivityManager)MonitorService.this.getSystemService(ACTIVITY_SERVICE);
      List<RunningTaskInfo> taskInfo = activityManager.getRunningTasks(1);
      String current = taskInfo.get(0).topActivity.getPackageName();

      // check if current process changed
      if(addToStatistics(current) && callback != null)
      {
        final Bundle b = new Bundle();
        // TODO: pass necessary info to UI via bundle
        mHandler.post(new Runnable()
        {
          public void run()
          {
            callback.sendResults(1, b);
          }
        });
      }
    }
  }

  private void fillProcessList()
  {
    pl.fillProcessList(processList, packages);
  }

}

Dịch vụ sử dụng một lớp người trợ giúp để xây dựng danh sách quy trình.

ProcessList

public abstract class ProcessList
{
  // process package name
  public static final String COLUMN_PROCESS_NAME = "process";

  // TODO: arbitrary property (can be user-fiendly name)
  public static final String COLUMN_PROCESS_PROP = "property";

  // number of times a process has been activated
  public static final String COLUMN_PROCESS_COUNT = "count";

  // number of seconds a process was in foreground
  public static final String COLUMN_PROCESS_TIME = "time";

  private ContextWrapper context;

  ProcessList(ContextWrapper context)
  {
    this.context = context;
  }

  protected abstract boolean isFilteredByName(String pack);

  public void fillProcessList(ArrayList<HashMap<String,Object>> processList, ArrayList<String> packages)
  {
    ActivityManager activityManager = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
    List<RunningAppProcessInfo> procInfo = activityManager.getRunningAppProcesses();

    HashMap<String, Object> hm;
    final PackageManager pm = context.getApplicationContext().getPackageManager();

    for(int i = 0; i < procInfo.size(); i++)
    {
      String process = procInfo.get(i).processName;
      String packageList = Arrays.toString(procInfo.get(i).pkgList);
      if(!packageList.contains(process))
      {
        process = procInfo.get(i).pkgList[0];
      }

      if(!packages.contains(process) && !isFilteredByName(process))
      {
        ApplicationInfo ai;
        String applicationName = "";

        for(int k = 0; k < procInfo.get(i).pkgList.length; k++)
        {
          String thisPackage = procInfo.get(i).pkgList[k];
          try
          {
            ai = pm.getApplicationInfo(thisPackage, 0);
          }
          catch(final NameNotFoundException e)
          {
            ai = null;
          }
          if(k > 0) applicationName += " / ";
          applicationName += (String)(ai != null ? pm.getApplicationLabel(ai) : "(unknown)");
        }

        packages.add(process);
        hm = new HashMap<String, Object>();
        hm.put(COLUMN_PROCESS_NAME, process);
        hm.put(COLUMN_PROCESS_PROP, applicationName);
        processList.add(hm);
      }
    }

    // optional sorting
    Comparator<HashMap<String, Object>> comparator = new Comparator<HashMap<String, Object>>()
    {
      public int compare(HashMap<String, Object> object1, HashMap<String, Object> object2) 
      {       
        return ((String)object1.get(COLUMN_PROCESS_NAME)).compareToIgnoreCase((String)object2.get(COLUMN_PROCESS_NAME));
      }
    };
    Collections.sort(processList, comparator);

    packages.clear();
    for(HashMap<String, Object> e : processList)
    {
      packages.add((String)e.get(COLUMN_PROCESS_NAME));
    }
  }

}

Cuối cùng là bản kê khai.

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.yourpackage"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="18" />

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

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".MonitorActivity"
            android:label="@string/app_name"
            android:configChanges="orientation|keyboardHidden" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name=".MonitorService" />
    </application>

</manifest>

Như bạn có thể thấy, nó đã có rất nhiều mã. Nó được trích xuất một phần từ một ứng dụng đang hoạt động, nhưng tôi đã thực hiện các thay đổi nhanh chóng cho nhu cầu của bạn, vì vậy có thể có lỗi chính tả, tất cả các lần nhập đều bị bỏ qua, v.v. Tuy nhiên, tôi hy vọng điều này sẽ giúp được một chút.

BỔ SUNG: Kẹo mút +

Hãy cẩn thận: các phiên bản Android mới nhất đã phá vỡ cách tiếp cận nói trên. Đây là những gì tài liệu chính thức nói về phương thức getRunningTasks và các phương pháp khác:

Kể từ LOLLIPOP, phương pháp này không còn khả dụng đối với các ứng dụng của bên thứ ba nữa: việc giới thiệu các nội dung gần đây tập trung vào tài liệu có nghĩa là nó có thể làm rò rỉ thông tin người cho người gọi. Đối với khả năng tương thích ngược, nó vẫn sẽ retu rn một tập con nhỏ dữ liệu của nó: ít nhất là các tác vụ của riêng người gọi và có thể là một số tác vụ khác như home được biết là không nhạy cảm.

Tôi nghĩ đây là một việc làm quá mức cần thiết và có thể được thực hiện theo cách chọn lọc và thuận tiện hơn nhiều. Chưa kể rằng điều này có vẻ quá sân khấu khi xem xét nhiều tính năng được tích hợp sẵn từ Google với những lo ngại về quyền riêng tư. Dù sao, chúng tôi không thể làm gì với điều này.

Cách giải quyết duy nhất là triển khai dịch vụ trợ năng của Android (thông tin thêm tại đâytại đây ) và chặn tất cả các hành động với các ứng dụng tăng và mất tập trung từ đó. Người dùng nên kích hoạt dịch vụ theo cách thủ công! Ứng dụng của bạn bằng cách nào đó sẽ hướng người dùng làm như vậy.

36 hữu ích 3 bình luận chia sẻ
10

Suy nghĩ của tôi,

  1. Phát triển ứng dụng đặt một số dữ liệu của họ ở chế độ công khai đối với quy trình khác để truy cập chúng.

    Google "Cách sử dụng các nhà cung cấp nội dung ".

    Mỗi ứng dụng của bạn sẽ cần phải ghi lại tất cả các hoạt động mà họ đã thực hiện. Dữ liệu này sẽ được công khai để được truy cập.

  2. Bạn không cần phải chạy một dịch vụ mọi lúc cho việc này. Bất cứ khi nào ứng dụng giám sát của bạn được mở. Nó chỉ cần lấy dữ liệu đó từ tất cả các ứng dụng bạn muốn và hiển thị chúng cho phù hợp.

  3. Đối với trường hợp bạn muốn gửi dữ liệu đó trên máy chủ định kỳ trong nền. Sau đó, bạn cần một dịch vụ . Nhưng bạn vẫn không cần phải chạy nó mãi mãi . Làm một cái gì đó như thế này.

    i) Từ dịch vụ tìm nạp dữ liệu và tải lên máy chủ.

    ii) Dừng dịch vụ và lên lịch báo động sau một thời gian T1 để bắt đầu lại dịch vụ của riêng bạn để thực hiện lại bước 1.

    iii) T1 phụ thuộc vào yêu cầu. Cách làm mới dữ liệu bạn muốn trên máy chủ.

Tôi thậm chí có thể cho bạn biết con trỏ đoạn mã nếu bạn muốn biết cách triển khai những gì tôi đã nói ở trên. Nhưng tôi khuyên bạn nên tìm điều đó trên google và tự làm điều đó trước. Đăng một câu hỏi cụ thể khác trên StackOverflow nếu bạn gặp bất kỳ khó khăn nào trong đó.

Hi vọng điêu nay co ich. :)

Biên tập:

Thứ nhất. Cuối cùng chỉ có bạn là người phải viết mã. Lấy con trỏ và giúp đỡ từ đây. Đừng mong đợi mã đầy đủ. Kiểm tra thêm chi tiết bên dưới.

A)

Bạn cần đặt ứng dụng của mình làm Nhà cung cấp nội dung. Kiểm tra liên kết bên dưới. và làm theo các ví dụ trong đó. Bạn sẽ kết thúc trong một ứng dụng có dữ liệu sẽ có sẵn cho những người khác. Nó dễ dàng đi về phía trước.

http://developer.android.com/guide/topics/providers/content-providers.html

http://developer.android.com/guide/topics/providers/content-provider-creating.html

http://www.vogella.com/articles/AndroidSQLite/article.html

Tất cả ứng dụng trò chơi của bạn cần công khai dữ liệu để có thể truy cập. Bây giờ một khi bạn đã hoàn thành việc này.

Bây giờ bạn chỉ cần truy cập tất cả dữ liệu trong ứng dụng giám sát của mình và hiển thị nó.

B)

Như tôi đã nói nếu bạn muốn làm điều này thông qua dịch vụ. Bạn không cần phải chạy nó mãi mãi. Chỉ cần khởi động dịch vụ một lần, tải dữ liệu từ nhà cung cấp nội dung và làm bất cứ điều gì bạn muốn. Đặt báo thức để gọi dịch vụ ở giai đoạn sau để thực hiện lại thao tác tương tự.

Tôi giả định nếu cứ sau 10 phút, dịch vụ của bạn có thể tìm nạp dữ liệu từ nhà cung cấp nội dung (Ứng dụng trò chơi của bạn mà bạn muốn theo dõi). Nó sẽ như sau.

public class MonitoringService extends Service {

    private static final String ACTION_FETCH = "action_fetch";
    private static final int REPEAT_DATALOAD_INTERVAL_MS = 10 * 60 * 1000; // 10 Min

    private static PendingIntent makeSelfPendingIntent(Context context) {
        PendingIntent intent = PendingIntent.getService(
                           context, 0, makeSelfIntent(context), 0);
        return intent;
    }

    private static Intent makeSelfIntent(Context context) {
        Intent intent = new Intent(context, MonitoringService.class);
        intent.setAction(ACTION_FETCH);
        return intent;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        if (intent != null && intent.getAction() != null) {
            String action = intent.getAction();
            if (action.equals(ACTION_FETCH)) {
                loadDataFromContentProviderDoWhateverYouWantThen();
                setAlarmToRedoLoad();
                stopSelf();

            }
        }
        return Super.onStartCommand(intent, flags, startId);
    }

    private void setAlarmToRedoLoad() {
        AlarmManager alarmManager = (AlarmManager) 
                                     getSystemService(Context.ALARM_SERVICE);
        alarmManager.set(AlarmManager.RTC_WAKEUP,
                     System.currentTimeMillis() + REPEAT_DATALOAD_INTERVAL_MS,
                     makeSelfPendingIntent(getApplicationContext()));
    }

    private void loadDataFromContentProviderDoWhateverYouWantThen(){
        check this link how to load data from content provider.
        as your games app are content providers. It should be loaded easily.
        then do whatever you want display, upload anything

        http://developer.android.com/guide/topics/providers/content-provider-basics.html
    }

    // Call this method from onCreate of your monitoring app
    public static void start(Context context) {
        Intent intent = makeSelfIntent(context);
        context.startService(intent);
    }

}

C) đảm bảo rằng bạn cho phép người dùng ứng dụng giám sát của mình dừng dịch vụ này bất cứ lúc nào. Đừng quên hủy báo thức trong trường hợp đó. vì vậy nó không chạy trong nền mãi mãi.

D) Bạn cũng có thể làm cho mọi thứ được phát sóng dựa trên. Bất cứ khi nào ứng dụng trò chơi của bạn lưu dữ liệu, họ sẽ phát sự kiện này và cho phép dịch vụ của bạn được gọi sau khi nghe chương trình phát sóng đó. tải nó sau đó chỉ.

E) Như Phill cũng đã nói rằng bạn cũng có thể sử dụng Google Analytics.

Bạn muốn thực hiện điều này như thế nào bây giờ phụ thuộc vào yêu cầu của bạn

Hi vọng điêu nay co ich. Hãy dùng thử và cho tôi biết bạn đang gặp phải vấn đề gì khác

10 hữu ích 2 bình luận chia sẻ
1

Sử dụng mã ví dụ này để kiểm tra xem trình duyệt có đang chạy hay không

ActivityManager activityManager = (ActivityManager) this.getSystemService( ACTIVITY_SERVICE );
    List<RunningAppProcessInfo> procInfos = actvityManager.getRunningAppProcesses();
    for(int i = 0; i < procInfos.size(); i++){
        if(procInfos.get(i).processName.equals("com.android.browser")) {
            Toast.makeText(getApplicationContext(), "Browser is running", Toast.LENGTH_LONG).show();
        }
    }

Để tạo một dịch vụ, bạn phải tạo một lớp mở rộng từ lớp cơ sở Dịch vụ và thực hiện hàm trong một vòng lặp vô hạn chẳng hạn như while(true)trong onStartCommand()hàm. đừng quên thêm dịch vụ của bạn vào tệp kê khai giữa <service></service>các thẻ, một hướng dẫn hay có trên http://www.vogella.com/articles/AndroidServices/article.html

1 hữu ích 0 bình luận chia sẻ
1

Để có được ứng dụng đang chạy hiện tại, bạn có thể sử dụng:

ActivityManager am = (ActivityManager) mContext.getSystemService(Activity.ACTIVITY_SERVICE);
String packageName = am.getRunningTasks(1).get(0).topActivity.getPackageName();

Bạn có thể kiểm tra điều này định kỳ từ dịch vụ đang chạy của mình. Bạn cũng sẽ cần xác định một quyền bắt buộc trong tệp kê khai của mình:android.permission.GET_TASKS

1 hữu ích 1 bình luận chia sẻ
0

Các giải pháp sau dựa trên giả định rằng bạn sở hữu tất cả năm ứng dụng mà bạn đang cố gắng giám sát. Nếu nó khác khôn ngoan, tôi sẽ cung cấp cho bạn một giải pháp khác.

Hãy phân tích vấn đề ngay bây giờ.

  1. Dịch vụ thông tin về ứng dụng đang chạy hay không.
  2. Dịch vụ thiết kế
  3. lưu trữ dữ liệu

Bạn nên sử dụng Intentđể phát thông báo về việc ứng dụng của bạn có đang chạy hay không. Sử dụng hoạt động onPauseonResumeđể phát tin nhắn.

Bây giờ hãy gọi hàm này từ onPause và onResume,

   public void broadcastMessage(String method_name){
        Intent intent=new Intent("com.service.myservice");
        Bundle bundle=new Bundle();
        bundle.putString("app_name", this.getApplicationInfo().packageName);
        bundle.putLong("time", System.currentTimeMillis());
            //just to keep track if it is on pause or in on resume
        bundle.putString("method", method_name);
        intent.putExtras(bundle);
        this.startService(intent);
    }

và bạn có thể gọi điều này như cách sau

public void onPause(){
        super.onPause();
        broadcastMessage(Thread.currentThread().getStackTrace()[1].getMethodName());
    }

Hoặc là

public void onPause(){
        super.onPause();
        broadcastMessage("onPause");
    }

Vì vậy, tại sao onPause và onResume vì game thủ chỉ chơi trò chơi giữa các lần gọi hàm này.

Dịch vụ thiết kế

Sử dụng IntentServicevà đọc phần này nếu bạn muốn biết tại sao.

@Override
    protected void onHandleIntent(Intent intent) {
        // TODO Auto-generated method stub
        Bundle bundle=intent.getExtras();
        String app_name=bundle.getString("app_name");
        long time=bundle.getLong("time");
        //then do whatever you wanna do with this data

    }

Lưu trữ

ContentProviderlà một lựa chọn tốt để lưu trữ dữ liệu và nó cũng rất mạnh mẽ; tích hợp và mở rộng tốt trên Android, nhưng trong trường hợp này có vẻ như bạn chỉ muốn lưu trữ một số thông tin rất đơn giản và như vậy, bạn cũng có thể chọn một cái gì đó rất đơn giản.

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

 protected void storeData(String app_name, long time) {
        if ((app_name==null)||(time<=0)) return;
        SharedPreferences sharedPreferences = PreferenceManager .getDefaultSharedPreferences(getApplicationContext());
        Editor editor = sharedPreferences.edit();
              //concatenating app name just to make key unique
        long start_time=sharedPreferences.getLong(app_name+"_start_time", -1);
        if (start_time==-1){
            //start time is empty means this is my start time
            // and user just started the app
            editor.putLong(app_name+"_start_time", time);
            editor.putLong(app_name+"_counter", sharedPreferences.getLong(app_name+"_counter", 0)+1);
        }else{
            //user is now closing the app. 
            long time_played=time-start_time;
            long total_time=sharedPreferences.getLong(app_name+"_total_time", 0);
            total_time=total_time+time_played;
            //saving total time
            editor.putLong(app_name+"_total_time", time);
            //removing start time for next pass
            editor.remove(app_name+"_start_time");
        }
        editor.commit();
    }
    public long getTotalTimeUserSpent(String app_name){
        SharedPreferences sharedPreferences = PreferenceManager .getDefaultSharedPreferences(getApplicationContext());
        return sharedPreferences.getLong(app_name+"_total_time", 0);
    }
    public long numberOfTimeUserPlayed(String app_name){
        SharedPreferences sharedPreferences = PreferenceManager .getDefaultSharedPreferences(getApplicationContext());
        return sharedPreferences.getLong(app_name+"_counter", 0);
    }

chỉ cần gọi các phương thức này từ onHandleIntent.

Mảnh ghép cuối cùng sẽ được phân phối. Bạn có thể phân phối điều này trên một ứng dụng riêng biệt hoặc một phần của năm ứng dụng này. Các ứng dụng riêng biệt là cách dễ dàng nhất để thực hiện. Nhưng nếu bạn chọn sử dụng ứng dụng này như một phần của cả năm ứng dụng này, hãy đọc cuộc thảo luận này .

0 hữu ích 0 bình luận chia sẻ
-4

Cài đặt Covenant Eyes trên thiết bị Android của bạn sẽ giám sát tất cả lưu lượng truy cập Internet trên trình duyệt được cài đặt sẵn của điện thoại và báo cáo các ứng dụng bổ sung đang được sử dụng trên thiết bị.

-4 hữu ích 0 bình luận chia sẻ
loading
Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ android service usage statistics , hoặc hỏi câu hỏi của bạn.

Có thể bạn quan tâm

loading