1
0
mirror of https://github.com/TeamNewPipe/NewPipe synced 2025-10-29 06:17:38 +00:00

Merge branch 'master' of github.com:theScrabi/NewPipe

This commit is contained in:
Adam Howard
2016-01-03 19:44:13 +00:00
42 changed files with 916 additions and 340 deletions

View File

@@ -0,0 +1,46 @@
package org.schabi.newpipe;
import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import info.guardianproject.netcipher.NetCipher;
import info.guardianproject.netcipher.proxy.OrbotHelper;
public class App extends Application {
private static boolean useTor;
@Override
public void onCreate() {
super.onCreate();
// if Orbot is installed, then default to using Tor, the user can still override
if (OrbotHelper.requestStartTor(this)) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
configureTor(prefs.getBoolean(getString(R.string.useTor), true));
}
}
/**
* Set the proxy settings based on whether Tor should be enabled or not.
*/
static void configureTor(boolean enabled) {
useTor = enabled;
if (useTor) {
NetCipher.useTor();
} else {
NetCipher.setProxy(null);
}
}
static void checkStartTor(Context context) {
if (useTor) {
OrbotHelper.requestStartTor(context);
}
}
static boolean isUsingTor() {
return useTor;
}
}

View File

@@ -17,6 +17,7 @@ import android.os.IBinder;
import android.os.PowerManager;
import android.support.v7.app.NotificationCompat;
import android.util.Log;
import android.widget.RemoteViews;
import android.widget.Toast;
import java.io.IOException;
@@ -113,9 +114,9 @@ public class BackgroundPlayer extends Service /*implements MediaPlayer.OnPrepare
private int noteID = TAG.hashCode();
private BackgroundPlayer owner;
private NotificationManager noteMgr;
private NotificationCompat.Builder noteBuilder;
private WifiManager.WifiLock wifiLock;
private Bitmap videoThumbnail = null;
private NotificationCompat.Builder noteBuilder;
public PlayerThread(String src, String title, BackgroundPlayer owner) {
this.source = src;
@@ -124,10 +125,9 @@ public class BackgroundPlayer extends Service /*implements MediaPlayer.OnPrepare
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
}
@Override
public void run() {
Resources res = getApplicationContext().getResources();
mediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);//cpu lock
try {
mediaPlayer.setDataSource(source);
@@ -174,54 +174,7 @@ public class BackgroundPlayer extends Service /*implements MediaPlayer.OnPrepare
filter.addAction(ACTION_STOP);
registerReceiver(broadcastReceiver, filter);
PendingIntent playPI = PendingIntent.getBroadcast(owner, noteID,
new Intent(ACTION_PLAYPAUSE), PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Action playButton = new NotificationCompat.Action.Builder
(R.drawable.ic_play_arrow_white_48dp, "Play", playPI).build();
/*
NotificationCompat.Action pauseButton = new NotificationCompat.Action.Builder
(R.drawable.ic_pause_white_24dp, "Pause", playPI).build();
*/
PendingIntent stopPI = PendingIntent.getBroadcast(owner, noteID,
new Intent(ACTION_STOP), PendingIntent.FLAG_UPDATE_CURRENT);
noteBuilder = new NotificationCompat.Builder(owner);
noteBuilder
.setContentTitle(title)
//really? Id like to put something more helpful here.
//.setContentText("NewPipe is playing in the background")
.setContentText(channelName)
//.setAutoCancel(!mediaPlayer.isPlaying())
.setOngoing(true)
.setDeleteIntent(stopPI)
//doesn't fit with Notification.MediaStyle
//.setProgress(vidLength, 0, false)
.setSmallIcon(R.drawable.ic_play_circle_filled_white_24dp)
.setLargeIcon(videoThumbnail)
.setTicker(
String.format(res.getString(
R.string.backgroundPlayerTickerText), title))
.addAction(playButton);
//.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
//.setLargeIcon(cover)
if(android.os.Build.VERSION.SDK_INT >= 16)
noteBuilder.setPriority(Notification.PRIORITY_LOW);
if(android.os.Build.VERSION.SDK_INT >= 21)
noteBuilder.setCategory(Notification.CATEGORY_TRANSPORT);
noteBuilder.setStyle(new NotificationCompat.MediaStyle()
//.setMediaSession(mMediaSession.getSessionToken())
.setShowActionsInCompactView(new int[]{0})
.setShowCancelButton(true)
.setCancelButtonIntent(stopPI));
if(videoThumbnail != null) {
noteBuilder.setLargeIcon(videoThumbnail);
}
Notification note = noteBuilder.build();
Notification note = buildNotification();
Intent openDetailView = new Intent(getApplicationContext(),
VideoItemDetailActivity.class);
@@ -249,7 +202,6 @@ public class BackgroundPlayer extends Service /*implements MediaPlayer.OnPrepare
Log.d(TAG, "sleep failure");
}
}*/
}
private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@@ -303,5 +255,93 @@ public class BackgroundPlayer extends Service /*implements MediaPlayer.OnPrepare
afterPlayCleanup();
}
}
private Notification buildNotification() {
Notification note;
Resources res = getApplicationContext().getResources();
noteBuilder = new NotificationCompat.Builder(owner);
PendingIntent playPI = PendingIntent.getBroadcast(owner, noteID,
new Intent(ACTION_PLAYPAUSE), PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent stopPI = PendingIntent.getBroadcast(owner, noteID,
new Intent(ACTION_STOP), PendingIntent.FLAG_UPDATE_CURRENT);
/*
NotificationCompat.Action pauseButton = new NotificationCompat.Action.Builder
(R.drawable.ic_pause_white_24dp, "Pause", playPI).build();
*/
noteBuilder
.setOngoing(true)
.setDeleteIntent(stopPI)
//doesn't fit with Notification.MediaStyle
//.setProgress(vidLength, 0, false)
.setSmallIcon(R.drawable.ic_play_circle_filled_white_24dp)
.setTicker(
String.format(res.getString(
R.string.backgroundPlayerTickerText), title));
if (android.os.Build.VERSION.SDK_INT < 21) {
NotificationCompat.Action playButton = new NotificationCompat.Action.Builder
(R.drawable.ic_play_arrow_white_48dp,
res.getString(R.string.play), playPI).build();
noteBuilder
.setContentTitle(title)
//really? Id like to put something more helpful here.
//.setContentText("NewPipe is playing in the background")
.setContentText(channelName)
//.setAutoCancel(!mediaPlayer.isPlaying())
.setDeleteIntent(stopPI)
//doesn't fit with Notification.MediaStyle
//.setProgress(vidLength, 0, false)
.setLargeIcon(videoThumbnail)
.addAction(playButton);
//.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
//.setLargeIcon(cover)
if (android.os.Build.VERSION.SDK_INT >= 16)
noteBuilder.setPriority(Notification.PRIORITY_LOW);
noteBuilder.setStyle(new NotificationCompat.MediaStyle()
//.setMediaSession(mMediaSession.getSessionToken())
.setShowActionsInCompactView(new int[]{0})
.setShowCancelButton(true)
.setCancelButtonIntent(stopPI));
if (videoThumbnail != null) {
noteBuilder.setLargeIcon(videoThumbnail);
}
note = noteBuilder.build();
} else {
RemoteViews view =
new RemoteViews(BuildConfig.APPLICATION_ID, R.layout.player_notification);
view.setImageViewBitmap(R.id.backgroundCover, videoThumbnail);
view.setTextViewText(R.id.backgroundSongName, title);
view.setTextViewText(R.id.backgroundArtist, channelName);
view.setOnClickPendingIntent(R.id.backgroundStop, stopPI);
view.setOnClickPendingIntent(R.id.backgroundPlayPause, playPI);
RemoteViews expandedView =
new RemoteViews(BuildConfig.APPLICATION_ID, R.layout.player_notification);
expandedView.setImageViewBitmap(R.id.backgroundCover, videoThumbnail);
expandedView.setTextViewText(R.id.backgroundSongName, title);
expandedView.setTextViewText(R.id.backgroundArtist, channelName);
expandedView.setOnClickPendingIntent(R.id.backgroundStop, stopPI);
expandedView.setOnClickPendingIntent(R.id.backgroundPlayPause, playPI);
noteBuilder.setCategory(Notification.CATEGORY_TRANSPORT);
//Make notification appear on lockscreen
noteBuilder.setVisibility(Notification.VISIBILITY_PUBLIC);
note = noteBuilder.build();
note.contentView = view;
//todo: This never shows up. I was not able to figure out why:
note.bigContentView = expandedView;
}
return note;
}
}
}

