I have write this simple code for getting tweets from twitter
public static void main(String[] args) throws TwitterException {
// TODO code application logic here
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setDebugEnabled(true)
.setOAuthConsumerKey("**********")
.setOAuthConsumerSecret("**************")
.setOAuthAccessToken("***************")
.setOAuthAccessTokenSecret("**************");
TwitterFactory tf= new TwitterFactory(cb.build());
twitter4j.Twitter tw= tf.getInstance();
List<Status> statuses = tw.getHomeTimeline();
for(Status status1 : statuses){
System.out.println(status1.getUser().getName()+ " : "+ status1.getText());
}
But I want to get about 4000 tweets in urdu language. I don't know how to do. please help me
With that code you will only get Tweets from the Timeline of the register user, from Twitter4j:
ResponseList getHomeTimeline() Returns the 20 most recent
statuses, including retweets, posted by the authenticating user and
that user's friends. This is the equivalent of /timeline/home on the
Web."
If you want to get at least 4000 tweets in urdu you could do several things, for example you could get the sample stream from Twitter:
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setDebugEnabled(true)
.setOAuthConsumerKey("**********")
.setOAuthConsumerSecret("**************")
.setOAuthAccessToken("***************")
.setOAuthAccessTokenSecret("**************");
TwitterStream twitterStream = new TwitterStreamFactory(cb.build())
.getInstance();
StatusListener listener = new StatusListener() {
#Override
public void onStatus(Status status) {
System.out.println("#"+status.getUser().getScreenName()+": "+status.getText());
// HERE YOU STORE YOUR TWEETS
}
#Override
public void onException(Exception ex) {
ex.printStackTrace();
}
#Override
public void onDeletionNotice(StatusDeletionNotice arg0) {
// TODO Auto-generated method stub
}
#Override
public void onScrubGeo(long arg0, long arg1) {
}
#Override
public void onStallWarning(StallWarning arg0) {
// TODO Auto-generated method stub
System.out.println(arg0);
}
#Override
public void onTrackLimitationNotice(int arg0) {
// TODO Auto-generated method stub
System.out.println(arg0);
}
};
twitterStream.addListener(listener);
twitterStream.sample("ur");
Until you get the 4000 tweets that you want.
You can use twitter search instead of just getting specific user's tweets. What I have done for getting tweets in Turkish language is just using twitter's advanced search feature. In my situation adding lang:tr after specified search phrase returned tweets in Turkish language to me. You can use lang:ur instead of lang:tr for getting tweets in Urdu Language.
Here is my code:
public class TwitterDataGetter implements Runnable {
private Thread twitterDataGetterThread;
final static Logger logger = Logger.getLogger(TwitterDataGetter.class);
public TwitterDataGetter() {
try {
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setDebugEnabled(true);
cb.setOAuthConsumerKey("your consumer key");
cb.setOAuthConsumerSecret("your consumer secret");
cb.setOAuthAccessToken("your access token");
cb.setOAuthAccessTokenSecret("your access token secret");
cb.setIncludeEntitiesEnabled(true);
this.twitter = new TwitterFactory(cb.build()).getInstance();
logger.info("Twitter API Configuration Successful");
} catch (Exception e) {
logger.error("Twitter API Configuration Error", e);
}
}
public void getTweet(String keyword){
List<Status> statuses = null;
Query query;
QueryResult result;
try {
query = new Query(keyword + " lang:tr");
query.setCount(100);
do {
final long startTime = System.nanoTime();
result = twitter.search(query);
statuses = result.getTweets();
for (Status status : statuses) {
System.out.println(status.getText());
}
final long duration = System.nanoTime() - startTime;
if((5500 - duration/1000000) > 0){
Thread.sleep((5500 - duration/1000000));
}
} while ((query = result.nextQuery()) != null);
} catch (TwitterException e) {
logger.error("TwitterException", e);
} catch (InterruptedException e) {
logger.error("InterruptedException", e);
throw new RuntimeException(e);
}
}
#Override
public void run() {
while(true){
this.getTweet("");
}
}
public void start(){
if(twitterDataGetterThread == null){
twitterDataGetterThread = new Thread(this, "Twitter Thread");
}
twitterDataGetterThread.start();
logger.info("Twitter Thread started");
}
}
Calling getTweet(String keyword) method with empty string returns latest tweets in your language without filtering them with any keyword.
Hope it helps.
PS: you can also check search results for your language from this link https://twitter.com/search?f=tweets&vertical=default&q=lang%3Aur
Related
I'm using the implementation 'com.android.volley:volley:1.1.1' to make a POST call to a REST web service. Unfortunately, the conclusion (i.e. User does not exist) is reached before the response comes back from the server and is always wrong (In reality user actually does exist).
On the console, the logger messages appear in the wrong order:
E/: THIS IS SUPPOSED TO HAPPEN SECOND - USER NOT FOUND ALERT
I/: THIS IS SUPPOSED TO HAPPEN FIRST: VALIDATING DATA
After hours of reading, I found that a Callback Interface will ensure proper execution order. However, after implementing it, the result is the same. What could be wrong, please?
ControladorLoginExistente.Java
public class ControladorLoginUsrExistente {
public AbstractMap.SimpleEntry<String, Map<String, String>> callEndpointLoginUsrExistente(Context context) {
try {
JSONObject jsonRequest = new JSONObject();
jsonRequest.put("email", "mymail#themail.com");
jsonRequest.put("password", "12345");
final JSONObject[] jsonResponse = {null};
new PostRequestConVolley().getResponse(Constantes.URL_ACCESO_USUARIO_EXISTENTE, jsonRequest, context, new VolleyCallback() {
#Override
public void onSuccessResponse(JSONObject jsonObject) {
jsonResponse[0] = jsonObject;
Log.i(null,"THIS IS SUPPOSED TO HAPPEN FIRST: VALIDATING DATA");
}
});
Boolean exito = jsonResponse[0].getBoolean("exito");
String descripcion = jsonResponse[0].getString("descripcion");
String codigoHttp = jsonResponse[0].getString("codigoHttp");
JSONArray respuestaTransaccion = jsonResponse[0].getJSONArray("respuestaTransaccion");
if(exito == false || codigoHttp.equals("200")){
Log.e(null,"THIS IS SUPPOSED TO HAPPEN SECOND: USER NOT FOUND ALERT");
return new AbstractMap.SimpleEntry<>(descripcion, new HashMap<>());
}
Log.i(null,"THIS IS SUPPOSED TO HAPPEN SECOND: USER NOT FOUND ALERT");
return new AbstractMap.SimpleEntry<>(Constantes.EXITO, new HashMap<>());
} catch (Exception ex) {
Log.e(null,"THIS IS SUPPOSED TO HAPPEN SECOND: USER NOT FOUND ALERT");
return new AbstractMap.SimpleEntry<>("ERROR: " + ex.toString(), new HashMap<>());
}
}
}
PostRequestConVolley.java
public class PostRequestConVolley {
public JSONObject getResponse(String url, JSONObject body, Context context, final VolleyCallback callback) {
try {
RequestQueue queue = Volley.newRequestQueue(context);
JsonObjectRequest jsonRequest = new JsonObjectRequest(POST, url, body,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
callback.onSuccessResponse(response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e(null, error.toString());
}
}) {
#Override
public Map<String, String> getHeaders() {
Map<String, String> params = new HashMap<String, String>();
params.put("Content-Type", "application/json");
params.put("Connection", "keep-alive");
return params;
}
#Override
public String getBodyContentType() {
return "application/json; charset=utf-8";
}
#Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
Log.i(null, "El HTTP code es:" + response.statusCode);
return super.parseNetworkResponse(response);
}
};
queue.add(jsonRequest);
} catch (Exception ex) {
ex.printStackTrace();
}
return body;
}
}
VolleyCallbackInterface
import org.json.JSONObject;
public interface VolleyCallback {
void onSuccessResponse(JSONObject jsonObject);
}
I want to use pusher sdk in Flutter from android native code because its library no yet completely supported in flutter but when i send first message it received it successfully the next message make app crush with Reply already submitted error her on this line result.success(txt);
public class MainActivity extends FlutterActivity {
private static final String CHANNEL = "demo.gawkat.com/info";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler((methodCall, result) -> {
final Map<String, Object> arguments = methodCall.arguments();
if (methodCall.method.equals("getMessage")) {
Pusher pusher = new Pusher("faa685e4bb3003eb825c");
pusher.connect();
Channel channel = pusher.subscribe("messages");
channel.bind("new_message", (channelName, eventName, data) -> runOnUiThread(() -> {
Gson gson = new Gson();
Message message = gson.fromJson(data, Message.class);
String txt = message.text;
result.success(txt);
}));
}
});
}
}
Flutter code:
Future<String> _getMessage() async {
String value;
try {
value = await platform.invokeMethod('getMessage');
} catch (e) {
print(e);
}
return value;
}
Error is
FATAL EXCEPTION: main
Process: com.example.flutter_app, PID: 6296
java.lang.IllegalStateException: Reply already submitted
at io.flutter.view.FlutterNativeView$PlatformMessageHandlerImpl$1.reply(FlutterNativeView.java:197)
at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler$1.success(MethodChannel.java:204)
at com.example.flutter_app.MainActivity.lambda$null$0(MainActivity.java:40)
at com.example.flutter_app.-$$Lambda$MainActivity$axbDTe2B0rhavWD22s4E8-fuCaQ.run(Unknown Source:4)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767
I think it is happening after Flutter upgrade > 1.5.4.hotfix.
Anyway, Yes there is a solution (Refer this github issue),
In your Activitybelow onCreate() add this class:
private static class MethodResultWrapper implements MethodChannel.Result {
private MethodChannel.Result methodResult;
private Handler handler;
MethodResultWrapper(MethodChannel.Result result) {
methodResult = result;
handler = new Handler(Looper.getMainLooper());
}
#Override
public void success(final Object result) {
handler.post(
new Runnable() {
#Override
public void run() {
methodResult.success(result);
}
});
}
#Override
public void error(
final String errorCode, final String errorMessage, final Object errorDetails) {
handler.post(
new Runnable() {
#Override
public void run() {
methodResult.error(errorCode, errorMessage, errorDetails);
}
});
}
#Override
public void notImplemented() {
handler.post(
new Runnable() {
#Override
public void run() {
methodResult.notImplemented();
}
});
}
}
Then, instead of using MethodChannel result to setMethodCallHandler argument callback add name as rawResult and then inside that callback, add this line:
MethodChannel.Result result = new MethodResultWrapper(rawResult);
As below:
//......
new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
(call, rawResult) -> {
MethodChannel.Result result = new MethodResultWrapper(rawResult);
//.....
I use flags for this problem.
Just make sure that methods of same channels are called simultaneously.
The problem seem to appear then.
If two methods needs to be called simulatenously without any problem define both methods in 2 different channels
var resultMap = Map<String, MethodChannel.Result> = HashMap()
new MethodChannel(getFlutterView(), CHANNEL_1).setMethodCallHandler((methodCall, result) -> {
final Map<String, Object> arguments = methodCall.arguments();
if (methodCall.method.equals("method1")) {
// implement method 1
}
});
new MethodChannel(getFlutterView(), CHANNEL_2).setMethodCallHandler((methodCall, result) -> {
final Map<String, Object> arguments = methodCall.arguments();
if (methodCall.method.equals("method2")) {
resultMap = resultMap + mapOf(CHANNEL_2 to MethodResultWrapper(result) // use this later to return result
// implement method2
result.success(true) // or whatever value
}
});
This reduce the chance of "Reply already submitted" error.
Incase if you are using MethodResultWrapper as #Blasanka answer use flags before result.success
when method is invoked set flag to true
val methodCheckFlag: Boolean = true
then when result need to be returned
if(methodCheckFlag) {
methodCheckFlag = false;
methodWrapperResult?.success(true) // or what ever value to return
}
or use the saved MethodResultWrapper as
if(methodCheckFlag) {
methodCheckFlag = false;
resultMap[CHANNEL_2]?.success(true) // or what ever value to return
}
I am able to get the live twitter stream using the twitter streaming api like below
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setDebugEnabled(true);
cb.setOAuthConsumerKey("xxxx");
cb.setOAuthConsumerSecret("xxxx");
cb.setOAuthAccessToken("xxxx");
cb.setOAuthAccessTokenSecret("xx");
int count = 0;
TwitterStream twitterStream = new TwitterStreamFactory(cb.build()).getInstance();
StatusListener listener = new StatusListener() {
public void onStatus(Status status) {
System.out.println("#" + status.getUser().getScreenName() + " - " + status.getText());
// count++;
}
public void onDeletionNotice(StatusDeletionNotice statusDeletionNotice) {
System.out.println("Got a status deletion notice id:" + statusDeletionNotice.getStatusId());
}
public void onTrackLimitationNotice(int numberOfLimitedStatuses) {
System.out.println("Got track limitation notice:" + numberOfLimitedStatuses);
}
public void onScrubGeo(long userId, long upToStatusId) {
System.out.println("Got scrub_geo event userId:" + userId + " upToStatusId:" + upToStatusId);
}
public void onException(Exception ex) {
ex.printStackTrace();
}
#Override
public void onStallWarning(StallWarning arg0) {
// TODO Auto-generated method stub
}
};
FilterQuery fq = new FilterQuery();
String keywords[] = {"samsung"};
String lang[] = {"en"};
fq.track(keywords);
fq.language(lang);
twitterStream.addListener(listener);
twitterStream.filter(fq);
How do I restrict the number of tweets? The above program is running indefinitely. How do I stop the program after getting the required number of tweets?
Limit storing your tweets in for instance LinkedBlockingQueue
private LinkedBlockingQueue<Status> tweets = new LinkedBlockingQueue<>(10000);
StatusListener listener = new StatusListener() {
#Override
public void onStatus(Status status) {
tweets.add(status);
}
You can later retrive it in foreach loop using Status message = obrada.poll(); .... Or just create counter and ask for size of your regular ArrayList --
if (tweets.size() >= 1000) twitterStream.shutdown(); twitterStream.cleanUp();
I want to stream tweets from twitter in my java application. I am currently able to do that using Twitter4J.
Here is my code sample -
public static void main(String args[])
{
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setDebugEnabled(true);
cb.setOAuthConsumerKey("PEBF3A1wUnNLfT83jpjGBEVNn");
cb.setOAuthConsumerSecret("Cqcuw6xyQ2tVtkGdy76s9fQuDigyDuJwxrgMETNhfuORloNFju");
cb.setOAuthAccessToken("2492966954-Fut0P36Enh0V1UAAVODUHSTGvYKy4lscWIEpaej");
cb.setOAuthAccessTokenSecret("x8onfYsnZvgImnyLVd1ncwvMhwNtrieU16gTkywUZOzpP");
TwitterStream twitterStream = new TwitterStreamFactory(cb.build()).getInstance();
StatusListener listener = new StatusListener(){
public void onStatus(Status status)
{
System.out.println();
System.out.println("*****************************************************************");
User user = status.getUser();
// gets Username
String username = status.getUser().getScreenName();
System.out.println(username);
String profileLocation = user.getLocation();
System.out.println(profileLocation);
long tweetId = status.getId();
System.out.println(tweetId);
String content = status.getText();
System.out.println(content +"\n");
}
public void onDeletionNotice(StatusDeletionNotice statusDeletionNotice) {}
public void onTrackLimitationNotice(int numberOfLimitedStatuses) {}
public void onException(Exception ex) {
ex.printStackTrace();
}
#Override
public void onScrubGeo(long arg0, long arg1) {
// TODO Auto-generated method stub
}
#Override
public void onStallWarning(StallWarning arg0) {
// TODO Auto-generated method stub
}
};
List<String> queries = new ArrayList<String>();
queries.add("#carb0nx");
twitterStream.addListener(listener);
//twitterStream.firehose(20);
String[] trackQueries = (String[]) queries.toArray(new String[queries.size()]);
FilterQuery filterQuery = new FilterQuery();
twitterStream.filter(filterQuery.track(trackQueries));
}
The above program fetches only the tweets which are getting added for the hashtag after running the program. I want to get all the older tweets as well before getting the newly added tweets.
Thanks in advance.enter code here
The code you have posted uses streaming api. So you will get only new tweets.
Check out this example for old tweets:
https://github.com/yusuke/twitter4j/blob/master/twitter4j-examples/src/main/java/twitter4j/examples/search/SearchTweets.java
Also check out https://dev.twitter.com/docs/rate-limiting/1.1 for REST API Rate Limiting
I use the twitter4j query interface to filter tweets http://twitter4j.org/javadoc/twitter4j/Query.html. But the twitter spout in https://github.com/nathanmarz/storm-starter/blob/master/src/jvm/storm/starter/spout/TwitterSampleSpout.java:43 uses queue.offer(status). I don't have a reference to Status, how do I integrate these API(s) to process live tweets.
This is what we have been using successfully to filter tweets:
public void open(Map conf, TopologyContext context, SpoutOutputCollector collector) {
queue = new LinkedBlockingQueue<Status>(1000);
_collector = collector;
StatusListener listener = new StatusListener() {
public void onStatus(Status status) {
queue.offer(status);
}
public void onDeletionNotice(StatusDeletionNotice sdn) {
}
public void onTrackLimitationNotice(int i) {
}
public void onScrubGeo(long l, long l1) {
}
public void onException(Exception e) {
}
};
TwitterStreamFactory fact = new TwitterStreamFactory(new ConfigurationBuilder().setUser(_username).setPassword(_pwd).build());
_twitterStream = fact.getInstance();
_twitterStream.addListener(listener);
_twitterStream.filter(new FilterQuery().track(TERMS_TO_TRACK).setIncludeEntities(true));
}