예제 #1
0
 public static boolean isServiceAvailable() {
   boolean isAvailable = MyContextHolder.get().isReady();
   if (!isAvailable) {
     boolean tryToInitialize = false;
     synchronized (serviceAvailableLock) {
       tryToInitialize = mServiceAvailable;
     }
     if (tryToInitialize && !MyContextHolder.get().initialized()) {
       MyContextHolder.initialize(null, TAG);
       isAvailable = MyContextHolder.get().isReady();
     }
   }
   if (isAvailable) {
     long availableInMillis = 0;
     synchronized (serviceAvailableLock) {
       availableInMillis = timeWhenTheServiceWillBeAvailable - System.currentTimeMillis();
       if (!mServiceAvailable && availableInMillis <= 0) {
         setServiceAvailable();
       }
       isAvailable = mServiceAvailable;
     }
     if (!isAvailable) {
       MyLog.v(
           TAG,
           "Service will be available in "
               + java.util.concurrent.TimeUnit.MILLISECONDS.toSeconds(availableInMillis)
               + " seconds");
     }
   } else {
     MyLog.v(TAG, "Service is unavailable: Context is not Ready");
   }
   return isAvailable;
 }
예제 #2
0
 static void sendCommandEvenForUnavailable(CommandData commandData) {
   // Using explicit Service intent,
   // see
   // http://stackoverflow.com/questions/18924640/starting-android-service-using-explicit-vs-implicit-intent
   Intent serviceIntent = new Intent(MyContextHolder.get().context(), MyService.class);
   if (commandData != null) {
     serviceIntent = commandData.toIntent(serviceIntent);
   }
   MyContextHolder.get().context().startService(serviceIntent);
 }
예제 #3
0
 /** Stop {@link MyService} asynchronously */
 public static synchronized void stopService() {
   if (!MyContextHolder.get().isReady()) {
     return;
   }
   // Don't do "context.stopService", because we may lose some information and (or) get Force Close
   // This is "mild" stopping
   CommandData element = new CommandData(CommandEnum.STOP_SERVICE, "");
   MyContextHolder.get()
       .context()
       .sendBroadcast(element.toIntent(MyAction.EXECUTE_COMMAND.getIntent()));
 }
 private Cursor queryDatabase() {
   final String method = "queryDatabase";
   Cursor cursor = null;
   for (int attempt = 0; attempt < 3 && !isCancelled(); attempt++) {
     try {
       cursor =
           MyContextHolder.get()
               .context()
               .getContentResolver()
               .query(
                   getParams().mContentUri,
                   getParams().mProjection,
                   getParams().mSa.selection,
                   getParams().mSa.selectionArgs,
                   getParams().mSortOrder);
       break;
     } catch (IllegalStateException e) {
       logD(method, "Attempt " + attempt + " to prepare cursor", e);
       DbUtils.closeSilently(cursor);
       try {
         Thread.sleep(500);
       } catch (InterruptedException e2) {
         logD(method, "Attempt " + attempt + " to prepare cursor was interrupted", e2);
         break;
       }
     }
   }
   return cursor;
 }