View File

@@ -57,26 +57,29 @@ public class DownloadDialog extends DialogFragment {
@Override
public void onClick(DialogInterface dialog, int which) {
Context context = getActivity();
SharedPreferences defaultPreferences = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
String suffix = "";
String title = arguments.getString(TITLE);
String url = "";
String downloadFolder = Environment.DIRECTORY_DOWNLOADS;
switch(which) {
case 0: // Video
suffix = arguments.getString(FILE_SUFFIX_VIDEO);
url = arguments.getString(VIDEO_URL);
downloadFolder = Environment.DIRECTORY_MOVIES;
break;
case 1:
suffix = arguments.getString(FILE_SUFFIX_AUDIO);
url = arguments.getString(AUDIO_URL);
downloadFolder = Environment.DIRECTORY_MUSIC;
break;
default:
Log.d(TAG, "lolz");
}
//to avoid hard-coded string like "/storage/emulated/0/NewPipe"
final File dir = new File(defaultPreferences.getString(
"download_path_preference",
Environment.getExternalStorageDirectory().getAbsolutePath() + "/NewPipe"));
//to avoid hard-coded string like "/storage/emulated/0/Movies"
String downloadPath = prefs.getString(getString(R.string.downloadPathPreference),
Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + downloadFolder);
final File dir = new File(downloadPath);
if(!dir.exists()) {
boolean mkdir = dir.mkdir(); //attempt to create directory
if(!mkdir && !dir.isDirectory()) {
@@ -84,17 +87,21 @@ public class DownloadDialog extends DialogFragment {
//TODO notify user "download directory should be changed" ?
}
}
DownloadManager dm = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
DownloadManager.Request request = new DownloadManager.Request(
Uri.parse(url));
request.setDestinationUri(Uri.fromFile(new File(
defaultPreferences.getString("download_path_preference", "/storage/emulated/0/NewPipe")
+ "/" + title + suffix)));
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
try {
dm.enqueue(request);
} catch (Exception e) {
e.printStackTrace();
String saveFilePath = dir + "/" + title + suffix;
if (App.isUsingTor()) {
// if using Tor, do not use DownloadManager because the proxy cannot be set
Downloader.downloadFile(getContext(), url, saveFilePath);
} else {
DownloadManager dm = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
DownloadManager.Request request = new DownloadManager.Request(
Uri.parse(url));
request.setDestinationUri(Uri.fromFile(new File(saveFilePath)));
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
try {
dm.enqueue(request);
} catch (Exception e) {
e.printStackTrace();
}
}
}
});

View File

@@ -1,12 +1,30 @@
package org.schabi.newpipe;
import android.app.Notification;
import android.app.NotificationManager;
import android.content.Context;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.UnknownHostException;
import javax.net.ssl.HttpsURLConnection;
import info.guardianproject.netcipher.NetCipher;
/**
* Created by Christian Schabesberger on 14.08.15.
*
@@ -28,6 +46,7 @@ import java.net.UnknownHostException;
*/
public class Downloader {
public static final String TAG = "Downloader";
private static final String USER_AGENT = "Mozilla/5.0";
@@ -40,7 +59,7 @@ public class Downloader {
String ret = "";
try {
URL url = new URL(siteUrl);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
HttpsURLConnection con = NetCipher.getHttpsURLConnection(url);
con.setRequestProperty("Accept-Language", language);
ret = dl(con);
}
@@ -84,7 +103,7 @@ public class Downloader {
try {
URL url = new URL(siteUrl);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
HttpsURLConnection con = NetCipher.getHttpsURLConnection(url);
ret = dl(con);
}
catch(Exception e) {
@@ -93,4 +112,92 @@ public class Downloader {
return ret;
}
/**
* Downloads a file from a URL in the background using an {@link AsyncTask}.
*
* @param fileURL HTTP URL of the file to be downloaded
* @param saveFilePath path of the directory to save the file
* @throws IOException
*/
public static void downloadFile(final Context context, final String fileURL, final String saveFilePath) {
new AsyncTask<Void, Integer, Void>() {
private NotificationManager nm;
private NotificationCompat.Builder builder;
private int notifyId = 0x1234;
private int fileSize = 0xffffffff;
@Override
protected void onPreExecute() {
super.onPreExecute();
nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Drawable icon = context.getResources().getDrawable(R.mipmap.ic_launcher);
builder = new NotificationCompat.Builder(context)
.setSmallIcon(android.R.drawable.stat_sys_download)
.setLargeIcon(((BitmapDrawable) icon).getBitmap())
.setContentTitle(saveFilePath.substring(saveFilePath.lastIndexOf('/') + 1))
.setContentText(saveFilePath)
.setProgress(fileSize, 0, false);
nm.notify(notifyId, builder.build());
}
@Override
protected Void doInBackground(Void... voids) {
HttpsURLConnection con = null;
try {
con = NetCipher.getHttpsURLConnection(fileURL);
int responseCode = con.getResponseCode();
// always check HTTP response code first
if (responseCode == HttpURLConnection.HTTP_OK) {
fileSize = con.getContentLength();
InputStream inputStream = new BufferedInputStream(con.getInputStream());
FileOutputStream outputStream = new FileOutputStream(saveFilePath);
int bufferSize = 8192;
int downloaded = 0;
int bytesRead = -1;
byte[] buffer = new byte[bufferSize];
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
downloaded += bytesRead;
if (downloaded % 50000 < bufferSize) {
publishProgress(downloaded);
}
}
outputStream.close();
inputStream.close();
publishProgress(bufferSize);
} else {
Log.i(TAG, "No file to download. Server replied HTTP code: " + responseCode);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (con != null) {
con.disconnect();
con = null;
}
}
return null;
}
@Override
protected void onProgressUpdate(Integer... progress) {
builder.setProgress(fileSize, progress[0], false);
nm.notify(notifyId, builder.build());
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
nm.cancel(notifyId);
}
}.execute();
}
}

View File

@@ -0,0 +1,36 @@
package org.schabi.newpipe;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
public class ExitActivity extends Activity {
@SuppressLint("NewApi")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT >= 21) {
finishAndRemoveTask();
} else {
finish();
}
System.exit(0);
}
public static void exitAndRemoveFromRecentApps(Activity activity) {
Intent intent = new Intent(activity, ExitActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
| Intent.FLAG_ACTIVITY_CLEAR_TASK
| Intent.FLAG_ACTIVITY_NO_ANIMATION);
activity.startActivity(intent);
}
}

View File

@@ -0,0 +1,77 @@
package org.schabi.newpipe;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.preference.PreferenceManager;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
/**
* Created by chschtsch on 12/29/15.
*/
public class Localization {
public static Locale getPreferredLocale(Context context) {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
String languageCode = sp.getString(String.valueOf(R.string.searchLanguage), "en");
if(languageCode.length() == 2) {
return new Locale(languageCode);
}
else if(languageCode.contains("_")) {
String country = languageCode
.substring(languageCode.indexOf("_"), languageCode.length());
return new Locale(languageCode.substring(0, 2), country);
}
return Locale.getDefault();
}
public static String localizeViewCount(long viewCount, Context context) {
Locale locale = getPreferredLocale(context);
Resources res = context.getResources();
String viewsString = res.getString(R.string.viewCountText);
NumberFormat nf = NumberFormat.getInstance(locale);
String formattedViewCount = nf.format(viewCount);
return String.format(viewsString, formattedViewCount);
}
public static String localizeNumber(long number, Context context) {
Locale locale = getPreferredLocale(context);
NumberFormat nf = NumberFormat.getInstance(locale);
return nf.format(number);
}
private static String formatDate(String date, Context context) {
Locale locale = getPreferredLocale(context);
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
Date datum = null;
try {
datum = formatter.parse(date);
} catch (ParseException e) {
e.printStackTrace();
}
DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM, locale);
return df.format(datum);
}
public static String localizeDate(String date, Context context) {
Resources res = context.getResources();
String dateString = res.getString(R.string.uploadDateText);
String formattedDate = formatDate(date, context);
return String.format(dateString, formattedDate);
}
}

View File

@@ -0,0 +1,32 @@
package org.schabi.newpipe;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
public class PanicResponderActivity extends Activity {
public static final String PANIC_TRIGGER_ACTION = "info.guardianproject.panic.action.TRIGGER";
@SuppressLint("NewApi")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
if (intent != null && PANIC_TRIGGER_ACTION.equals(intent.getAction())) {
// TODO explicitly clear the search results once they are restored when the app restarts
// or if the app reloads the current video after being killed, that should be cleared also
ExitActivity.exitAndRemoveFromRecentApps(this);
}
if (Build.VERSION.SDK_INT >= 21) {
finishAndRemoveTask();
} else {
finish();
}
}
}

