git rebase解决所有冲突

Corrected the title of the permission requesting dialog in LaunchActivity

Add a widget from Android Studio widget template

add the layout of widget , add the support Android Studio 3.0

fix the support Android Studio 3.0

Completed the development of app widget to show the recent blogs.

chance the previewImage of app widget

fixed the bug that occurred when there were less than 30 notes

update build tools
This commit is contained in:
xingxing
2017-12-26 18:31:10 +08:00
parent 3da951f9af
commit 3b433b6585
23 changed files with 580 additions and 23 deletions

View File

@@ -3,7 +3,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
}
}
repositories {
@@ -13,7 +13,6 @@ repositories {
maven { url "http://dl.bintray.com/piasy/maven" }
}
apply plugin: 'com.android.application'
apply plugin: 'com.neenbedankt.android-apt'
def dbflow_version = "4.0.0-beta2"
def ciName = isEmpty(System.getenv("TRAVIS_TAG")) ? "Staging" : System.getenv("TRAVIS_TAG")
@@ -33,7 +32,7 @@ android {
}
}
compileSdkVersion 25
buildToolsVersion "25.0.2"
buildToolsVersion '26.0.2'
defaultConfig {
applicationId "com.leanote.android"
minSdkVersion 19
@@ -76,12 +75,12 @@ dependencies {
compile 'com.android.support:cardview-v7:25.3.0'
compile 'com.jakewharton:butterknife:8.4.0'
apt 'com.jakewharton:butterknife-compiler:8.4.0'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.4.0'
compile group: 'com.squareup.okhttp3', name: 'logging-interceptor', version: '3.4.1'
compile group: 'com.squareup.retrofit2', name: 'adapter-rxjava', version: '2.1.0'
apt "com.github.Raizlabs.DBFlow:dbflow-processor:${dbflow_version}"
annotationProcessor "com.github.Raizlabs.DBFlow:dbflow-processor:${dbflow_version}"
compile "com.github.Raizlabs.DBFlow:dbflow-core:${dbflow_version}"
compile "com.github.Raizlabs.DBFlow:dbflow:${dbflow_version}"
@@ -107,4 +106,5 @@ dependencies {
compile 'com.github.piasy:GlideImageLoader:1.2.5'
compile 'com.weiwangcn.betterspinner:library-material:1.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
}

View File

@@ -8,7 +8,6 @@
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
@@ -51,7 +50,9 @@
android:screenOrientation="portrait"
android:label="@string/about" />
<activity
android:name=".ui.PictureViewerActivity" android:screenOrientation="portrait" />
android:name=".ui.PictureViewerActivity"
android:label="@string/edit"
android:screenOrientation="portrait" />
<service
android:name=".background.NoteSyncService"
@@ -72,9 +73,29 @@
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
android:resource="@xml/provider_paths" />
</provider>
<receiver
android:name=".appwidget.NoteAppWidget"
android:icon="@drawable/ic_add"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/widget_provider" />
</receiver>
<service
android:name=".appwidget.WidgetService"
android:permission="android.permission.BIND_REMOTEVIEWS" />
<activity android:name=".appwidget.RedirActivity"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.NoDisplay"/>
</application>
</manifest>

View File

@@ -0,0 +1,108 @@
package org.houxg.leamonax.appwidget;
import android.appwidget.AppWidgetManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.widget.RemoteViews;
import android.widget.RemoteViewsService;
import org.houxg.leamonax.R;
import org.houxg.leamonax.database.NoteDataStore;
import org.houxg.leamonax.model.Account;
import org.houxg.leamonax.model.Note;
import org.houxg.leamonax.ui.NotePreviewActivity;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class AppWidgetViewsFactory implements RemoteViewsService.RemoteViewsFactory {
private Context ctxt=null;
private int appWidgetId;
private List<Note> allNotes;
public AppWidgetViewsFactory(Context ctxt, Intent intent) {
this.ctxt=ctxt;
appWidgetId=intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
allNotes = NoteDataStore.getAllNotes(Account.getCurrent().getUserId());
Collections.sort(allNotes, new Comparator<Note>() {
@Override
public int compare(Note o1, Note o2) {
String temp1=o1.getUpdatedTimeVal()+"";
String temp2=o2.getUpdatedTimeVal()+"";
return temp2.compareTo(temp1);
}
});
if(allNotes.size()>30){
allNotes=allNotes.subList(0,30);
}
}
@Override
public void onCreate() {
// no-op
}
@Override
public void onDestroy() {
// no-op
}
@Override
public int getCount() {
return(allNotes.size());
}
@Override
public RemoteViews getViewAt(int position) {
RemoteViews row=new RemoteViews(ctxt.getPackageName(),
R.layout.note_app_widget_row);
row.setTextViewText(R.id.appwidget_row_title, allNotes.get(position).getTitle());
String textTemp="";
if(allNotes.get(position).getContent().length()>200){
textTemp=allNotes.get(position).getContent().substring(0,200)+"...";
}else {
textTemp=allNotes.get(position).getContent();
}
row.setTextViewText(R.id.appwidget_row_text, textTemp);
Intent intent=new Intent();
Bundle extras=new Bundle();
extras.putLong(NotePreviewActivity.EXT_NOTE_LOCAL_ID, allNotes.get(position).getId());
intent.putExtras(extras);
row.setOnClickFillInIntent(R.id.widget_note, intent);
return(row);
}
@Override
public RemoteViews getLoadingView() {
return(null);
}
@Override
public int getViewTypeCount() {
return(1);
}
@Override
public long getItemId(int position) {
return(position);
}
@Override
public boolean hasStableIds() {
return(true);
}
@Override
public void onDataSetChanged() {
// no-op
}
}

View File

@@ -0,0 +1,92 @@
package org.houxg.leamonax.appwidget;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.util.Log;
import android.widget.RemoteViews;
import org.houxg.leamonax.R;
public class NoteAppWidget extends AppWidgetProvider {
private int widgetIds[];
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
Log.i("debug!!!!!!!!!!!!!!!!","接收到广播");
// abortBroadcast();
// for (int i=0;i<widgetIds.length;i++){
// Intent svcIntent=new Intent(context, WidgetService.class);
// RemoteViews widget=new RemoteViews(context.getPackageName(),
// R.layout.note_app_widget);
//
// widget.setRemoteAdapter(widgetIds[i], R.id.words,
// svcIntent);
//
// Intent clickIntent=new Intent(context, RedirActivity.class);
// PendingIntent clickPI=PendingIntent
// .getActivity(context, 0,
// clickIntent,
// PendingIntent.FLAG_UPDATE_CURRENT);
//
// widget.setPendingIntentTemplate(R.id.words, clickPI);
//
// AppWidgetManager.getInstance(context).updateAppWidget(widgetIds[i], widget);
//
// }
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
widgetIds=appWidgetIds;
for (int i=0; i<appWidgetIds.length; i++) {
Intent svcIntent=new Intent(context, WidgetService.class);
svcIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]);
svcIntent.setData(Uri.parse(svcIntent.toUri(Intent.URI_INTENT_SCHEME)));
RemoteViews widget=new RemoteViews(context.getPackageName(),
R.layout.note_app_widget);
widget.setRemoteAdapter(appWidgetIds[i], R.id.words,
svcIntent);
Intent clickIntent=new Intent(context, RedirActivity.class);
PendingIntent clickPI=PendingIntent
.getActivity(context, 0,
clickIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
widget.setPendingIntentTemplate(R.id.words, clickPI);
// Intent i=new Intent(ctxt,NotePreviewActivity.class);
// i.putExtra(NotePreviewActivity.EXT_NOTE_LOCAL_ID, allNotes.get(position).getId());
// row.setOnClickFillInIntent(R.id.widget_note, i);
appWidgetManager.updateAppWidget(appWidgetIds[i], widget);
}
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
// When the user deletes the widget, delete the preference associated with it.
}
@Override
public void onEnabled(Context context) {
// Enter relevant functionality for when the first widget is created
}
@Override
public void onDisabled(Context context) {
// Enter relevant functionality for when the last widget is disabled
}
}