예제 #5
0
  /**
   * Delete a record(s) from the database.
   *
   * @see android.content.ContentProvider#delete(android.net.Uri, java.lang.String,
   *     java.lang.String[])
   */
  @Override
  public int delete(Uri uri, String selection, String[] selectionArgs) {
    SQLiteDatabase db = MyContextHolder.get().getDatabase().getWritableDatabase();
    int count = 0;
    ParsedUri uriParser = ParsedUri.fromUri(uri);
    switch (uriParser.matched()) {
      case MSG:
        count = deleteMessages(db, selection, selectionArgs);
        break;

      case MSG_ITEM:
        count = deleteMessages(db, BaseColumns._ID + "=" + uriParser.getMessageId(), null);
        break;

      case USER:
        count = deleteUsers(db, selection, selectionArgs);
        break;

      case USER_ITEM:
        count = deleteUsers(db, BaseColumns._ID + "=" + uriParser.getUserId(), null);
        break;

      default:
        throw new IllegalArgumentException(uriParser.toString());
    }
    return count;
  }
  @Override
  protected void setUp() throws Exception {
    super.setUp();
    TestSuite.initializeWithData(this);
    iteration = (iteration >= 4 ? 1 : iteration + 1);
    switch (iteration) {
      case 2:
        showAttachedImages = showAttachedImagesOld;
        showAvatars = !showAvatarsOld;
        break;
      case 3:
        showAttachedImages = !showAttachedImagesOld;
        showAvatars = showAvatarsOld;
        break;
      case 4:
        showAttachedImages = !showAttachedImagesOld;
        showAvatars = !showAvatarsOld;
        break;
      default:
        showAttachedImagesOld = MyPreferences.showAttachedImages();
        showAvatarsOld = MyPreferences.showAvatars();
        showAttachedImages = showAttachedImagesOld;
        showAvatars = showAvatarsOld;
        break;
    }
    setPreferences();
    MyLog.setLogToFile(true);
    logStartStop("setUp started");

    MyAccount ma =
        MyContextHolder.get()
            .persistentAccounts()
            .fromAccountName(TestSuite.CONVERSATION_ACCOUNT_NAME);
    assertTrue(ma.isValid());
    MyContextHolder.get().persistentAccounts().setCurrentAccount(ma);

    Intent intent =
        new Intent(
            Intent.ACTION_VIEW,
            MatchedUri.getTimelineUri(ma.getUserId(), TimelineType.HOME, false, 0));
    setActivityIntent(intent);

    activity = getActivity();

    assertTrue("MyService is available", MyServiceManager.isServiceAvailable());
    logStartStop("setUp ended");
  }
