这是我的第一个 Android 应用程序,所以请放轻松。这个想法是检测用户何时将照片放入 /mnt/sdcard 并将其上传到 Imgur,然后将链接复制到系统剪贴板。
正在使用的类
我的应用程序中有三个课程。ObserveNewImages
用于FileObserver
检测前述路径中的新照片。
观察图像.java
public class ObserveNewImages extends Service {
final String pathToObserve = android.os.Environment.getExternalStorageDirectory().toString(); // stores "/mnt/sdcard"
final String upload_to = "https://api.imgur.com/3/upload.json";
final String API_key = "API_KEY_GOES_HERE";
public static final String TAG = "Awais";
String link; //full path to where the image is stored
Intent upload;
@Override
public void onCreate(){
upload = new Intent(this, Imgur.class); //just initializing an intent for use later. Nothing special.
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "In onStartCommand");
FileObserver observer = new FileObserver(pathToObserve){
//As soon as we detect a new file in pathToObserve
//, I fire up the service for uploading image to Imgur.
@Override
public void onEvent(int event, String file){
if (event == FileObserver.CREATE){
Log.d(TAG, "file address: " + pathToObserve + "/" + file);
link = pathToObserve + "/" + file;
upload.putExtra("path",link);
startService(upload);
}
}
};
observer.startWatching();
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
继续Imgur.java
其中包括两个类Imgur.class
和一个ImgurTask
扩展类,AsyncTask
以便网络任务在单独的线程上进行。
Imgur.java
public class Imgur extends Service{
String path;
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
path = intent.getStringExtra("path");
new ImgurTask().execute(path);
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
class ImgurTask extends AsyncTask<String, Void, String>{
final String upload_to = "https://api.imgur.com/3/upload.json";
final String API_key = "API_KEY_GOES_HERE";
public static final String TAG = "Awais";
String link;
@Override
protected String doInBackground(String... params) {
HttpClient httpClient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpPost httpPost = new HttpPost(upload_to);
httpPost.setHeader("Authorization", "Client-ID " + API_key);
try {
MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
entity.addPart("image", new FileBody(new File(params[0])));
entity.addPart("key", new StringBody(API_key));
httpPost.setEntity(entity);
HttpResponse response = httpClient.execute(httpPost, localContext);
String response_string = EntityUtils.toString(response.getEntity());
Log.d(TAG, "Response from Imgur: " + response_string);
JSONObject json = new JSONObject(response_string);
//Parsing JSON manually since I couldn't get it work using JSONObject's built-in class functions
String json_str = json.toString();
Integer indexlink = json_str.indexOf("link");
Integer colonlink = json_str.indexOf(":", indexlink);
Integer secondbracket = json_str.indexOf("}", colonlink);
link = json_str.substring(colonlink+2, secondbracket-1);
link = link.replace("\\","");
return link;
}catch (Exception e){
e.printStackTrace();
}
return "error";
}
@Override
protected void onPostExecute(String result) {
if (result != "error"){
//copying link to clipboard
ClipboardManager clipboard = (ClipboardManager)getApplicationContext().getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("Imgur link", result);
clipboard.setPrimaryClip(clip);
Toast.makeText(getApplicationContext(), "Link is ready to paste: " + result, Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(getApplicationContext(), "Error: Are you connected to the Internet?", Toast.LENGTH_SHORT).show();
}
super.onPostExecute(result);
}
}
}
MainActivity.java
这仅用于启动ObserveImages
服务。
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//start service
Intent start_observing = new Intent(this, ObserveImages.class);
startService(start_observing);
Toast.makeText(getApplicationContext(), "Automatic Image Uploader is now running!", Toast.LENGTH_SHORT).show();
finish();
}
}
问题
存在三个问题:
服务只是在一段时间后停止工作。没有任何内容显示日志(我已从此处的代码中删除)以表明应用程序正在运行。为了让事情再次运行,我必须再次从应用程序图标启动。
在几次上传(有时是 4-5 次,有时最多 10 次)之后,Imgur 的服务器会发送一个 405 Not Allowed 响应。离开应用程序一分钟,然后再回来,服务器会发回正确的响应。
应用程序在一段时间后崩溃。FileObserver 类引发空指针异常。