View File

@@ -0,0 +1,108 @@
package org.houxg.leamonax.appwidget;
import android.app.Activity;
import android.appwidget.AppWidgetManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import org.houxg.leamonax.R;
/**
* The configuration screen for the {@link NoteAppWidget NoteAppWidget} AppWidget.
*/
public class NoteAppWidgetConfigureActivity extends Activity {
private static final String PREFS_NAME = "org.houxg.leamonax.appwidget.NoteAppWidget";
private static final String PREF_PREFIX_KEY = "appwidget_";
int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
EditText mAppWidgetText;
View.OnClickListener mOnClickListener = new View.OnClickListener() {
public void onClick(View v) {
final Context context = NoteAppWidgetConfigureActivity.this;
// 单击按钮的时候,字符串存储在本地
String widgetText = mAppWidgetText.getText().toString();
// saveTitlePref(context, mAppWidgetId, widgetText);
// 更新app小部件是配置活动的职责
// It is the responsibility of the configuration activity to update the app widget
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
NoteAppWidget.updateAppWidget(context, appWidgetManager, mAppWidgetId);
// 确保我们将原始应用程序小部件Id传回
// Make sure we pass back the original appWidgetId
Intent resultValue = new Intent();
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
setResult(RESULT_OK, resultValue);
finish();
}
};
public NoteAppWidgetConfigureActivity() {
super();
}
// 存储在本地的字符串对象
// Write the prefix to the SharedPreferences object for this widget
static void saveTitlePref(Context context, int appWidgetId, String text) {
SharedPreferences.Editor prefs = context.getSharedPreferences(PREFS_NAME, 0).edit();
prefs.putString(PREF_PREFIX_KEY + appWidgetId, text);
prefs.apply();
}
// 从共享首选项对象中读取这个小部件的前缀。
// 如果没有保存的首选项,则从资源中获取默认值
// Read the prefix from the SharedPreferences object for this widget.
// If there is no preference saved, get the default from a resource
static String loadTitlePref(Context context, int appWidgetId) {
SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, 0);
String titleValue = prefs.getString(PREF_PREFIX_KEY + appWidgetId, null);
if (titleValue != null) {
return titleValue;
} else {
return context.getString(R.string.appwidget_text);
}
}
//在删除部件的时候删除sp里面的存储
static void deleteTitlePref(Context context, int appWidgetId) {
SharedPreferences.Editor prefs = context.getSharedPreferences(PREFS_NAME, 0).edit();
prefs.remove(PREF_PREFIX_KEY + appWidgetId);
prefs.apply();
}
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
// Set the result to CANCELED. This will cause the widget host to cancel
// out of the widget placement if the user presses the back button.
setResult(RESULT_CANCELED);
setContentView(R.layout.note_app_widget_configure);
mAppWidgetText = (EditText) findViewById(R.id.appwidget_text);
findViewById(R.id.add_button).setOnClickListener(mOnClickListener);
// Find the widget id from the intent.
Intent intent = getIntent();
Bundle extras = intent.getExtras();
if (extras != null) {
mAppWidgetId = extras.getInt(
AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
}
// If this activity was started with an intent without an app widget ID, finish with an error.
if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
finish();
return;
}
mAppWidgetText.setText(loadTitlePref(NoteAppWidgetConfigureActivity.this, mAppWidgetId));
}
}