예제 #7
0
  /** Update objects (one or several records) in the database */
  @Override
  public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
    SQLiteDatabase db = MyContextHolder.get().getDatabase().getWritableDatabase();
    int count = 0;
    ParsedUri uriParser = ParsedUri.fromUri(uri);
    long accountUserId = 0;
    switch (uriParser.matched()) {
      case MSG:
        count = db.update(Msg.TABLE_NAME, values, selection, selectionArgs);
        break;

      case MSG_ITEM:
        accountUserId = uriParser.getAccountUserId();
        long rowId = uriParser.getMessageId();
        MsgOfUserValues msgOfUserValues = MsgOfUserValues.valueOf(accountUserId, values);
        msgOfUserValues.setMsgId(rowId);
        if (values.size() > 0) {
          count =
              db.update(
                  Msg.TABLE_NAME,
                  values,
                  BaseColumns._ID
                      + "="
                      + rowId
                      + (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""),
                  selectionArgs);
        }
        count += msgOfUserValues.update(db);
        break;

      case USER:
        count = db.update(User.TABLE_NAME, values, selection, selectionArgs);
        break;

      case USER_ITEM:
        accountUserId = uriParser.getAccountUserId();
        long selectedUserId = uriParser.getUserId();
        FollowingUserValues followingUserValues =
            FollowingUserValues.valueOf(accountUserId, selectedUserId, values);
        count =
            db.update(
                User.TABLE_NAME,
                values,
                BaseColumns._ID
                    + "="
                    + selectedUserId
                    + (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""),
                selectionArgs);
        followingUserValues.update(db);
        optionallyLoadAvatar(selectedUserId, values);
        break;

      default:
        throw new IllegalArgumentException(uriParser.toString());
    }

    return count;
  }
 @Override
 MessageEditorData executeAsync(MyAccount maIn, long msgId) {
   MyAccount ma =
       MyContextHolder.get()
           .persistentAccounts()
           .fromUserId(MyQuery.msgIdToLongColumnValue(MyDatabase.Msg.SENDER_ID, msgId));
   CommandData commandData = CommandData.updateStatus(ma.getAccountName(), msgId);
   MyServiceManager.sendManualForegroundCommand(commandData);
   return null;
 }
 @Override
 protected void setUp() throws Exception {
   super.setUp();
   MyLog.i(this, "setUp started");
   TestSuite.initializeWithData(this);
   ma =
       MyContextHolder.get()
           .persistentAccounts()
           .fromAccountName(TestSuite.GNUSOCIAL_TEST_ACCOUNT_NAME);
   assertTrue(TestSuite.GNUSOCIAL_TEST_ACCOUNT_NAME + " exists", ma.isValid());
 }
  private void testFileProvider(long downloadRowId) throws IOException {
    DownloadData data = DownloadData.fromId(downloadRowId);
    assertTrue(data.getFilename(), data.getFile().exists());

    Uri uri = FileProvider.downloadFilenameToUri(data.getFile().getFilename());
    InputStream in = MyContextHolder.get().context().getContentResolver().openInputStream(uri);
    byte[] buffer = new byte[100];
    int bytesRead = in.read(buffer);
    assertEquals(buffer.length, bytesRead);
    in.close();
  }
 void executeOnUiThread(MessageContextMenu menu, MessageEditorData editorData) {
   if (editorData.recipientId != 0) {
     /**
      * We better switch to the account selected for this message in order not to add new
      * "MsgOfUser" entries hence duplicated messages in the combined timeline
      */
     MyContextHolder.get().persistentAccounts().setCurrentAccount(editorData.ma);
     menu.switchTimelineActivity(
         TimelineType.USER, menu.messageList.isTimelineCombined(), editorData.recipientId);
   }
 }
 protected void copyMessageText(MessageEditorData editorData) {
   MyLog.v(this, "text='" + editorData.body + "'");
   if (!TextUtils.isEmpty(editorData.body)) {
     // http://developer.android.com/guide/topics/text/copy-paste.html
     ClipboardManager clipboard =
         (ClipboardManager)
             MyContextHolder.get().context().getSystemService(Context.CLIPBOARD_SERVICE);
     ClipData clip = ClipData.newPlainText(I18n.trimTextAt(editorData.body, 40), editorData.body);
     clipboard.setPrimaryClip(clip);
     MyLog.v(this, "clip='" + clip.toString() + "'");
   }
 }
예제 #13
0
 private static Drawable loadDefaultAvatar(boolean lightTheme) {
   Drawable avatar = null;
   MyLog.v(AvatarDrawable.class, "Loading default avatar");
   Context context = MyContextHolder.get().context();
   if (context != null) {
     avatar =
         context
             .getResources()
             .getDrawable(
                 lightTheme ? R.drawable.ic_action_user_light : R.drawable.ic_action_user);
   }
   return avatar;
 }
예제 #14
0
 /**
  * Starts MyService asynchronously if it is not already started and send command to it.
  *
  * @param commandData to the service or null
  */
 public static void sendCommand(CommandData commandData) {
   if (!isServiceAvailable()) {
     // Imitate a soft service error
     commandData.getResult().incrementNumIoExceptions();
     commandData.getResult().setMessage("Service is not available");
     MyServiceEventsBroadcaster.newInstance(MyContextHolder.get(), MyServiceState.STOPPED)
         .setCommandData(commandData)
         .setEvent(MyServiceEvent.AFTER_EXECUTING_COMMAND)
         .broadcast();
     return;
   }
   sendCommandEvenForUnavailable(commandData);
 }
