1

オンラインデータバージョンが更新されているかどうかを確認するサービスによって開始される Android ブロードキャストレシーバー (重要な場合は Eclipse を使用) があります。もしそうなら、通知バーで通知をトリガーしたいと思います。

すべてが正常に機能しているように見えますが、SharedPreferences から得られる結果は信頼できません。ブロードキャスト レシーバーは、SharedPreferences に保存されている現在の値を取得し、それを Web URL から取得した値と比較すると想定されています。値を比較し、更新が行われたことを確認した場合 (つまり、URL の値が保存された値より大きい場合)、通知をトリガーし、SharedPreferences に保存された値も更新します。ブロードキャスト レシーバーは、この更新を 1 日に 1 回チェックします。これは、ユーザーに通知することのみを目的としており、それ以上のものではありません。

これを行うために使用しているコードは機能しているようです。しかし、あちこちで、何も変更されていないにもかかわらず、SharedPreferences からデフォルト値を取得し、更新通知をトリガーします。

ブロードキャストレシーバーの onReceive でやりすぎている可能性があることは認識していますが、ブロードキャストレシーバーから作業を行うアクティビティを起動する方法について非常に混乱しています。

これを実装するための最良の方法のコード例はありますか? 検索して検索しましたが、どちらの方法でもこれを行うための明確な手順が見つからないようです。ここに私が持っているものがあります:

public class AlarmReceiver extends BroadcastReceiver {

    public static JSONArray myJArray2;
    public static InputStream is = null;
    public static final String URL_DatabaseVersion = "http://www.mysite.com/mobile/version.php";
    public static NotificationManager nm;
    public static Boolean updated = false;
    public static int latestVersion = 0;
    public static int internalVersion = 2;

    public static final String PREFS_NAME = "MyPrefsFile";

    @Override
    public void onReceive(Context context, Intent intent) {

        updated = false;
        SharedPreferences settings = context.getSharedPreferences(PREFS_NAME, 0);
        internalVersion = settings.getInt("dataversion", 1); 

        InputStream is = null;
        String result = "";
        ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
        nameValuePairs.add(new BasicNameValuePair("",""));

        try{
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost(URL_DatabaseVersion);
            httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); 
            HttpResponse response = httpclient.execute(httppost);
            HttpEntity entity = response.getEntity();
            is = entity.getContent();
        }catch(Exception e){
        }

        try{
            BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) 
            {
                sb.append(line + "\n");
            }
            is.close();
            result=sb.toString();
        }catch(Exception e){
        }

        try{
            JSONArray myJArray = new JSONArray(result);
            myJArray2 = myJArray;
        }catch(JSONException e){
        }     

        int mode = Activity.MODE_PRIVATE;
        SharedPreferences mySharedPreferences = context.getSharedPreferences("MyPrefsFile",mode);           
        SharedPreferences.Editor editor = mySharedPreferences.edit();
        editor.putInt ("dataversion", latestVersion);
        editor.commit();

        if (!Arrays.asList(myJArray2).contains(null))   
        {
            try{
                for(int i=0;i<myJArray2.length();i++)
                {
                    JSONObject json_data = myJArray2.getJSONObject(i);
                    latestVersion = json_data.getInt("title");

                    if (internalVersion < latestVersion)
                    {
                        updated = true;
                    } 
                    else
                    {
                        updated = false;
                    }
                }
            }
            catch(Exception e)
            {}
            finally
            {}
        }
        else
        {
            updated = false;
        }

        if (updated)
        {
            nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
            CharSequence from = "Database Updated";
            CharSequence message = "I: " + internalVersion + " L: " + latestVersion + "Click to open.";
            PendingIntent contentIntent = PendingIntent.getActivity(context, 0, new Intent(), 0);
            Notification notif = new Notification(R.drawable.icon, "Database Updated", System.currentTimeMillis());
            notif.setLatestEventInfo(context, from, message, contentIntent);
            nm.notify(1, notif);
        }
    }
}

はい、おそらくBroadcastReceiverでやりすぎているので、それが問題の原因になっている可能性がありますが、他の方法でこれを行う方法がわかりません。このコードの結果をログに記録すると、最初はうまく機能します。internalVersion を介して 2 回目は 0 になります。URL から取得した値は常に正しいです。

何かご意見は?長々とすみません。ありがとう。

コーリー

4

3 に答える 3

2

SharedPreference.Editor.commit()ブロッキングコールです。これには時間がかかり、ANR が発生する可能性があります。

API 9 以降で使用apply()し、古い API バージョンで期待値をローカルに保存する前にこれをスレッド化し、このコードをサービスに移動し、例外をログに記録して、このような競合状態に対して適切にデバッグできるようにします。

于 2012-09-07T21:57:23.377 に答える
0

以下を使用してみてください:

 int mode = Context.MODE_PRIVATE;

それ以外の

 int mode = Activity.MODE_PRIVATE;

SharedPreferencesに値を保存し始めます。

于 2013-03-18T07:44:29.573 に答える
0

何かが変更されたことに気付いた場合にのみ、変更を書き込み/コミットする必要があります。つまり、「if (updated)」ブランチにあります。また、静的メンバーを使用するのではなく、サーバーから読み取った値をコミットする必要があります。

レシーバーが(新しいプロセスで)新たに開始されたとします。この場合、静的な値は初期値から始まるため、latestversion は "0" です。この値をコミットします。

次の実行では、「0」を読み取ります。現在、内部バージョンはサーバーのバージョンよりも低くなっています - 変更が発生していない場合でも。

于 2012-09-07T22:18:51.273 に答える