View File

@@ -0,0 +1,32 @@
package org.houxg.leamonax.appwidget;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;
import org.houxg.leamonax.ui.NotePreviewActivity;
public class RedirActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Long word=getIntent().getLongExtra(NotePreviewActivity.EXT_NOTE_LOCAL_ID,-1);
Intent intent=new Intent(RedirActivity.this,NotePreviewActivity.class);
Bundle bundle=new Bundle();
if(word==-1){
Toast.makeText(this, "笔记编号错误", Toast.LENGTH_LONG).show();
}else {
bundle.putLong(NotePreviewActivity.EXT_NOTE_LOCAL_ID,word);
intent.putExtras(bundle);
startActivity(intent);
}
finish();
}
}

View File

@@ -0,0 +1,12 @@
package org.houxg.leamonax.appwidget;
import android.content.Intent;
import android.widget.RemoteViewsService;
public class WidgetService extends RemoteViewsService {
@Override
public RemoteViewsFactory onGetViewFactory(Intent intent) {
return(new AppWidgetViewsFactory(this.getApplicationContext(),
intent));
}
}

View File

@@ -38,7 +38,7 @@ public class LaunchActivity extends Activity {
}else {
AlertDialog.Builder builder=new AlertDialog.Builder(LaunchActivity.this);
builder.setMessage(getString(R.string.permission_get_description));
builder.setTitle(getString(R.string.permission_denied));
builder.setTitle(getString(R.string.permission_get));
builder.setPositiveButton(getString(R.string.allow), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
@@ -129,7 +129,8 @@ public class LaunchActivity extends Activity {
if(hasPermission(Manifest.permission.CAMERA ,
Manifest.permission.WRITE_EXTERNAL_STORAGE ,
Manifest.permission.READ_EXTERNAL_STORAGE ,
Manifest.permission.READ_PHONE_STATE )){
Manifest.permission.READ_PHONE_STATE
)){
doAfterGetPermission();
}else {
Toast.makeText(LaunchActivity.this,getString(R.string.permission_get_error),Toast.LENGTH_SHORT).show();

View File

@@ -108,6 +108,14 @@ public class NoteEditActivity extends BaseActivity implements EditorFragment.Edi
return super.onCreateOptionsMenu(menu);
}
@Override
protected void onDestroy() {
Intent intent = new Intent();
intent.setAction("android.appwidget.action.APPWIDGET_UPDATE");
this.sendBroadcast(intent);
super.onDestroy();
}
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
switch (item.getItemId()) {

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#c9c9c9">
<item>
<shape android:shape="rectangle">
<solid android:color="#FFFFFF" />
<corners android:radius="0dp" />
</shape>
</item>
<item android:drawable="@drawable/rounded_corners" />
</ripple>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#FFFFFF" />
<corners android:radius="4dp" />
</shape>

View File

@@ -0,0 +1,63 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/relativeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/transparent"
android:padding="@dimen/widget_margin">
<RelativeLayout
android:id="@+id/title_layout_widget"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="@color/colorPrimary"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:paddingStart="5dp"
android:paddingEnd="10dp"
>
<ImageView
android:id="@+id/widget_top_icon"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:background="@drawable/ic_launcher" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="@id/widget_top_icon"
android:layout_centerVertical="true"
android:text="@string/app_name"
android:textColor="@color/white"
android:textSize="18sp"
tools:ignore="NotSibling" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_alignParentEnd="true"
android:text="@string/recent_notes"
android:textColor="@color/white"
android:textSize="14sp"
tools:ignore="NotSibling" />
</RelativeLayout>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/words"
android:divider="@null"
android:layout_marginTop="2dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:layout_below="@+id/title_layout_widget"
android:background="@color/transparent"/>
</RelativeLayout>

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="@string/configure"/>
<EditText
android:id="@+id/appwidget_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"/>
<Button
android:id="@+id/add_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/add_widget"/>
</LinearLayout>

View File

@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/relativeLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="@dimen/widget_margin"
>
<RelativeLayout
android:id="@+id/widget_note"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:layout_marginBottom="2dp"
android:padding="2dp"
android:background="@drawable/ripple_bg"
>
<TextView
android:id="@+id/appwidget_row_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
android:textStyle="bold"
android:textColor="@color/primary_text_light"/>
<TextView
android:id="@+id/appwidget_row_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/appwidget_row_title"
android:textColor="@color/primary_text_light"/>
</RelativeLayout>
</RelativeLayout>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--
Refer to App Widget Documentation for margin information
http://developer.android.com/guide/topics/appwidgets/index.html#CreatingLayout
-->
<dimen name="widget_margin">0dp</dimen>
</resources>

View File

@@ -51,7 +51,7 @@
<string name="password">密码</string>
<string name="preview">预览</string>
<string name="public_note">公开笔记</string>
<string name="recent_notes">最近</string>
<string name="recent_notes">最近笔记</string>
<string name="revert">还原</string>
<string name="reverting">还原中</string>
<string name="save">保存</string>

View File

@@ -2,4 +2,10 @@
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<!--
Refer to App Widget Documentation for margin information
http://developer.android.com/guide/topics/appwidgets/index.html#CreatingLayout
-->
<dimen name="widget_margin">8dp</dimen>
</resources>

View File

@@ -121,4 +121,7 @@
<string name="permission_get_description">We need some permission to start the application</string>
<string name="permission_get">Permission request</string>
<string name="allow">allow</string>
<string name="appwidget_text">EXAMPLE</string>
<string name="configure">Configure</string>
<string name="add_widget">Add widget</string>
</resources>

View File

@@ -0,0 +1,9 @@
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="146dip"
android:minHeight="146dip"
android:updatePeriodMillis="43200000"
android:initialLayout="@layout/note_app_widget"
android:autoAdvanceViewId="@+id/words"
android:previewImage="@drawable/ic_launcher"
android:resizeMode="vertical"
/>