예제 #15
0
 @Override
 protected MyAccount findBestAccountForDownload() {
   long originId = MyQuery.msgIdToOriginId(data.msgId);
   boolean subscribedFound = false;
   MyAccount bestAccount =
       MyContextHolder.get().persistentAccounts().findFirstSucceededMyAccountByOriginId(originId);
   for (MyAccount ma : MyContextHolder.get().persistentAccounts().collection()) {
     if (ma.getOriginId() == originId && ma.isValidAndSucceeded()) {
       MessageForAccount msg = new MessageForAccount(data.msgId, ma);
       if (msg.hasPrivateAccess()) {
         bestAccount = ma;
         break;
       }
       if (msg.isSubscribed) {
         bestAccount = ma;
         subscribedFound = true;
       }
       if (msg.isTiedToThisAccount() && !subscribedFound) {
         bestAccount = ma;
       }
     }
   }
   return bestAccount;
 }
 @Override
 protected void setUp() throws Exception {
   super.setUp();
   MyLog.i(this, "setUp started");
   TestSuite.initializeWithData(this);
   ma =
       MyContextHolder.get()
           .persistentAccounts()
           .fromAccountName(TestSuite.CONVERSATION_ACCOUNT_NAME);
   assertTrue(ma.isValid());
   selectedMessageId =
       MyQuery.oidToId(
           OidEnum.MSG_OID, ma.getOriginId(), TestSuite.CONVERSATION_ENTRY_MESSAGE_OID);
   assertTrue("Selected message exists", selectedMessageId != 0);
   MyLog.i(this, "setUp ended");
 }
예제 #17
0
 @Override
 public void onReceive(Context context, Intent intent) {
   String action = intent.getAction();
   if (action.equals(MyAction.SERVICE_STATE.getAction())) {
     MyContextHolder.initialize(context, this);
     synchronized (mServiceState) {
       stateQueuedTime = System.nanoTime();
       waitingForServiceState = false;
       mServiceState = MyServiceState.load(intent.getStringExtra(IntentExtra.SERVICE_STATE.key));
     }
     MyLog.d(this, "Notification received: Service state=" + mServiceState);
   } else if ("android.intent.action.BOOT_COMPLETED".equals(action)) {
     MyLog.d(this, "Trying to start service on boot");
     sendCommand(CommandData.getEmpty());
   } else if ("android.intent.action.ACTION_SHUTDOWN".equals(action)) {
     // We need this to persist unsaved data in the service
     MyLog.d(this, "Stopping service on Shutdown");
     setServiceUnavailable();
     stopService();
   }
 }
예제 #18
0
 /**
  * Returns previous service state and queries service for its current state asynchronously.
  * Doesn't start the service, so absence of the reply will mean that service is stopped @See <a
  * href="http://groups.google.com/group/android-developers/browse_thread/thread/8c4bd731681b8331/bf3ae8ef79cad75d">here</a>
  */
 public static MyServiceState getServiceState() {
   synchronized (mServiceState) {
     long time = System.nanoTime();
     if (waitingForServiceState
         && (time - stateQueuedTime)
             > java.util.concurrent.TimeUnit.SECONDS.toMillis(STATE_QUERY_TIMEOUT_SECONDS)) {
       // Timeout expired
       waitingForServiceState = false;
       mServiceState = MyServiceState.STOPPED;
     } else if (!waitingForServiceState && mServiceState == MyServiceState.UNKNOWN) {
       // State is unknown, we need to query the Service again
       waitingForServiceState = true;
       stateQueuedTime = time;
       mServiceState = MyServiceState.UNKNOWN;
       CommandData element = new CommandData(CommandEnum.BROADCAST_SERVICE_STATE, "");
       MyContextHolder.get()
           .context()
           .sendBroadcast(element.toIntent(MyAction.EXECUTE_COMMAND.getIntent()));
     }
   }
   return mServiceState;
 }
 public void testLoad() {
   Context context = MyContextHolder.get().context();
   ConversationLoader<ConversationViewItem> loader =
       new ConversationLoader<ConversationViewItem>(
           ConversationViewItem.class, context, ma, selectedMessageId);
   progressCounter = 0;
   loader.load(this);
   List<ConversationViewItem> list = loader.getMsgs();
   assertTrue("List is not empty", !list.isEmpty());
   boolean indentFound = false;
   boolean orderFound = false;
   for (ConversationViewItem oMsg : list) {
     if (oMsg.mIndentLevel > 0) {
       indentFound = true;
     }
     if (oMsg.mListOrder != 0) {
       orderFound = true;
     }
   }
   assertTrue("Indented message found", indentFound);
   assertTrue("Ordered message found", orderFound);
   assertTrue(progressCounter > 0);
 }