View File

@@ -187,6 +187,18 @@ public class PlayVideoActivity extends AppCompatActivity {
videoView.pause();
}
@Override
public void onResume() {
super.onResume();
App.checkStartTor(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
prefs = getPreferences(Context.MODE_PRIVATE);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();

View File

@@ -1,13 +1,14 @@
package org.schabi.newpipe;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.Environment;
import android.preference.CheckBoxPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.v7.app.ActionBar;
@@ -17,6 +18,8 @@ import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import info.guardianproject.netcipher.proxy.OrbotHelper;
/**
* Created by Christian Schabesberger on 31.08.15.
*
@@ -39,6 +42,7 @@ import android.view.ViewGroup;
public class SettingsActivity extends PreferenceActivity {
private static final int REQUEST_INSTALL_ORBOT = 0x1234;
private AppCompatDelegate mDelegate = null;
@Override
@@ -56,13 +60,48 @@ public class SettingsActivity extends PreferenceActivity {
}
public static class SettingsFragment extends PreferenceFragment {
private CheckBoxPreference useTorCheckBox;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.settings_screen);
// if Orbot is installed, then default to using Tor, the user can still override
useTorCheckBox = (CheckBoxPreference) findPreference(getString(R.string.useTor));
final Activity activity = getActivity();
final boolean useTor = OrbotHelper.isOrbotInstalled(activity);
useTorCheckBox.setDefaultValue(useTor);
useTorCheckBox.setChecked(useTor);
useTorCheckBox.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object o) {
boolean useTor = (Boolean) o;
if (useTor) {
if (OrbotHelper.isOrbotInstalled(activity)) {
App.configureTor(true);
} else {
Intent intent = OrbotHelper.getOrbotInstallIntent(activity);
activity.startActivityForResult(intent, REQUEST_INSTALL_ORBOT);
}
} else {
App.configureTor(false);
}
return true;
}
});
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// try to start tor regardless of resultCode since clicking back after
// installing the app does not necessarily return RESULT_OK
App.configureTor(requestCode == REQUEST_INSTALL_ORBOT
&& OrbotHelper.requestStartTor(this));
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
@@ -148,17 +187,4 @@ public class SettingsActivity extends PreferenceActivity {
}
return true;
}
public static void initSettings(Context context) {
PreferenceManager.setDefaultValues(context, R.xml.settings_screen, false);
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
if(sp.getString(context.getString(R.string.downloadPathPreference), "").isEmpty()){
SharedPreferences.Editor spEditor = sp.edit();
String newPipeDownloadStorage =
Environment.getExternalStorageDirectory().getAbsolutePath() + "/NewPipe";
spEditor.putString(context.getString(R.string.downloadPathPreference)
, newPipeDownloadStorage);
spEditor.apply();
}
}
}

View File

@@ -1,5 +1,6 @@
package org.schabi.newpipe;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -33,7 +34,7 @@ class VideoInfoItemViewCreator {
this.inflater = inflater;
}
public View getViewFromVideoInfoItem(View convertView, ViewGroup parent, VideoPreviewInfo info) {
public View getViewFromVideoInfoItem(View convertView, ViewGroup parent, VideoPreviewInfo info, Context context) {
ViewHolder holder;
if(convertView == null) {
convertView = inflater.inflate(R.layout.video_item, parent, false);
@@ -59,8 +60,7 @@ class VideoInfoItemViewCreator {
if(!info.upload_date.isEmpty()) {
holder.itemUploadDateView.setText(info.upload_date);
} else {
//tweak if necessary: This is a hack to prevent having white space in the layout :P
holder.itemUploadDateView.setText(String.format("%d", info.view_count));
holder.itemUploadDateView.setText(Localization.localizeViewCount(info.view_count, context));
}
return convertView;

View File

@@ -113,6 +113,12 @@ public class VideoItemDetailActivity extends AppCompatActivity {
.commit();
}
@Override
public void onResume() {
super.onResume();
App.checkStartTor(this);
}
@Override
public void onSaveInstanceState(Bundle outState) {
outState.putString(VideoItemDetailFragment.VIDEO_URL, videoUrl);

View File

@@ -1,9 +1,7 @@
package org.schabi.newpipe;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
@@ -35,13 +33,7 @@ import android.view.MenuItem;
import android.widget.Toast;
import java.net.URL;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Locale;
import java.util.Vector;
import org.schabi.newpipe.services.VideoExtractor;
@@ -235,7 +227,7 @@ public class VideoItemDetailFragment extends Fragment {
switch (info.errorCode) {
case VideoInfo.NO_ERROR: {
View nextVideoView = videoItemViewCreator
.getViewFromVideoInfoItem(null, nextVideoFrame, info.nextVideo);
.getViewFromVideoInfoItem(null, nextVideoFrame, info.nextVideo, getContext());
nextVideoFrame.addView(nextVideoView);
@@ -253,31 +245,20 @@ public class VideoItemDetailFragment extends Fragment {
uploaderView.setText(info.uploader);
actionBarHandler.setChannelName(info.uploader);
Locale locale = getPreferredLocale();
NumberFormat nf = NumberFormat.getInstance(locale);
String localisedViewCount = nf.format(info.view_count);
viewCountView.setText(
String.format(
res.getString(R.string.viewCountText), localisedViewCount));
String localizedViewCount = Localization.localizeViewCount(info.view_count, getContext());
viewCountView.setText(localizedViewCount);
thumbsUpView.setText(nf.format(info.like_count));
thumbsDownView.setText(nf.format(info.dislike_count));
String localizedLikeCount = Localization.localizeNumber(info.like_count, getContext());
thumbsUpView.setText(localizedLikeCount);
@SuppressLint("SimpleDateFormat")
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
Date datum = null;
try {
datum = formatter.parse(info.upload_date);
} catch (ParseException e) {
e.printStackTrace();
}
String localizedDislikeCount = Localization.localizeNumber(info.dislike_count, getContext());
thumbsDownView.setText(localizedDislikeCount);
DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM, locale);
String localizedDate = Localization.localizeDate(info.upload_date, getContext());
uploadDateView.setText(localizedDate);
String localisedDate = df.format(datum);
uploadDateView.setText(
String.format(res.getString(R.string.uploadDateText), localisedDate));
descriptionView.setText(Html.fromHtml(info.description));
descriptionView.setMovementMethod(LinkMovementMethod.getInstance());
actionBarHandler.setServiceId(streamingServiceId);
@@ -306,7 +287,7 @@ public class VideoItemDetailFragment extends Fragment {
VideoItemDetailFragment.ARG_ITEM_ID, currentVideoInfo.nextVideo.id); */
detailIntent.putExtra(
VideoItemDetailFragment.VIDEO_URL, currentVideoInfo.nextVideo.webpage_url);
//todo: make id dynamic the following line is crap
detailIntent.putExtra(VideoItemDetailFragment.STREAMING_SERVICE, streamingServiceId);
startActivity(detailIntent);
}
@@ -315,7 +296,7 @@ public class VideoItemDetailFragment extends Fragment {
break;
case VideoInfo.ERROR_BLOCKED_BY_GEMA:
thumbnailView.setImageBitmap(BitmapFactory.decodeResource(
getResources(), R.drawable.gruese_die_gema_unangebracht));
getResources(), R.drawable.gruese_die_gema));
backgroundButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@@ -458,30 +439,6 @@ public class VideoItemDetailFragment extends Fragment {
}
}
/**Returns the java.util.Locale object which corresponds to the locale set in NewPipe's preferences.
* Currently not affected by the device's locale.*/
private Locale getPreferredLocale() {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
String languageKey = getContext().getString(R.string.searchLanguage);
//i know the following line defaults languageCode to "en", but java is picky about uninitialised values
// Schabi: well lint tels me the value is redundant. I'll suppress it for now.
@SuppressWarnings("UnusedAssignment")
String languageCode = "en";
languageCode = sp.getString(languageKey, "en");
if(languageCode.length() == 2) {
return new Locale(languageCode);
}
else if(languageCode.contains("_")) {
String country = languageCode
.substring(languageCode.indexOf("_"), languageCode.length());
return new Locale(languageCode.substring(0, 2), country);
}
return Locale.getDefault();
}
private boolean checkIfLandscape() {
DisplayMetrics displayMetrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);

View File

@@ -3,6 +3,7 @@ package org.schabi.newpipe;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.NavUtils;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SearchView;
@@ -171,7 +172,13 @@ public class VideoItemListActivity extends AppCompatActivity
}
}
SettingsActivity.initSettings(this);
PreferenceManager.setDefaultValues(this, R.xml.settings_screen, false);
}
@Override
public void onResume() {
super.onResume();
App.checkStartTor(this);
}
/**

View File

@@ -96,7 +96,7 @@ class VideoListAdapter extends BaseAdapter {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
convertView = viewCreator.getViewFromVideoInfoItem(convertView, parent, videoList.get(position));
convertView = viewCreator.getViewFromVideoInfoItem(convertView, parent, videoList.get(position), context);
if(listView.isItemChecked(position)) {
convertView.setBackgroundColor(ContextCompat.getColor(context,R.color.primaryColorYoutube));