예제 #20
0
  /** Formats message as a View suitable for a conversation list */
  private View oneMessageToView(ConversationOneMessage oMsg) {
    final String method = "oneMessageToView";
    if (MyLog.isLoggable(this, MyLog.VERBOSE)) {
      MyLog.v(
          this,
          method
              + ": msgId="
              + oMsg.msgId
              + (oMsg.avatarDrawable != null
                  ? ", avatar=" + oMsg.avatarDrawable.getFileName()
                  : ""));
    }
    LayoutInflater inflater = LayoutInflater.from(context);
    int layoutResource = R.layout.message_conversation;
    if (!Activity.class.isAssignableFrom(context.getClass())) {
      MyLog.w(this, "Context should be from an Activity");
    }
    View messageView = inflater.inflate(layoutResource, null);
    messageView.setOnCreateContextMenuListener(contextMenu);

    float displayDensity = context.getResources().getDisplayMetrics().density;
    // See
    // http://stackoverflow.com/questions/2238883/what-is-the-correct-way-to-specify-dimensions-in-dip-from-java-code
    int indent0 = (int) (10 * displayDensity);
    int indentPixels = indent0 * oMsg.indentLevel;

    LinearLayout messageIndented = (LinearLayout) messageView.findViewById(R.id.message_indented);
    if (oMsg.msgId == selectedMessageId && oMsgs.size() > 1) {
      messageIndented.setBackgroundDrawable(
          context.getResources().getDrawable(R.drawable.message_current_background));
    }

    int viewToTheLeftId = 0;
    if (oMsg.indentLevel > 0) {
      View divider = messageView.findViewById(R.id.divider);
      RelativeLayout.LayoutParams layoutParams =
          new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 1);
      layoutParams.leftMargin = indentPixels - 4;
      divider.setLayoutParams(layoutParams);

      if (MyLog.isLoggable(this, MyLog.VERBOSE)) {
        MyLog.v(this, "density=" + displayDensity);
      }
      viewToTheLeftId = 2;
      ImageView indentView =
          new ConversationIndentImageView(context, messageIndented, indentPixels);
      indentView.setId(viewToTheLeftId);
      ((ViewGroup) messageIndented.getParent()).addView(indentView);
    }

    if (MyPreferences.showAvatars()) {
      ImageView avatarView = new ImageView(context);
      int size = Math.round(AvatarDrawable.AVATAR_SIZE_DIP * displayDensity);
      avatarView.setScaleType(ScaleType.FIT_CENTER);
      RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(size, size);
      layoutParams.topMargin = 3;
      if (oMsg.indentLevel > 0) {
        layoutParams.leftMargin = 1;
      }
      if (viewToTheLeftId == 0) {
        layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
      } else {
        layoutParams.addRule(RelativeLayout.RIGHT_OF, viewToTheLeftId);
      }
      avatarView.setLayoutParams(layoutParams);
      avatarView.setImageDrawable(oMsg.avatarDrawable.getDrawable());
      indentPixels += size;
      ((ViewGroup) messageIndented.getParent()).addView(avatarView);
    }
    messageIndented.setPadding(indentPixels + 6, 2, 6, 2);

    TextView id = (TextView) messageView.findViewById(R.id.id);
    id.setText(Long.toString(oMsg.msgId));
    TextView linkedUserId = (TextView) messageView.findViewById(R.id.linked_user_id);
    linkedUserId.setText(Long.toString(oMsg.linkedUserId));

    TextView author = (TextView) messageView.findViewById(R.id.message_author);
    TextView body = (TextView) messageView.findViewById(R.id.message_body);
    TextView details = (TextView) messageView.findViewById(R.id.message_details);

    author.setText(oMsg.author);

    TextView number = (TextView) messageView.findViewById(R.id.message_number);
    number.setText(Integer.toString(oMsg.historyOrder));

    if (!TextUtils.isEmpty(oMsg.body)) {
      body.setLinksClickable(true);
      body.setMovementMethod(LinkMovementMethod.getInstance());
      body.setFocusable(true);
      body.setFocusableInTouchMode(true);
      Spanned spanned = Html.fromHtml(oMsg.body);
      body.setText(spanned);
      if (!MbMessage.hasUrlSpans(spanned)) {
        Linkify.addLinks(body, Linkify.ALL);
      }
    }

    // Everything else goes to messageDetails
    String messageDetails = RelativeTime.getDifference(context, oMsg.createdDate);
    if (!SharedPreferencesUtil.isEmpty(oMsg.via)) {
      messageDetails +=
          " "
              + String.format(
                  MyContextHolder.get().getLocale(),
                  context.getText(R.string.message_source_from).toString(),
                  oMsg.via);
    }
    if (oMsg.inReplyToMsgId != 0) {
      String inReplyToName = oMsg.inReplyToName;
      if (SharedPreferencesUtil.isEmpty(inReplyToName)) {
        inReplyToName = "...";
      }
      messageDetails +=
          " "
              + String.format(
                  MyContextHolder.get().getLocale(),
                  context.getText(R.string.message_source_in_reply_to).toString(),
                  oMsg.inReplyToName)
              + " ("
              + msgIdToHistoryOrder(oMsg.inReplyToMsgId)
              + ")";
    }
    if (!SharedPreferencesUtil.isEmpty(oMsg.rebloggersString)
        && !oMsg.rebloggersString.equals(oMsg.author)) {
      if (!SharedPreferencesUtil.isEmpty(oMsg.inReplyToName)) {
        messageDetails += ";";
      }
      messageDetails +=
          " "
              + String.format(
                  MyContextHolder.get().getLocale(),
                  context
                      .getText(ma.alternativeTermForResourceId(R.string.reblogged_by))
                      .toString(),
                  oMsg.rebloggersString);
    }
    if (!SharedPreferencesUtil.isEmpty(oMsg.recipientName)) {
      messageDetails +=
          " "
              + String.format(
                  MyContextHolder.get().getLocale(),
                  context.getText(R.string.message_source_to).toString(),
                  oMsg.recipientName);
    }
    if (MyLog.isLoggable(this, MyLog.VERBOSE)) {
      messageDetails = messageDetails + " (i" + oMsg.indentLevel + ",r" + oMsg.replyLevel + ")";
    }
    details.setText(messageDetails);
    ImageView favorited = (ImageView) messageView.findViewById(R.id.message_favorited);
    favorited.setImageResource(
        oMsg.favorited ? android.R.drawable.star_on : android.R.drawable.star_off);
    return messageView;
  }
예제 #21
0
 /** @see android.content.ContentProvider#onCreate() */
 @Override
 public boolean onCreate() {
   MyContextHolder.storeContextIfNotPresent(getContext(), this);
   return MyContextHolder.get().isReady();
 }
예제 #22
0
  /**
   * Get a cursor to the database
   *
   * @see android.content.ContentProvider#query(android.net.Uri, java.lang.String[],
   *     java.lang.String, java.lang.String[], java.lang.String)
   */
  @Override
  public Cursor query(
      Uri uri,
      String[] projection,
      String selectionIn,
      String[] selectionArgsIn,
      String sortOrder) {
    SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
    boolean built = false;
    String selection = selectionIn;
    String[] selectionArgs = selectionArgsIn;
    String sql = "";

    ParsedUri uriParser = ParsedUri.fromUri(uri);
    switch (uriParser.matched()) {
      case TIMELINE:
        qb.setDistinct(true);
        qb.setTables(TimelineSql.tablesForTimeline(uri, projection));
        qb.setProjectionMap(ProjectionMap.MSG);
        break;

      case TIMELINE_ITEM:
        qb.setTables(TimelineSql.tablesForTimeline(uri, projection));
        qb.setProjectionMap(ProjectionMap.MSG);
        qb.appendWhere(
            ProjectionMap.MSG_TABLE_ALIAS + "." + BaseColumns._ID + "=" + uriParser.getMessageId());
        break;

      case TIMELINE_SEARCH:
        qb.setTables(TimelineSql.tablesForTimeline(uri, projection));
        qb.setProjectionMap(ProjectionMap.MSG);
        String searchQuery = uriParser.getSearchQuery();
        if (!TextUtils.isEmpty(searchQuery)) {
          if (!TextUtils.isEmpty(selection)) {
            selection = " AND (" + selection + ")";
          } else {
            selection = "";
          }
          // TODO: Search in MyDatabase.User.USERNAME also
          selection = "(" + User.AUTHOR_NAME + " LIKE ?  OR " + Msg.BODY + " LIKE ?)" + selection;

          selectionArgs = addBeforeArray(selectionArgs, "%" + searchQuery + "%");
          selectionArgs = addBeforeArray(selectionArgs, "%" + searchQuery + "%");
        }
        break;

      case MSG_COUNT:
        sql = "SELECT count(*) FROM " + Msg.TABLE_NAME + " AS " + ProjectionMap.MSG_TABLE_ALIAS;
        if (!TextUtils.isEmpty(selection)) {
          sql += " WHERE " + selection;
        }
        break;

      case MSG:
        qb.setTables(Msg.TABLE_NAME + " AS " + ProjectionMap.MSG_TABLE_ALIAS);
        qb.setProjectionMap(ProjectionMap.MSG);
        break;

      case USER:
      case USERLIST:
        qb.setTables(User.TABLE_NAME);
        qb.setProjectionMap(ProjectionMap.USER);
        break;

      case USER_ITEM:
        qb.setTables(User.TABLE_NAME);
        qb.setProjectionMap(ProjectionMap.USER);
        qb.appendWhere(BaseColumns._ID + "=" + uriParser.getUserId());
        break;

      default:
        throw new IllegalArgumentException(uriParser.toString());
    }

    // If no sort order is specified use the default
    String orderBy;
    if (TextUtils.isEmpty(sortOrder)) {
      switch (uriParser.matched()) {
        case TIMELINE:
        case TIMELINE_ITEM:
        case TIMELINE_SEARCH:
          orderBy = Msg.DEFAULT_SORT_ORDER;
          break;

        case MSG_COUNT:
          orderBy = "";
          break;

        case USER:
        case USERLIST:
        case USER_ITEM:
          orderBy = User.DEFAULT_SORT_ORDER;
          break;

        default:
          throw new IllegalArgumentException(uriParser.toString());
      }
    } else {
      orderBy = sortOrder;
    }

    Cursor c = null;
    if (MyContextHolder.get().isReady()) {
      // Get the database and run the query
      SQLiteDatabase db = MyContextHolder.get().getDatabase().getReadableDatabase();
      boolean logQuery = MyLog.isVerboseEnabled();
      try {
        if (sql.length() == 0) {
          sql = qb.buildQuery(projection, selection, null, null, orderBy, null);
          built = true;
        }
        // Here we substitute ?-s in selection with values from selectionArgs
        c = db.rawQuery(sql, selectionArgs);
        if (c == null) {
          MyLog.e(this, "Null cursor returned");
          logQuery = true;
        }
      } catch (Exception e) {
        logQuery = true;
        MyLog.e(this, "Database query failed", e);
      }

      if (logQuery) {
        String msg = "query, SQL=\"" + sql + "\"";
        if (selectionArgs != null && selectionArgs.length > 0) {
          msg += "; selectionArgs=" + Arrays.toString(selectionArgs);
        }
        MyLog.v(TAG, msg);
        if (built) {
          msg =
              "uri="
                  + uri
                  + "; projection="
                  + Arrays.toString(projection)
                  + "; selection="
                  + selection
                  + "; sortOrder="
                  + sortOrder
                  + "; qb.getTables="
                  + qb.getTables()
                  + "; orderBy="
                  + orderBy;
          MyLog.v(TAG, msg);
        }
      }
    }

    if (c != null) {
      c.setNotificationUri(getContext().getContentResolver(), uri);
    }
    return c;
  }
예제 #23
0
  /**
   * Insert a new record into the database.
   *
   * @see android.content.ContentProvider#insert(android.net.Uri, android.content.ContentValues)
   */
  @Override
  public Uri insert(Uri uri, ContentValues initialValues) {

    ContentValues values;
    MsgOfUserValues msgOfUserValues = new MsgOfUserValues(0);
    FollowingUserValues followingUserValues = null;
    long accountUserId = 0;

    long rowId;
    Uri newUri = null;
    try {
      Long now = System.currentTimeMillis();
      SQLiteDatabase db = MyContextHolder.get().getDatabase().getWritableDatabase();

      String table;

      if (initialValues != null) {
        values = new ContentValues(initialValues);
      } else {
        values = new ContentValues();
      }

      ParsedUri uriParser = ParsedUri.fromUri(uri);
      switch (uriParser.matched()) {
        case MSG_ITEM:
          accountUserId = uriParser.getAccountUserId();

          table = Msg.TABLE_NAME;
          /** Add default values for missed required fields */
          if (!values.containsKey(Msg.AUTHOR_ID) && values.containsKey(Msg.SENDER_ID)) {
            values.put(Msg.AUTHOR_ID, values.get(Msg.SENDER_ID).toString());
          }
          if (!values.containsKey(Msg.BODY)) {
            values.put(Msg.BODY, "");
          }
          if (!values.containsKey(Msg.VIA)) {
            values.put(Msg.VIA, "");
          }
          values.put(Msg.INS_DATE, now);

          msgOfUserValues = MsgOfUserValues.valueOf(accountUserId, values);
          break;

        case ORIGIN_ITEM:
          table = Origin.TABLE_NAME;
          break;

        case USER_ITEM:
          table = User.TABLE_NAME;
          values.put(User.INS_DATE, now);
          accountUserId = uriParser.getAccountUserId();
          followingUserValues = FollowingUserValues.valueOf(accountUserId, 0, values);
          break;

        default:
          throw new IllegalArgumentException(uriParser.toString());
      }

      rowId = db.insert(table, null, values);
      if (rowId == -1) {
        throw new SQLException("Failed to insert row into " + uri);
      } else if (User.TABLE_NAME.equals(table)) {
        optionallyLoadAvatar(rowId, values);
      }

      msgOfUserValues.setMsgId(rowId);
      msgOfUserValues.insert(db);

      if (followingUserValues != null) {
        followingUserValues.followingUserId = rowId;
        followingUserValues.update(db);
      }

      switch (uriParser.matched()) {
        case MSG_ITEM:
          newUri = MatchedUri.getMsgUri(accountUserId, rowId);
          break;
        case ORIGIN_ITEM:
          newUri = MatchedUri.getOriginUri(rowId);
          break;
        case USER_ITEM:
          newUri = MatchedUri.getUserUri(accountUserId, rowId);
          break;
        default:
          break;
      }
    } catch (Exception e) {
      MyLog.e(this, "Insert " + uri, e);
    }
    return newUri;
  }
예제 #24
0
 public TimelineCursorLoader1(TimelineListParameters params) {
   super(MyContextHolder.get().context());
   this.mParams = params;
   serviceConnector = new MyServiceEventsReceiver(this);
 }